为什么我的自定义伪动画与jQuery的原生动画功能不同步?

时间:2014-10-12 22:43:00

标签: javascript jquery css animation

事实证明,虽然你可以通过jQuery UI为元素的background-color设置动画,但是对于使用background: linear-gradient()函数的元素,你不能对它进行渲染,因为它被渲染为图像 - 你但是可以使用jQuery的.css()方法设置线性渐变。

因此,对此问题的一个简单解决方案是创建一个伪动画,该伪动画通过css方法在特定持续时间内快速设置线性渐变超过10-30毫秒。有了这个,您实际上可以创建线性渐变动画。 Here's an example

我已经做到了这一点,但我遇到了一个问题。在我为我的线性渐变设置动画的同时,我还通过原生jQuery animate()方法为具有相同开始值和结束值的另一种背景颜色设置动画,并且这些动画不会同时执行尽管指定两者的持续时间相等。

在本机jQuery动画之后,线性渐变动画正在以明显的方式启动和完成,尽管我的代码中早先实际上将它称为稍微(大约4行)。

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

...

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

我想知道这是一个伪装成时间问题的缓和问题,但即使在jQuery anim上指定缓动时,它仍然可见。

以下是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();
    }

然而,当这个函数运行时,它可以工作,但它明显与本机jQuery动画不同步。任何想法为什么会这样?

JSFiddle demonstrating the problem

1 个答案:

答案 0 :(得分:0)

为了避免不同系统以不同方式(或以不同速度)计算变化的问题,您可以使用动画的step回调来简化整个过程,然后从动画颜色“窃取”值:

$('#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)'
        });
    }
});

这样,它们将始终保持同步,因为每次值更改时都会回调步骤。

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