Matrix.js
Featherweight CSS 3D Engine
Similar to Three.js CSS3D Renderer, but less intrusive and much lighter in weight. The core is 2kb minified/gzipped. Doesn't provide any vector/matrix math utilities though.
But there are no matrices in the source code!
Originally I wanted to use matrix3d() for everything, hence the name. Ironically it turned out that using native CSS transform functions is faster than multiplying matrices in JavaScript, so I eneded up not using matrices at all.
Compatibility
Mostly it has to do with the Browser's capability of handling CSS3D transforms. Works best in Chrome, very good in Safari (both desktop and iOS), and not so good in Firefox (not hardware accelerated and has some z-index issues). Doesn't work in IE10 because IE10 doesn't support transform-style: preserve-3d
yet.
Examples
Documentation
The core is simply mx.js
which provides:
There are a few other extensions such as MX.Scene
and MX.RotationControl
, and pre-built objects such as MX.Box
, MX.Coords
and MX.TexturedBox
which can all be separately loaded as needed. For usage of these extensions, please refer to the examples
folder.
MX
The global object. Contains all the components and some global configurations.
Properties
-
MX.rotationUnit { String }
Default:
'rad'
, other available value:'deg'
.
Unit used for rotation values. -
MX.positionAtCenter { Boolean }
Default:
true
Whether or not to auto-center.mx-object3d
elements. Seeexamples/no_centering.html
for more details.
Methods
-
MX.toRad()
converts degrees to radians.
-
MX.toDeg()
converts radians to degrees.
MX.Object3D
The core base class. Every MX.Object3D
has an el
property which is the native DOM element. You can create a new MX.Object3D
in multiple ways:
// attach to an existing element:
var wrappedObj = new MX.Object3D(document.getElementById('my-object'))
// create an element with specified tag, id or classname:
var obj = new MX.Object3D('div#main-box.box')
// obj.el => <div id="main-box" class="box"></div>
// or nothing at all, and el will just be a div.
var obj2 = new MX.Object3D()
It also comes with an inheritence util method extend()
:
// Creating a resuable box class
var Box = MX.Object3D.extend({
// init will be called in the constructor function
init: function () {
// MX.Object3D's constructor is called first
// so this.el will be already created in here
this.el.classList.add('box')
},
// all other properties will be mixed into the prototype
spin: function () { ... }
})
var box = new Box()
// You can further extend Box:
var BigBox = Box.extend({
init: function () {
this.scale = 10
}
})
Once you have an MX.Object3D
instance, you can manipulate in a style similar to Flash/ActionScript:
var obj = new MX.Object3D().addTo('body')
obj.x = 100
obj.y = 100 // y axis points UPWARDS!
obj.z = 100 // z axis points AWAY from the user
obj.rotationX += Math.PI / 2 // default rotation unit is in radian
obj.update() // you need to call update() to actually apply the css change to DOM
Instance Properties
-
el { HTMLElement }
The DOM element
-
x, y, z { Number }
Default:
0
The position of the element in the 3D space, relative to:- Its parent object's center if
MX.positionAtCenter
istrue
- Its default position on page if
MX.positionAtCenter
isfalse
- Its parent object's center if
-
rotationX, rotationY, rotationZ { Number }
Default:
0
The rotation on each axis. The euler order is XYZ. -
scaleX, scaleY, scaleZ { Number }
Default:
1
The scale on each axis. -
scale { Number }
Default:
1
The scale for all three axes. If this is not 1 it will override any scaling on individual axis. -
perspective { Number }
Default:
0
The perspective for this object, relative to its own center. -
width, height { Number }
Default:
0
el
's CSS width & height. Setting this will changeel
's CSS width & height properties. -
parent { MX.Object3D }
Default:
undefined
The parent object containing this object. -
children { [ MX.Object3D ] }
Default:
[]
An array containing all children objects. -
updateChildren { Boolean }
Default:
true
Whether to call children'supdate()
as well during its ownupdate()
. -
rotationOrigin { Object }
Default:
undefined
If set, all rotations will happen relative to this point. Can be any object that hasx
,y
andz
properties. -
followTarget { Object }
Default:
undefined
If set, will aotumatically calllookAt(this.followTarget)
on everyupdate()
. Can be any object that hasx
,y
andz
properties. -
inverseLookAt { Boolean }
Default:
false
Inverse look at facing forlookAt()
,follow()
andgetLookAtEuler()
methods.
Instance Methods
-
update()
Check if the object's transform properties have changed, if yes, apply the CSS transform to
el
. IfupdateChildren
istrue
, will also callupdate()
on all children objects. -
add(child1, child2, ...)
Add child objects. Takes any number of arguments, which must be instances of
MX.Object3D
. -
remove(child1, child2, ...)
Remove child objects. Takes any number of arguments, which must be instances of
MX.Object3D
. -
addTo(target)
Add the object itself to a target. The target can be an instance of
MX.Object3D
, a native DOM element, or a querySelector string. -
lookAt(target)
Set the object's rotation so that it's facing the given target. Target can be any object with
x
,y
,z
properties. -
getLookAtEuler(target)
Returns an object whose
x
,y
,z
properties are the amount of rotations needed on each axis for the object to face the target. -
reset()
Resets object's position, rotation, scaling, rotationOrigin and followTarget to default values.
-
removeElement()
Removes the object's DOM element from the page.
-
setPosition(target), setRotation(target), setScale(target)
Convenience methods for setting values on multiple axis (maybe helpful when used in conunction with a 3d vector library). Target can be any object with
x
,y
,z
properties. Any omitted axis will use current value. -
setCSSTransformOrigin(value), setCSSTransformStyle(value), setCSSTransition(value), setCSSPerspective(value)
Set the object's
el
's CSS properties. -
onTransitionEnd(callback)
Add a listener for CSS transition end event. Automatically removes itself when fired.