Transforms are objects that encapsulate the four transformation components: translation, rotation, scale, and skew.
Transforms correspond directly to the CSS3 transformation matrix, combining their four components into a 16-element array. In conjunction with modifiers, they can be applied to renderables to produce visual effects.
Since Famo.us styles all DOM elements with position: absolute
, their positions must be defined by transform objects. In fact, this is the core technique that makes the Famo.us platform performant.
The Transform
class provides functions to break down a full transform into the four components. It also to provides functions to build up full transforms from them. In combination, we can use these functions to make elements appear to move, spin, and orient themselves in space.
All of the Transform
class’ functions return a full transform matrix. Modifiers insert that transform into the render tree, which applies it to all the elements beneath it. Now let’s take a look at how transforms are used in practice.
In general, we assign the output of a transform object to the transform
property of a modifier. The modifier handles applying that transform to the appropriate elements in the render tree. For example:
var modifier = new Modifier({
transform: Transform.translate(100, 200, 300)
});
If we take the above snippet, and replace the transform’s .translate()
method invocation with its output, the stanza above would look like this:
var modifier = new Modifier({
transform: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 100, 200, 300, 1]
});
That output, in turn, maps to a CSS matrix3d
transform:
transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 100, 200, 300, 1);
We can do more with transforms than just .translate()
elements as shown in the examples above. All transforms are built up from the following transform primitives, beginning with identity
, which represents an “unchanged” transform state. The transform primitives possible are:
The translate, scale, rotate, and skew components all have default values:
[0, 0, 0]
[0, 0, 0]
[1, 1, 1]
[0, 0, 0]
Now, let’s look at how to use each of these primitives individually:
Transform.identity
returns a 16-element array that represents no change:
Transform.identity
=> [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
// @famous-block
// @famous-block-option preset famous-0.3.0-globals
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var Modifier = famous.core.Modifier;
var Transform = famous.core.Transform;
var context = Engine.createContext();
var surface = new Surface({
size: [200, 200],
content: 'No change!',
properties: {
backgroundColor: '#fa5c4f'
}
});
var modifier = new Modifier({
transform: Transform.identity
});
context.add(modifier).add(surface);
Transform.translate(x, y, z)
takes three numbers representing pixels, and returns a 16-element array that represents a translation in each of the three directions.
Transform.translate(x, y, z);
=> [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1]
// @famous-block
// @famous-block-option preset famous-0.3.0-globals
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var Modifier = famous.core.Modifier;
var Transform = famous.core.Transform;
var context = Engine.createContext();
var surface = new Surface({
size: [200, 200],
content: 'Translated!',
properties: {
backgroundColor: '#fa5c4f'
}
});
var modifier = new Modifier({
transform: Transform.translate(100, 200)
});
context.add(modifier).add(surface);
Transform.scale(x, y, z)
takes three numbers representing scale factors, returns a 16-element array that represents a change in scale in each of the three directions.
Transform.scale(x, y, z);
=> [x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1]
// @famous-block
// @famous-block-option preset famous-0.3.0-globals
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var Modifier = famous.core.Modifier;
var Transform = famous.core.Transform;
var context = Engine.createContext();
var surface = new Surface({
size: [200, 200],
content: 'Scaled!',
properties: {
backgroundColor: '#fa5c4f'
}
});
var modifier = new Modifier({
transform: Transform.scale(1.5, 2.0)
});
context.add(modifier).add(surface);
Transform.rotateX(theta)
, Transform.rotateY(theta)
, and Transform.rotateZ(theta)
take in a value in radians, and return a 16-element array that represents a rotation in each of the the respective directions. (A shorthand, Tranform.rotate(x, y, z)
, is also available.)
Transform.rotateX(theta);
=> [1, 0, 0, 0, 0, cos(theta), -sin(theta), 0, 0, sin(theta), cos(theta), 0, 0, 0, 0, 1]
Transform.rotateY(theta);
=> [cos(theta), 0, sin(theta), 0, 0, 1, 0, 0, sin(theta), 0, cos(theta), 0, 0, 0, 0, 1]
Transform.rotateZ(theta);
=> [cos(theta), -sin(theta), 0, 0, sin(theta), cos(theta), 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
// @famous-block
// @famous-block-option preset famous-0.3.0-globals
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var Modifier = famous.core.Modifier;
var Transform = famous.core.Transform;
var context = Engine.createContext();
var surface = new Surface({
size: [200, 200],
content: 'Rotated!',
properties: {
backgroundColor: '#fa5c4f'
}
});
var modifier = new Modifier({
transform: Transform.rotate(0.5, 1.0, 0.4)
});
context.add(modifier).add(surface);
Transform.skewX(theta)
and Transform.skewY(theta)
take in a value in radians, and return a 16-element array that represents a distortion.
Transform.skewX(theta)
=> [1, 0, 0, 0, tan(theta), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
Transform.skewY(theta)
=> [1, tan(theta), 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
// @famous-block
// @famous-block-option preset famous-0.3.0-globals
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var Modifier = famous.core.Modifier;
var Transform = famous.core.Transform;
var context = Engine.createContext();
var surface = new Surface({
size: [200, 200],
content: 'Skewed!',
properties: {
backgroundColor: '#fa5c4f'
}
});
var modifier = new Modifier({
transform: Transform.skewX(0.5)
});
context.add(modifier).add(surface);
The Transform
class also has two preset transforms that can be used move the apparent placement of renderables toward or away from the screen. These are useful when layering renderables.
The Transform.inFront
property provides a small Z-translation forward toward the user.
The Transform.behind
property provides a small Z-translation backward away from the user.
Copyright © 2013-2015 Famous Industries, Inc.