简体   繁体   中英

Why is my custom pseudo-animation out of sync with jQuery's native animate function?

So it turns out that while you can animate the background-color of an element via jQuery UI, you cannot do the same for elements which use a background: linear-gradient() function as it is rendered as an image - you can however set linear gradients using jQuery's .css() method.

Therefore a simple solution to this problem is to create a pseudo animation which rapidly sets the linear-gradient via the css method over 10-30 milliseconds each for a particular duration. With this, you can actually create linear gradient animations. Here's an example .

I have done exactly this, but I'm encountering a problem. At the same time as I'm animating my linear gradients, I'm also animating another background-color with the same start and end values via the native jQuery animate() method, and these animations are not executing at the same time, despite specifying the duration as equal for both.

The linear gradient animation is being started and completed visibly after the native jQuery animation, despite actually calling it slightly earlier in my code (about 4 lines).

// Call to custom linear gradient animation
animateGradient(RGBstartColor, RGBstopColor, 300);

...

// Native jQuery animation
$('#stage').animate({ backgroundColor: RGBstopColor }, 300, 'linear');

I wondered if it was an easing problem disguised as a time problem, but even when specifying the easing on the jQuery anim, it's still visible.

Here's my code for animateGradient() :

    animateGradient = function(startString, stopString, duration) {
        // Convert an rgb() string to an array: [r, g, b]
        RGBStringToArray = function(string) {
            return string.substring(4, string.length-1).replace(/ /g, '').split(',')
        }

        // The looping function where the magic happens
        animationLoop = function() {

            diff = [parseInt(start[0]) + (diffStep[0] * i), parseInt(start[1]) + (diffStep[1] * i), parseInt(start[2]) + (diffStep[2] * i)];

            var diffString = 'rgb(' + Math.round(diff[0]) + ',' + Math.round(diff[1]) + ',' + Math.round(diff[2]) + ')';

            $('#serratedtop').css({ 
                background: 
                'linear-gradient(-45deg, ' + diffString + ' 12px, transparent 0), linear-gradient(45deg, ' + diffString + ' 12px, transparent 0)' 
            });

            setTimeout(function() {
                if (i <= iCount) {
                    animationLoop();
                }
                i++;
            }, 30);
        }

        var start = RGBStringToArray(startString);
        var stop = RGBStringToArray(stopString);

        var diff = [stop[0] - start[0], stop[1] - start[1], stop[2] - start[2]];

        var i = 0;
        var iCount = parseInt(duration / 30); // 30 milliseconds should be enough to render a high enough framerate (~ 33fps). 
        var diffStep = [diff[0] / iCount, diff[1] / iCount, diff[2] / iCount];

        // Call the magic 
        animationLoop();
    }

Yet, when this function runs, it works, but it's visibly out of sync with the native jQuery anim. Any ideas why this is?

JSFiddle demonstrating the problem

To avoid the problem of different systems calculating the changes differently (or at different speeds), you can simplify the whole thing by using the step callback of animate, then "stealing" the value from the animating colour:

$('#stage').animate({
    backgroundColor: 'rgb(230,250,250)'
}, {
    duration: 1000,
    step: function () {
        var col = $('#stage').css('backgroundColor');
        $('#serratedtop').css({
            background:
            'linear-gradient(-45deg, ' + col + ' 12px, transparent 0), linear-gradient(45deg, ' + col + ' 12px, transparent 0)'
        });
    }
});

This way they will always be in sync as the steps are called back each time the value changes.

JSFiddle: http://jsfiddle.net/bjgzLkuf/5/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM