randomising css animations

59
RANDOMISING CSS ANIMATIONS

Upload: asjb

Post on 27-Aug-2014

632 views

Category:

Technology


1 download

DESCRIPTION

This was from a talk I gave at New York Front End Coders in July 2013 on how to create random CSS Animations. CSS Keyframe Animations are definitions in CSS that outline the CSS properties to be animated and the points in time during the life of the animation that these animations should be achieved. This can lead to huge amounts of CSS when trying to make something appear random. This talk sought to explain how randomisation (of a sort) was achieved. Hopefully the slides themselves can communicate this.

TRANSCRIPT

Page 1: Randomising css animations

RANDOMISING CSSANIMATIONS

Page 2: Randomising css animations

ADAM BANKINFront End Engineer at Shutterstock

14 years experience with HTML, CSS and JS

Page 3: Randomising css animations

AUSTRALIAN (z === "zed"); // true

"ize".replace(/z/, "s");

(r === "ahhhhhh"); // true

$("#shrimp").on("barbie", function () { console.error("racial stereotype"); console.error("and frankly, I'm offended");

return false; });

Page 4: Randomising css animations

RANDOMISING CSS ANIMATIONSWhy? Is this difficult?

Page 5: Randomising css animations
Page 6: Randomising css animations

Shutterstock labs home page

Page 7: Randomising css animations

THE APPROACHRespect the separation of concernsMinimal interaction with the DOMKeep it "jank"-free

Page 8: Randomising css animations

DAFT JANK

Addy Osmani's post on jank busting

Page 9: Randomising css animations

SEPARATION OF CONCERNSDon't write HTML Elements with JavaScriptUse CSS to change appearanceUse JavaScript for the rest

Page 10: Randomising css animations
Page 11: Randomising css animations

THE APPROACH (AGAIN)Respect the separation of concernsMinimal interaction with the DOMKeep it "jank"-free

Can we achieve randomised CSS animations with thisapproach?

Page 12: Randomising css animations

HTMLKeep it simple

Page 13: Randomising css animations

PREDEFINE YOUR DOM ELEMENTS <div id="bubble_source"> <div id="bubble_0" class="bubble"></div> <div id="bubble_1" class="bubble"></div> <div id="bubble_2" class="bubble"></div> <div id="bubble_3" class="bubble"></div> <div id="bubble_4" class="bubble"></div> <div id="bubble_5" class="bubble"></div> <div id="bubble_6" class="bubble"></div> … <div id="bubble_15" class="bubble"></div> </div>

HTML… Done

Page 14: Randomising css animations

CSSThe syntax of CSS Keyframe Animations

Page 15: Randomising css animations

AT-RULE AND NAME @keyframes myAnimationName {...}

Page 16: Randomising css animations

… WITH PREFIXES @-webkit-keyframes myAnimationName {...} @-moz-keyframes myAnimationName {...} @keyframes myAnimationName {...}

Page 17: Randomising css animations

WITH KEYFRAMES @keyframes myAnimationName { from { background-position: 0 0; }

to { background-position: -162px 0; } }

MDN has a list of animatable properties

Page 18: Randomising css animations

CHOOSE THE RIGHT PROPERTIES TO ANIMATEtop/left | translate

Paul Irish's post on using translate instead of top/left

Page 19: Randomising css animations

WITH PERCENTAGE-BASED KEYFRAMES @keyframes myAnimationName { 0% { background-position: 0 0; }

100% { background-position: -162px 0; } }

Page 20: Randomising css animations

MIXED VALUES IN KEYFRAMES @keyframes myAnimationName { 0% { background-position: 0 0; }

23% { opacity: 0; background-position: -162px 0; }

100% { opacity: 1; } }

Page 21: Randomising css animations

TARGETING PREFIXED PROPERTIES @-webkit-keyframes myAnimationName { 0% {-webkit-transform-origin: 0 0;} 100% {-webkit-transform-origin: 25px 0;} }

@-moz-keyframes myAnimationName { 0% {-moz-transform-origin: 0 0;} 100% {-moz-transform-origin: 25px 0;} }

@keyframes myAnimationName { 0% {transform-origin: 0 0;} 100% {transform-origin: 25px 0;} }

Page 22: Randomising css animations

ATTACHING A DEFINED KEYFRAME ANIMATION .classWithAnimation { animation: myAnimationName 1.2s linear 0s infinite; }

Page 23: Randomising css animations

... WITH PREFIXES .classWithAnimation { -webkit-animation: myAnimationName 1.2s linear 0s infinite; -moz-animation: myAnimationName 1.2s linear 0s infinite; animation: myAnimationName 1.2s linear 0s infinite; }

