Skip to content

Instantly share code, notes, and snippets.

@MattRoelle
Created March 5, 2014 01:45
Show Gist options
  • Save MattRoelle/9359662 to your computer and use it in GitHub Desktop.
Save MattRoelle/9359662 to your computer and use it in GitHub Desktop.
/*
* CSS matrix3d transform API
* Simplification of 3d transforms
* Matt Roelle
* 2013
*
* Dependent on the Sylvester math library (http://sylvester.jcoglan.com/)
*/
function Surface() {
// identity matrix, has no effect
this.matrix = Matrix.Diagonal([1,1,1,1]);
this.stack = [];
}
Surface.prototype.push = function() {
this.stack.push(this.matrix);
return this;
};
Surface.prototype.pop = function() {
this.matrix = this.stack.pop();
return this;
};
Surface.prototype.toCssString = function() {
var buffer = 'matrix3d(';
for(var y = 1; y <= 4; y++) {
for(var x = 1; x <= 4; x++) {
buffer += (this.matrix.e(y,x) + ',');
}
}
return (buffer.slice(0, buffer.length-1)+')');
};
Surface.prototype.bindToDomElement = function(element) {
this.domElement = element;
};
Surface.prototype.updateCSS = function(element) {
element.style['-webkit-transform'] = this.toCssString();
element.style['-moz-transform'] = this.toCssString();
element.style['-ms-transform'] = this.toCssString();
element.style['-o-transform'] = this.toCssString();
element.style['transform'] = this.toCssString();
};
Surface.prototype.update = function() {
if (this.domElement !== undefined) {
// if the surface is bound to a DOM element, automatically update the CSS
this.updateCSS(this.domElement);
}
/* all transformation functions return `this`, for chainability
* ie
* surface
* .translate(100,100)
* .rotate(0,Math.PI/2)
* .scale(2,2);
*/
return this;
};
Surface.prototype.translate = function(x, y, z) {
if (x === undefined) {
x = 0;
}
if (y === undefined) {
y = 0;
}
if (z === undefined) {
z = 0;
}
this.matrix = this.matrix.x($M([
[1,0,0,0],
[0,1,0,0],
[0,0,1,0],
[x,y,z,1]
]));
return this.update();
};
Surface.prototype.scale = function(x, y, z) {
if (x === undefined) {
x = 0;
}
if (y === undefined) {
y = 0;
}
if (z === undefined) {
z = 0;
}
this.matrix = this.matrix.x($M([
[x,0,0,0],
[0,y,0,0],
[0,0,z,0],
[0,0,0,1]
]));
return this.update();
};
Surface.prototype.rotate = function(x, y, z) {
if (x === undefined) {
x = 0;
}
if (y === undefined) {
y = 0;
}
if (z === undefined) {
z = 0;
}
this.matrix = this.matrix.x($M([
// x-axis rotation
[1,0,0,0],
[0,Math.cos(x),Math.sin(-1*x),0],
[0,Math.sin(x),Math.cos(x),0],
[0,0,0,1]
])).x($M([
// y-axis rotation
[Math.cos(y),0,Math.sin(y),0],
[0,1,0,0],
[Math.sin(-1*y),0,Math.cos(y),0],
[0,0,0,1]
])).x($M([
// z-axis rotation
[Math.cos(z),Math.sin(-1*z),0,0],
[Math.sin(z),Math.cos(z),0,0],
[0,0,1,0],
[0,0,0,1]
]));
return this.update();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment