jquery animate background-position firefox
Asked Answered
R

5

9

I got this background image slider thing working in chrome and safari, but it doesnt do anything in firefox. any help?

$(function(){
    var image= ".main-content";
    var button_left= "#button_left";
    var button_right= "#button_right";
    var animation= "easeOutQuint";
    var time= 800;
    var jump= 800;
    var action= 0;

    $(button_left).click(function(){
        right();
    });
    $(button_right).click(function(){
        left();
    });
    $(document).keydown(function(event){
        if(event.keyCode == '37'){
            right();
        }
    });
    $(document).keydown(function(event){
        if(event.keyCode == '39'){
            left();
        }
    });
    function left(){
        if(action == 0){
            action= 1;
            $(image).animate({backgroundPositionX: '-='+jump+'px'}, {duration: time, easing: animation});
            setTimeout(anim, time);
        }

    }
    function right(){
        if(action == 0){
            action= 1;
            $(image).animate({backgroundPositionX: '+='+jump+'px'}, {duration: time, easing: animation});
            setTimeout(anim, time);
        }
    }
    function anim(){
        action= 0;
    }
}); 

I also tried this but it also does nothing

$(image).animate({backgroundPosition: '500px 0px'}, 800);
Radiometeorograph answered 1/4, 2011 at 21:4 Comment(1)
I will if anyone can help solve my problemRadiometeorograph
R
2

here try this for background animation

(function($) {
    if (!document.defaultView || !document.defaultView.getComputedStyle) {
        var oldCurCSS = jQuery.curCSS;
        jQuery.curCSS = function(elem, name, force) {
            if (name === 'background-position') {
                name = 'backgroundPosition';
            }
            if (name !== 'backgroundPosition' || !elem.currentStyle || elem.currentStyle[name]) {
                return oldCurCSS.apply(this, arguments);
            }
            var style = elem.style;
            if (!force && style && style[name]) {
                return style[name];
            }
            return oldCurCSS(elem, 'backgroundPositionX', force) + ' ' + oldCurCSS(elem, 'backgroundPositionY', force);
        };
    }
    var oldAnim = $.fn.animate;
    $.fn.animate = function(prop) {
        if ('background-position' in prop) {
            prop.backgroundPosition = prop['background-position'];
            delete prop['background-position'];
        }
        if ('backgroundPosition' in prop) {
            prop.backgroundPosition = '(' + prop.backgroundPosition;
        }
        return oldAnim.apply(this, arguments);
    };

    function toArray(strg) {
        strg = strg.replace(/left|top/g, '0px');
        strg = strg.replace(/right|bottom/g, '100%');
        strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g, "$1px$2");
        var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
        return [parseFloat(res[1], 10), res[2], parseFloat(res[3], 10), res[4]];
    }
    $.fx.step.backgroundPosition = function(fx) {
        if (!fx.bgPosReady) {
            var start = $.curCSS(fx.elem, 'backgroundPosition');

            if (!start) { //FF2 no inline-style fallback
                start = '0px 0px';
            }
            start = toArray(start);
            fx.start = [start[0], start[2]];
            var end = toArray(fx.options.curAnim.backgroundPosition);
            fx.end = [end[0], end[2]];
            fx.unit = [end[1], end[3]];
            fx.bgPosReady = true;
        }
        //return;
        var nowPosX = [];
        nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
        nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
        fx.elem.style.backgroundPosition = nowPosX[0] + ' ' + nowPosX[1];
    };
})(jQuery);

Call to it like this,

$(this).animate({
    backgroundPosition: '0 0'
})
Rifleman answered 1/4, 2011 at 21:11 Comment(5)
did you add the last few bits of code })(jQuery); to the end of the plugin? also make sure whatever it is you want to animate is a background image.Rifleman
I forgot the extra bits, and it worked :) I had to add a little to my left and right functions to retrieve the new current position, but it works. Its still not quite as smooth as the webkit animate but it got the job done. thank you very much!Radiometeorograph
No worries, glad to be of help.Rifleman
please in future check your code formatting when you post. Just pasting it screws up the indentation, particularly when the source code file uses tabs. I have fixed it for you this time :-) (and the syntax error).Tereasaterebene
Here is the link to the plugin (referenced in the answer): protofunc.com/scripts/jquery/backgroundPositionExplicative
F
20

The version above doesn't work with jQuery 1.6.1. This one does.

(function($) {
if(!document.defaultView || !document.defaultView.getComputedStyle){
    var oldCurCSS = jQuery.curCSS;
    jQuery.curCSS = function(elem, name, force){
        if(name === 'background-position'){
            name = 'backgroundPosition';
        }
        if(name !== 'backgroundPosition' || !elem.currentStyle || elem.currentStyle[ name ]){
            return oldCurCSS.apply(this, arguments);
        }
        var style = elem.style;
        if ( !force && style && style[ name ] ){
            return style[ name ];
        }
        return oldCurCSS(elem, 'backgroundPositionX', force) +' '+ oldCurCSS(elem, 'backgroundPositionY', force);
    };
}

var oldAnim = $.fn.animate;
$.fn.animate = function(prop){
    if('background-position' in prop){
        prop.backgroundPosition = prop['background-position'];
        delete prop['background-position'];
    }
    if('backgroundPosition' in prop){
        prop.backgroundPosition = '('+ prop.backgroundPosition + ')';
    }
    return oldAnim.apply(this, arguments);
};

function toArray(strg){
    strg = strg.replace(/left|top/g,'0px');
    strg = strg.replace(/center/g,'50%');
    strg = strg.replace(/right|bottom/g,'100%');
    strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2");
    var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
    return [parseFloat(res[1],10),res[2],parseFloat(res[3],10),res[4]];
}

$.fx.step.backgroundPosition = function(fx) {
    if (!fx.bgPosReady) {
        var start = $.curCSS(fx.elem,'backgroundPosition');

        if(!start){//FF2 no inline-style fallback
            start = '0px 0px';
        }

        start = toArray(start);

        fx.start = [start[0],start[2]];

        var end = toArray(fx.end);
        fx.end = [end[0],end[2]];

        fx.unit = [end[1],end[3]];
        fx.bgPosReady = true;
    }

    var nowPosX = [];
    nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
    nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
    fx.elem.style.backgroundPosition = nowPosX[0]+' '+nowPosX[1];
};
})(jQuery);
Faris answered 8/6, 2011 at 14:9 Comment(2)
for those who want to know more abour curCSS: struckthrough.krystophv.org/tag/curcssSignalment
$.curCSS() was deprecated in jQuery 1.3 and removed in jQuery 1.8Sackman
T
11

The code posted by magiconair no longer works with jQuery 1.8. Here is a patched version that doesn't use the depreciated $.curCSS() method.

(function($) {
if(!document.defaultView || !document.defaultView.getComputedStyle){
    var oldCSS = jQuery.css;
    jQuery.css = function(elem, name, force){
        if(name === 'background-position'){
            name = 'backgroundPosition';
        }
        if(name !== 'backgroundPosition' || !elem.currentStyle || elem.currentStyle[ name ]){
            return oldCSS.apply(this, arguments);
        }
        var style = elem.style;
        if ( !force && style && style[ name ] ){
            return style[ name ];
        }
        return oldCSS(elem, 'backgroundPositionX', force) +' '+ oldCSS(elem, 'backgroundPositionY', force);
    };
}

var oldAnim = $.fn.animate;
$.fn.animate = function(prop){
    if('background-position' in prop){
        prop.backgroundPosition = prop['background-position'];
        delete prop['background-position'];
    }
    if('backgroundPosition' in prop){
        prop.backgroundPosition = '('+ prop.backgroundPosition + ')';
    }
    return oldAnim.apply(this, arguments);
};

function toArray(strg){
    strg = strg.replace(/left|top/g,'0px');
    strg = strg.replace(/right|bottom/g,'100%');
    strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2");
    var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
    return [parseFloat(res[1],10),res[2],parseFloat(res[3],10),res[4]];
}

$.fx.step.backgroundPosition = function(fx) {
    if (!fx.bgPosReady) {
        var start = $.css(fx.elem,'backgroundPosition');

        if(!start){//FF2 no inline-style fallback
            start = '0px 0px';
        }

        start = toArray(start);

        fx.start = [start[0],start[2]];

        var end = toArray(fx.end);
        fx.end = [end[0],end[2]];

        fx.unit = [end[1],end[3]];
        fx.bgPosReady = true;
    }

    var nowPosX = [];
    nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
    nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
    fx.elem.style.backgroundPosition = nowPosX[0]+' '+nowPosX[1];
};
})(jQuery);
Trona answered 19/9, 2012 at 10:59 Comment(0)
R
5

This code works well for me with jQuery 1.8.1 and Firefox, i had some issues getting Prydie's example to work:

http://nelsonwells.net/2012/08/using-bgpos-js-with-jquery-18/

/**
 * @author Alexander Farkas
 * v. 1.02
 *
 * Edited by Nelson Wells for jQuery 1.8 compatibility
 */
(function($) {
    $.extend($.fx.step,{
        backgroundPosition: function(fx) {
            if (fx.pos === 0 && typeof fx.end == 'string') {
                var start = $.css(fx.elem,'backgroundPosition');
                start = toArray(start);
                fx.start = [start[0],start[2]];
                var end = toArray(fx.end);
                fx.end = [end[0],end[2]];
                fx.unit = [end[1],end[3]];
            }
            var nowPosX = [];
            nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
            nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
            fx.elem.style.backgroundPosition = nowPosX[0]+' '+nowPosX[1];

            function toArray(strg){
                strg = strg.replace(/left|top/g,'0px');
                strg = strg.replace(/right|bottom/g,'100%');
                strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2");
                var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
                return [parseFloat(res[1],10),res[2],parseFloat(res[3],10),res[4]];
            }
        }
    });
})(jQuery);
Rothschild answered 26/9, 2012 at 9:36 Comment(0)
R
2

here try this for background animation

(function($) {
    if (!document.defaultView || !document.defaultView.getComputedStyle) {
        var oldCurCSS = jQuery.curCSS;
        jQuery.curCSS = function(elem, name, force) {
            if (name === 'background-position') {
                name = 'backgroundPosition';
            }
            if (name !== 'backgroundPosition' || !elem.currentStyle || elem.currentStyle[name]) {
                return oldCurCSS.apply(this, arguments);
            }
            var style = elem.style;
            if (!force && style && style[name]) {
                return style[name];
            }
            return oldCurCSS(elem, 'backgroundPositionX', force) + ' ' + oldCurCSS(elem, 'backgroundPositionY', force);
        };
    }
    var oldAnim = $.fn.animate;
    $.fn.animate = function(prop) {
        if ('background-position' in prop) {
            prop.backgroundPosition = prop['background-position'];
            delete prop['background-position'];
        }
        if ('backgroundPosition' in prop) {
            prop.backgroundPosition = '(' + prop.backgroundPosition;
        }
        return oldAnim.apply(this, arguments);
    };

    function toArray(strg) {
        strg = strg.replace(/left|top/g, '0px');
        strg = strg.replace(/right|bottom/g, '100%');
        strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g, "$1px$2");
        var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
        return [parseFloat(res[1], 10), res[2], parseFloat(res[3], 10), res[4]];
    }
    $.fx.step.backgroundPosition = function(fx) {
        if (!fx.bgPosReady) {
            var start = $.curCSS(fx.elem, 'backgroundPosition');

            if (!start) { //FF2 no inline-style fallback
                start = '0px 0px';
            }
            start = toArray(start);
            fx.start = [start[0], start[2]];
            var end = toArray(fx.options.curAnim.backgroundPosition);
            fx.end = [end[0], end[2]];
            fx.unit = [end[1], end[3]];
            fx.bgPosReady = true;
        }
        //return;
        var nowPosX = [];
        nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
        nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
        fx.elem.style.backgroundPosition = nowPosX[0] + ' ' + nowPosX[1];
    };
})(jQuery);

Call to it like this,

$(this).animate({
    backgroundPosition: '0 0'
})
Rifleman answered 1/4, 2011 at 21:11 Comment(5)
did you add the last few bits of code })(jQuery); to the end of the plugin? also make sure whatever it is you want to animate is a background image.Rifleman
I forgot the extra bits, and it worked :) I had to add a little to my left and right functions to retrieve the new current position, but it works. Its still not quite as smooth as the webkit animate but it got the job done. thank you very much!Radiometeorograph
No worries, glad to be of help.Rifleman
please in future check your code formatting when you post. Just pasting it screws up the indentation, particularly when the source code file uses tabs. I have fixed it for you this time :-) (and the syntax error).Tereasaterebene
Here is the link to the plugin (referenced in the answer): protofunc.com/scripts/jquery/backgroundPositionExplicative
C
0

Here an Update of the solution from Prydie (for jQuery 1.80 and higher).

It handle the case of "+=" and "-=" values :

$.fx.step.backgroundPosition = function(fx) {
if (!fx.bgPosReady) {
    var start = toArray($.css(fx.elem,'backgroundPosition') || '0px 0px');
    fx.start = [start[0],start[2]];
    var add = [
        (ret = /([+-])=/.exec( fx.end.split(' ')[0] )) && ret[1],
        (ret = /([+-])=/.exec( fx.end.split(' ')[1] )) && ret[1]
    ];
    var end = toArray(fx.end.replace(/([+-])=/g,''));
    fx.end = [
        add[0]?eval(start[0]+add[0]+end[0]):end[0],
        add[1]?eval(start[1]+add[1]+end[2]):end[2]
    ];
    fx.unit = [end[1],end[3]];
    fx.bgPosReady = true;
}
fx.now = [
    ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0],
    ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1]
];
fx.elem.style.backgroundPosition = fx.now[0]+' '+fx.now[1];
};

Note: you must use the others methods from the solution of Prydie to make it works.

sample of use :

$(this).animate({backgroundPosition:'bottom -=100'},5000,'linear',function(){});
Capeskin answered 18/7, 2013 at 10:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.