Page 24: Randomising css animations

SHORTHAND PROPERTIES EXPANDED /* shorthand */ .bubble { animation: myAnimationName 1.2s linear 0s infinite; }

/* expanded */ .bubble { animation-name: myAnimationName; animation-duration: 1.2s; animation-timing-function: linear; animation-delay: 0s; animation-iteration-count: infinite; }

and that's just some of them

… at MDNthere are more

Page 25: Randomising css animations

*AHEM*… PREFIXED /* let's now call it 'bubble' */ .bubble { -webkit-animation-name: myAnimationName; -webkit-animation-duration: 1.2s; -webkit-animation-timing-function: linear; -webkit-animation-delay: 0s; -webkit-animation-iteration-count: infinite; }

Page 26: Randomising css animations

ARE WE THERE YET?CSS Keyframe Animations, they:

define a start… the inbetween frames… and the end?

Page 27: Randomising css animations
Page 28: Randomising css animations

THE END IS NOT THE END"omit the to or 100% declaration from the@keyframe…"

"then you call the animation on the progressbar…"

"and just like that, the progress bar willanimate itself up to the value set by the inlinestyle."

Chris Coyer's post on animating to an inline style

Page 29: Randomising css animations
Page 30: Randomising css animations

"omit the to or 100% declaration from the@keyframe…"

@keyframes myAnimationName { 0% {background-position: 0 0;} }

Page 31: Randomising css animations

"…then you call the animation on the progressbar…"

.bubble { animation: myAnimationName 1.2s linear 0s infinite; }

Page 32: Randomising css animations

"…and just like that, the progress bar willanimate itself up to the value set by the inlinestyle."

<div id="bubble_0" class="bubble" style="background-position: -162px 0;"></div>

Page 33: Randomising css animations
Page 34: Randomising css animations

DOES IT NEED TO BE INLINE?What if the properties were set in a class ruleset?

/* css */ @keyframes myAnimationName { 0% {background-position: 0 0;} } .bubble { animation: myAnimationName 1.2s linear 0s infinite; } .background-move { background-position: -162px 0; }

Then the class was dynamically applied to the DOM Element?

<!-- html --> <div id="bubble_0" class="bubble background-move"></div>

Page 35: Randomising css animations
Page 36: Randomising css animations

