Beyond simple transitions,

with a pinch of Javascript.

Peter Nederlof

N toggles notes, P toggles fullscreen, arrow keys (or tap left/right) to navigate.

Hello

Twitter
@peterlof, @ExMachinaGames

Ex Machina Games
http://www.exmachinagames.com

Github
https://github.com/peterned

Slides
online asap!

Second screen results were more accurate than any polls!

In this presentation

  1. Brief recap of CSS properties
  2. Animating everything with transitions
  3. The problem with that
  4. The solution
  5. Demos
  6. Closing thoughts

Vendor prefixes etc

#derp {
	-webkit-transform: translate(50px, 50px);
	-moz-transform: translate(50px, 50px);
	-ms-transform: translate(50px, 50px);
	-o-transform: translate(50px, 50px);
	transform: translate(50px, 50px);
}

Imagine these were there ...

Also, all Javascript examples in these slides use native APIs only.

Brief recap

CSS Transformations

Translate

translate(x, y), translateX(x), translateY(y)

#derp {
	transform: translate(50px, 50px);
}

Scale

scale(x, y), scaleX(x), scaleY(y)

#derp {
	transform: scale(2, 0.5);
}

Rotate

rotate(angle)

#derp {
	transform: rotate(30deg);
}

Skew

skew(x, y), skewX(x), skewY(y)

#derp {
	transform: skew(30deg, 0);
}

Combined transformations

#derp {
	transform: translate(50px, 50px) scale(2, 0.5) rotate(30deg);
}

2D Matrix

matrix(scaleX, skewY, skewX, scaleY, translateX, translateY);

#derp {
	transform: matrix(1.17, -0.42, -0.14, 0.96, -75.20, 53.25);
}

Primarily for browsers internally, but don't dismiss it!

Brief recap

Transformations in 3D space

Translate, rotate, scale

Adds ...Z(z) and ...3d(x, y, z) transformations, except for skew.

#derp {
	transform: translate3d(0, 20px, 100px) rotateY(20deg);
}

on skewZ: http://lists.w3.org/Archives/Public/www-style/2010Jun/0061.html

Matrix3D

This function allows you to specify the raw 4x4 homogeneous transformation matrix of 16 values in column-major order. Have fun with that!

Matrix3D

#derp {
	transform: matrix3d(0.869295848659877, -0.03752066987527169,
	-0.4928660333547193, 0, 0.09933466539753062, 0.9900332889206209,
	0.09983341664682815, 0, 0.48420796333090704, -0.13574345715771877,
	0.8643589312813316, 0, 116.20991119941769, 12.5784297178525,
	112.55385649248043, 1);
}

Primarily for browsers internally, but don't dismiss it!

Additional 3D properties

Brief recap

CSS Transitions

Transitions

single,

#derp {
	transition: property duration easing delay;
}

and multiple,

#derp {
	transition:
		property duration easing delay,
		property duration easing delay;
}

Typical transiton using :hover

#derp {
	transition: transform 0.5s ease-out;
}

#derp:hover {
	transform: scale(1.25, 1.25);
}

Easing?

Default easing is not linear.

undefined

linear

Delays?

#derp {
	transition: transform 0.5s, opacity 0.5s 0.5s;
}

#derp:hover {
	transition: transform 0.5s 0.5s, opacity 0.5s;
}

At :hover the new delays are applied immediately!

Animating things

Animating things

Basically, there are two types of animations:

Static
From A to B: hovers, fades, etc.

Dynamic
Based on user interaction: drag & drop, inertia, ect.

Dynamic Animations

Mostly Javascript based, either using a library or a self-made script.

Unpredictable by nature

May use transformations, but probably no transitions ...

"Couldn't these use transitions too?"

Benefits of transitions

Why would we want to use transitions instead of an animation script?

Optimized in every way

This is why you should be using transitions and 3D transforms already:

The problem

transitions have no stop at current position

Stopping a transition?

What happens if you query the current property value with Javascript?

	// find the element
	var derp = document.querySelector("#derp");
	// get its computed style
	var computed = window.getComputedStyle(derp, null);
	// and query the value
	console.log(computed.getPropertyValue('transform'));

Let's try that, ...

current value:  

Possible solution?

Query the current transform value, and assign it ...

Possible solution

Plan of attack: Query the current transform value, and assign it ...

	// find the element, style and value
	var derp = document.querySelector("#derp");
	var computed = window.getComputedStyle(derp, null);
	var transform = computed.getPropertyValue('transform');
	// remove the transition
	derp.style.removeProperty('transition');
	// and assign the transformation
	derp.style.setProperty('transform', transform, '');

Let's try that too, ...

Real world example

Theory schmeory

Real world example

Draggable element with inertia, using 2D transforms and transitions.

Free rotating cube with inertia, using 3D transforms and transitions.

Matrix3D in Javascript

	// ...

	rotateY: function (a) {
		var c = Math.cos(a);
		var s = Math.sin(a);

		return this.multiply([
			 c, 0, s, 0,
			 0, 1, 0, 0,
			-s, 0, c, 0,
			 0, 0, 0, 1
		]);
	},

	// ...

Available on github!

Things to keep in mind

Querying CSS property values might not always work, for instance on inherited properties like fonts and colors.

The "transitionEnd" event is not fired when a transition is interrupted.

Assigning styles via the Javascript API has very high specificity.

	// remove the transition
	derp.style.removeProperty('transition');

So what about fallbacks?

Make fallbacks for critical cases only; like left and top positioning for lte IE8 instead of transformations.

Otherwise, use them as progressive enhancements, a lot.

Convice your client or project manager that this is OK.