Walrus
Walrus

Reputation: 20444

JQuery animate enhanced through webkit, inconsistent

The following code controls a function for sliding various items across a bar. It is using a plugin called JQuery animate enhanced that uses CSS3 where possible on supporting browsers.

Without CSS3 the function works perfectly. However with CSS3 once all tabs have been selected the first one will no longer cooperate.

the fiddle: http://jsfiddle.net/cqBZz/3/

the code:

$(document).ready(function () {
    var bounceholder = 0;
    var delayact = 0;
    $('.bouncetabs a').click(function () {
        $('.bouncetabs a').removeClass('active');
        $(this).addClass('active');

        if ($(this).index('.bouncetabs a') < bounceholder) {
            var backwards = 1
        } else {
            var backwards = 0
        }

        bounceholder = $(this).index('.bouncetabs a');
        var bounceoffset = 0;

        if ($('.bounceholder ul:eq(' + bounceholder + ') li').length == 6) {
            var bounceoffset = 0;
        } else if ($('.bounceholder ul:eq(' + bounceholder + ') li').length == 5) {
            var bounceoffset = 72;
        } else if ($('.bounceholder ul:eq(' + bounceholder + ') li').length == 4) {
            var bounceoffset = 144;
        } else if ($('.bounceholder ul:eq(' + bounceholder + ') li').length == 3) {
            var bounceoffset = 216;
        } else if ($('.bounceholder ul:eq(' + bounceholder + ') li').length == 2) {
            var bounceoffset = 288;
        }

        $('.bounceholder ul:eq(' + bounceholder + ')').prevAll().each(function () {
            $('li', this).each(function () {
                $(this).delay(150).animate({
                    left: -200,
                    top: 0,
                    leaveTransforms: true
                }, {
                    duration: 400,
                    queue: true
                });
            });
        });
        $('.bounceholder ul:eq(' + bounceholder + ')').nextAll().each(function () {
            $('li', this).each(function () {
                $(this).delay(150).animate({
                    left: +1000,
                    top: 0,
                    leaveTransforms: true
                }, 600);
            });
        });

        if (backwards == 1) {
            bounceoffset = 800 - bounceoffset;
            $($('.bounceholder ul:eq(' + bounceholder + ') li').get().reverse()).each(function (i) {
                delay = (i + 1) * 100;
                $(this).delay(delay).animate({
                    left: +bounceoffset,
                    top: 0,
                    opacity: 0.6,
                    leaveTransforms: true
                }, {
                    duration: 400,
                    queue: true
                });
                bounceoffset -= 160;
            });
        } else {
            $('.bounceholder ul:eq(' + bounceholder + ') li').each(function (i) {
                delay = (i + 1) * (100 * delayact);
                $(this).delay(delay).animate({
                    left: +bounceoffset,
                    top: 0,
                    opacity: 0.6,
                    leaveTransforms: true
                }, {
                    duration: 400,
                    queue: true
                });
                bounceoffset += 160;
            });
        }
        delayact = 1;

        return false
    });

});

Upvotes: 2

Views: 1508

Answers (1)

J&#246;rn Berkefeld
J&#246;rn Berkefeld

Reputation: 2579

The best way to deal with hardware acceleration currently is using a combination of CSS3 transition for -moz-translate, -webkit-translate and -webkit-translate3d and jQuery animate. My personal experience with the above mentioned tool is rather bad. It caused multiple errors on my pages.

Also set translateZ(0px) for all elements you want to move as translate3d is only used for safari and chrome (enables hardware acceleration)

Here's something to get started with. You have to add checks for browsers to make it work.

if(browser.isFF) {
    function moveDOM(jQueryObj,x,y) { 
        jQueryObj[0].style.cssText += '-moz-transform:translate('+x+'px,'+y+'px);'; 
    } // firefox does not know translate3d
} else if(browser.isAndroid) {
    function moveDOM(jQueryObj,x,y) {
        jQueryObj[0].style.cssText += '-webkit-transform:translate('+x+'px,'+y+'px);';
    } // most Android version currently don't know translate3d (U could add checks for the Android versions though -> caniuse.com
} else if(browser.isSafari || browser.isChrome) {
    function moveDOM(jQueryObj,x,y) {
        jQueryObj[0].style.cssText += '-webkit-transform:translate3d('+x+'px,'+y+'px,0px);';
    };
} else { // ie opera, others
    function moveDOM(jQueryObj,x,y) { 
        jQueryObj.animate({'left':x,'top':y},500); 
    };
}

// example run of the function, moving the element with the id myDiv to position (50,90)
moveDOM($("#myDiv"),50,90);

the delay for the css translates can be set via CSS3:

-webkit-transition: all 0.5s ease; -moz-transition: all 0.5s ease;

PS: you might wonder why i used default JS instead of jQuery's .css() functoin in 3 out of 4 cases... It's simply faster. If you want to increase speed even further, replace the += with = but that overwrites any other stlyes you might have added.

Upvotes: 1

Related Questions