RULESET AS INLINE STYLE /* Keyframe Animation definitions */ @-webkit-keyframes lightBlue { 0% { color: #2ed0e5; -webkit-transform: translate(0, 50px) scale(.2, .2); -webkit-transform-origin: 20px 0; } 14% { color: #2ed0e5; -webkit-transform: translate(0, -100px) scale(.3, .3); -webkit-transform-origin: 43px 0; } } @-moz-keyframes lightBlue { 0% { color: #2ed0e5; -moz-transform: translate(0, 50px) scale(.2, .2); -moz-transform-origin: 20px 0; } 14% { color: #2ed0e5; -moz-transform: translate(0, -100px) scale(.3, .3); -moz-transform-origin: 43px 0; } } @keyframes lightBlue { 0% { color: #2ed0e5;

Page 37: Randomising css animations

JAVASCRIPTMake it work

Page 38: Randomising css animations

WHAT DOES JAVASCRIPT GIVE US?requestAnimationFrame/cancelAnimationFrame methodsEvent-type "animationend"

Page 39: Randomising css animations

… WITH PREFIXESrequestAnimationFrame, msRequestAnimationFrame,

mozRequestAnimationFrame,webkitRequestAnimationFrame, oRequestAnimationFrame

animationend, MSAnimationEnd, webkitAnimationEnd,oAnimationEnd

Page 40: Randomising css animations

CLASSY JAVASCRIPT var ANIMATION_CLASSES = [ // colors ['color_dark_red', 'color_red', 'color_yellow', 'color_green', 'color_dark_pink' // translations ['translateA', 'translateB', 'translateC', 'translateD', 'translateE' // origins ['originA', 'originB', 'originC', 'originD', 'originE', 'originF'], // durations ['time_1500', 'time_1800', 'time_2000', 'time_2500', 'time_2700'], // easings ['easing_1', 'easing_2', 'easing_3'], // names ['light_blue', 'mid_blue'] ];

Page 41: Randomising css animations

GAME ONWhen the page loads we:

1. Load custom classes "Bubble" and "BubbleController"2. BubbleController puts all ".bubble" divs into an Array3. It then makes two 'object pools'4. One has "Bubble" instances, the other is ids from each div in

the Array

Page 42: Randomising css animations

OBJECT POOLS ON HTML5ROCKS

Colt McAnlis's post on Object Pools in JS

Page 43: Randomising css animations

GAME ON…Then:

1. BubbleController runs a loop creating setTimeouts at+200ms

2. The interval calls BubbleController's 'createBubble' method3. This method pops a Bubble instance from its pool4. It also pops an id from the id pool5. It creates a listener for completion of the Bubble's 'init'

method6. It creates a listener for completion of the Bubble's 'hide'

method7. It runs the Bubble's 'init' method, with the id property

Page 44: Randomising css animations

OBJECT POOL CODE IN BUBBLECONTROLLER // ̀bubbles̀ is an Array of Dom Elements // ̀bubbleClass̀ is Bubble function createObjectPools (bubbles, bubbleClass) { var j = bubbles.length; var bubbleArgs = { delegateName: NAME };

while (j--) { // populate the individual bubble's ids into an Array idPool[j] = bubbles[j].id;

// use an Object Pool to create enough instances to control each bubble bubblePool[j] = new bubbleClass(bubbleArgs); } }

Page 45: Randomising css animations

'CREATEBUBBLE' METHOD INBUBBLECONTROLLER

function createBubble () { // get new bubble instance id form the pools var bubble = bubblePool.pop(); var id = idPool.pop();

// listen for the end of the new bubble's init phase $.subscribe(NAME + EVENTS.INIT + STATUS.COMPLETE + id, bubbleInitCompleteHandler);

// call init on the bubble instance bubble.init({ id: id }); }

Page 46: Randomising css animations
Page 47: Randomising css animations

GAME ON… ALMOST THEREFinally, the Bubble's 'init' method:

1. The Bubble instance gets the DOM Element via the id2. Bubble creates a listener for the 'animationend' event3. It then gets a random class from each sub-Array in

ANIMATION_CLASSES4. It saves these as a String, but doesn't set its className5. It fires off its 'init complete' Event6. BubbleController reacts to this and calls

requestAnimationFrame.7. requestAnimationFrame calls the Bubble instances 'show'

method8. The 'show' method attaches the classlist, starting the

animation

Page 48: Randomising css animations

'INIT' METHOD IN BUBBLE Bubble.prototype.init = function (args) { // add inited variables this.id = args.id; this.node = doc.getElementById(args.id); this.$node = $(this.node); this.classList = 'bubble on';

// add listeners addListeners(this); setClassList(this);

$.publish(this.delegateName + EVENTS.INIT + STATUS.COMPLETE + this.id, [this]); };

Page 49: Randomising css animations

RANDOMISING THROUGH THEANIMATION_CLASSES ARRAY

function setClassList (instance) { var j = ANIMATION_CLASSES.length;

while (j--) { instance.classList += (' ' + randomValue(ANIMATION_CLASSES[j])); } }

function randomValue (arr) { var length = arr.length; var idx = (Math.random() * length) | 0;

return arr[idx]; }

Page 50: Randomising css animations

CALLING REQUESTANIMATIONFRAME INBUBBLECONTROLLER

function bubbleInitCompleteHandler (e, bubble) { $.unsubscribe(e.type, bubbleInitCompleteHandler);

win.requestAnimationFrame(function () { bubble.show(); }); }

Page 51: Randomising css animations

'SHOW' METHOD IN BUBBLE Bubble.prototype.show = function () { // appending the classes makes the bubble appear and the animation run this.node.className = this.classList; };

Page 52: Randomising css animations

GAME OFF'animationend' event

1. The Bubble reacts to the DOM Element's 'animationend'event

2. It changes the className of the DOM Element to "splat"3. It runs its 'hide' method and fires off 'hide complete'4. Inside the 'hide complete' Event is the id as a String5. BubbleController reacts to this6. It 'pools' the Bubble instance and 'pools' the id7. It then runs its 'createBubble' method to start all over again

Page 53: Randomising css animations

RE-'POOLING' THE BUBBLE AND ID INBUBBLECONTROLLER

function bubbleAnimationCompleteHandler (e, bubble, id) { // add the completed bubble and its id back into the pools bubblePool.unshift(bubble); idPool.unshift(id);

createBubble(); }

Page 54: Randomising css animations

SO!!!Did it work?

Labs home page

Page 55: Randomising css animations

TIME ESCAPES METhe bubbles are done with :before and :afterThey're webfonts - that's a story in itselfYou can pause the bubbles'animation-timing-function' easing is done with cubic-beziersTHEY'RE CLICKABLE!

Page 56: Randomising css animations
Page 57: Randomising css animations
Page 58: Randomising css animations
Page 59: Randomising css animations

[email protected]@adambankin

DID I MENTION WE'REHIRING?!