Javascript function for easier cross-browser CSS3 transformations
I'm currently using a lot of CSS3 transforms for sliding and zooming images. As with all the new HTML5/CSS3 techniques, the fact that they are not supported by all the browsers is a pain in the ass. So I made some functions to generate some cross-browser CSS3 transform codes, to apply on my styles.
And here they are, wrapped inside a nice object (you can also get a .js file from here)
CSS = {
/**
* Generates CSS3's translate3d transformation style for Opera, Chrome/Safari, Firefox and IE
*
* @method translate3d
* @param {Number} x The X axis coordinate
* @param {Number} y The Y axis coordinate
* @param {Number} z The Z axis coordinate
* @param {Number} t The transition time / animation duration, defaults to 0
* @return {String} The css style code
*/
translate3d : function(x, y, z, t) {
t = (typeof t === "undefined") ? 0 : t; //defaults to 0
var tr = '-webkit-transform: translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px); -webkit-transition: ' + t + 'ms;' +
'-moz-transform: translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px); -moz-transition: ' + t + 'ms;' +
'-ms-transform: translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px); -ms-transition: ' + t + 'ms;' +
'-o-transform: translate(' + x + 'px, ' + y + 'px); -o-transition: ' + t + 'ms;' +
'transform: translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px); transition: ' + t + 'ms;';
return tr;
},
/**
* Generates CSS3's scale3d transformation style for Opera, Chrome/Safari, Firefox and IE
* The scaling is symetric, with the same value for width and height
*
* @method scale3d
* @param {Number} s The scale
* @param {Number} t The transition time / animation duration, defaults to 0
* @return {String} The css style code
*/
scale3d : function(s, t) {
t = (typeof t === "undefined") ? 0 : t; //defaults to 0
var tr = '-webkit-transform: scale3d(' + s + ', ' + s + ', 1); -webkit-transition: ' + t + 'ms;' +
'-moz-transform: scale3d(' + s + ', ' + s + ', 1); -moz-transition: ' + t + 'ms;' +
'-ms-transform: scale3d(' + s + ', ' + s + ', 1); -ms-transition: ' + t + 'ms;' +
'-o-transform: scale(' + s + '); -o-transition: ' + t + 'ms;' +
'transform: scale3d(' + s + ', ' + s + ', 1); transition: ' + t + 'ms;';
return tr
},
/**
* Used to move a scaled element using translate, while keeping the scale
* Generates the required CSS3 style for Opera, Chrome/Safari, Firefox and IE
*
* @method zoomTo
* @param {Number} x The X axis coordinate of the transformation
* @param {Number} y The Y axis coordinate of the transformation
* @param {Number} s The scale of the element (symetric, with the same value for width and height)
* @param {Number} t The transition time / animation duration, defaults to 0
* @return The css style code
*/
zoomTo : function(x, y, s, t) {
s = (typeof s === "undefined") ? 2 : s; //defaults to 2
t = (typeof t === "undefined") ? 0 : t; //defaults to 0
var tr = '-webkit-transform: translate3d(' + x + 'px, ' + y + 'px, 0px) scale3d(' + s + ', ' + s + ', 1);' +
'-moz-transform: translate3d(' + x + 'px, ' + y + 'px, 0px) scale3d(' + s + ', ' + s + ', 1);' +
'-ms-transform: translate3d(' + x + 'px, ' + y + 'px, 0px) scale3d(' + s + ', ' + s + ', 1);' +
'-o-transform: translate(' + x + 'px, ' + y + 'px) scale(' + s + ');' +
'transform: translate3d(' + x + 'px, ' + y + 'px, 0px) scale3d(' + s + ', ' + s + ', 1);' +
'-webkit-transition: ' + t + 'ms;' +
'-moz-transition: ' + t + 'ms;' +
'-ms-transition: ' + t + 'ms;' +
'-o-transition: ' + t + 'ms;' +
'transition: ' + t + 'ms;';
return tr;
}
}
First I needed the translate3d transformation, to move the slider. Since it uses hardware acceleration, it's supposed to be faster than the classic transformation. The only problem is that Opera doesn't offer support for it yet, so it has to be replaced with a simple translate.
So how do you use it?
Let's say you have a div with the id testDiv and you want to move it with 300 pixels to the left and 100 pixels down. And you also want to use it with a nice animation that lasts half a second (500ms)
testDiv = document.getElementById('testDiv');
testDiv.setAttribute('style', CSS.translate3d(-300, 100, 0, 500));
Wanna move it back after that, with no animation this time? Easy
testDiv.setAttribute('style', CSS.translate3d(0, 0, 0));
A 0, 0, 0 translation resets the object to its original position and the last parameter, the animation duration is optional and defaults to 0 (no animation).
The next function scales an element and I used it for zooming. Since I needed a nice, symmetric zoom and not a skew or a stretch, I only use one parameter and zoom it with the same ratio for both width and height. So here's how you would apply a 2x zoom to the testDiv, with a 1 second animation:
testDiv.setAttribute('style', CSS.scale3d(2, 1000));
To reset, apply a scale of 1.
And to wrap things up, I also made an rather ambiguously named function zoomTo, that I use to let the user drag around the zoomed image in case it doesn't fit on the screen. It's basically a 3d translation applied to a scaled object. So in order to move with 200 pixels to the right and 100 pixels to the top a zoomed div, just do this
testDiv.setAttribute('style', CSS.zoomTo(200, -100, 2));
And there you have it!