Animating translate3d with jQuery

Using CSS3's translate3d for animated transitions can greatly improve performance, especially on mobile, because doing so triggers hardware acceleration. This means that your phone will kick in a little extra umph to get the animation done.

But normally you have to use CSS to achieve these animations, because transform: translate3d(x, y, z); can't be manipuated via jQuery's animate() method. And if you use only CSS, you lose the convenience of the complete callback (a callback fired when the animation is complete).

I was working on a project with some simple animations, but advanced enough that CSS alone wasn't enough. So I whipped up a little helper function in jQuery to help me out. It's a bit hacky, but it worked great for my needs. Basically, it sets the easing and duration that you want on the element, then applies the translation. Then, using setTimeout, it removes the easing and duration part of the CSS and fires the complete callback.

The first parameter is a collection with defaults { x: 0, y: 0, z: 0}. The other 3 parameters are the same as jQuery's animate, meaning you can skip some of the parameters (see http://api.jquery.com/animate/).

Here's the code:

;(function($) {
    var delay = 0;
    $.fn.translate3d = function(translations, speed, easing, complete) {
        var opt = $.speed(speed, easing, complete);
        opt.easing = opt.easing || 'ease';
        translations = $.extend({x: 0, y: 0, z: 0}, translations);

        return this.each(function() {
            var $this = $(this);

            $this.css({ 
                transitionDuration: opt.duration + 'ms',
                transitionTimingFunction: opt.easing,
                transform: 'translate3d(' + translations.x + 'px, ' + translations.y + 'px, ' + translations.z + 'px)'
            });

            setTimeout(function() { 
                $this.css({ 
                    transitionDuration: '0s', 
                    transitionTimingFunction: 'ease'
                });

                opt.complete();
            }, opt.duration + (delay || 0));
        });
    };
})(jQuery);

It worked great for what I needed it for, but your mileage may vary... But it was definitely worth it, cuz after I started using this, the animations were 10 times better on mobile. Much smoother.

Anyway... enjoy!