简体   繁体   English

JavaScript时间轴动画(setTimeout准确性问题)

[英]JavaScript timeline animation (setTimeout accuracy issues)

I began writing a simple animation class in JS, which utilizes Zepto.js animation capabilities but adds timeline-like capability to it. 我开始在JS中编写一个简单的动画类,该类利用Zepto.js动画功能,但向其添加了类似时间轴的功能。

The timeline itself is a simple array, that executes functions embedded in it when it's play() function is called: 时间轴本身是一个简单的数组,当调用play()函数时,该数组将执行嵌入其中的函数:

play : function(callback){

        for(var i=0; i<Animator.timeline.buffer.length; i++){

            Animator.timeline.buffer[i].animation();

        }

        if(callback){
            callback();
        }

    }

The setTimeout goes directly in the animation: setTimeout直接进入动画:

alpha : function(parameters, callback, delay){

    var target = parameters.target;
    var duration = parameters.duration;
    var easing = parameters.easing;
    var value = parameters.value;

    if(delay){
        setTimeout(function(){run();},delay*1000);
    } else {
        run();
    }

    function run(){
        $(target).anim({opacity:value},duration,easing);
        if(callback){
            callback();
        }
    }


}

So basically, the timeline just runs the setTimeout-ed functions which are placed in it's buffer array. 因此,基本上,时间轴只运行setTimeout-ed函数,这些函数位于其缓冲区数组中。

This approach works (almost) as intended with WebKit animations, but i've run into a few problems when doing image sequences (animations using setInterval which change the image's src). 这种方法(几乎)按预期与WebKit动画一起工作,但是在执行图像序列(使用setInterval的动画来更改图像的src)时遇到了一些问题。 As JS timers don't guarantee execution in their appointed time, sometimes animations run late, likely because of the embedded setInterval inside them. 由于JS计时器不能保证在指定的时间执行,因此有时动画会延迟播放,这可能是因为其中嵌入了setInterval。

Any ideas on how to solve this? 关于如何解决这个问题的任何想法? I am aware that embedding all animations as callbacks inside one another would solve much of the issues, but i don't really know how to do that from inside the timeline loop. 我知道,将所有动画作为回调相互嵌入可以解决很多问题,但是我真的不知道如何从时间轴循环中做到这一点。 Also, it would quickly become an unreadable mess of callbacks if I call all functions in a direct manner (without using the timeline). 另外,如果我以直接方式(不使用时间轴)调用所有函数,它将很快变成一团乱麻的回调。

For reference, the sequence function of my animator class: 作为参考,我的动画师类的序列函数是:

sequence : function(parameters, callback, delay){

    var target = parameters.target;
    var path = parameters.path;
    var baseName = parameters.baseName;
    var digits = parameters.digits;
    var extension = parameters.extension;
    var frames = parameters.frames;
    var loop = parameters.loop;

    if(parameters.interval){
        var _interval = parameters.interval
    } else {
        var _interval = 15;
    }


    var currentFrame = 0;
    var imageUrl = '';

    var fileName = baseName;

    for(var i=0; i<=digits; i++){
        fileName+='0';
    }

    if(delay){
        setTimeout(function(){runSequence();},delay*1000);
    } else {
        runSequence();
    }

    function runSequence(){

        var interval = setInterval(function(){

        if(currentFrame >= frames){
            currentFrame = 0;
            if(!loop) {
                clearInterval(interval);
                if(callback){
                    callback();
                }
            }
        } else {
            imageUrl = path+fileName.substring(0, fileName.length-currentFrame.toString().length)+currentFrame+"."+extension;
            $(target).attr('src',imageUrl);
            currentFrame++;
        }

    },_interval);

    }

}

Also, a sample of an animation created by using this class: 同样,使用此类创建的动画示例:

Animator.timeline.append(function(){
                Animator.alpha({'target':'#logo', 'value':1, 'duration':1, 'easing':'ease-out' });
            });

            Animator.timeline.append(function(){
                 Animator.sequence({'target':'#sequence', 'path':'images/sequences/index/', 'baseName':'nr1_', 'digits':3, 'extension':'png', 'frames':50},'',1.5);
            });

            Animator.timeline.append(function(){
                Animator.scale({'target':'#text', 'width':.5, 'height':.15, 'duration':1, 'easing':'ease-in-out'},'',3.2);
            });

             Animator.timeline.append(function(){
                Animator.alpha({'target':'#link', 'value':1, 'duration':1,'easing':'ease-out'},'',4.7);
            });

            Animator.timeline.play();

As an additional note, I was aiming to create something similar to GreenSock in AS3, if that helps. 另外,如果有帮助,我打算在AS3中创建类似于GreenSock的内容。

Thanks. 谢谢。

Accurate setInterval can be simulated by compensating for the time it takes to execute every iteration, maybe this gist I wrote can help you: 可以通过补偿执行每次迭代所需的时间来模拟准确的setInterval,也许我写的这个要旨可以帮助您:

https://gist.github.com/1185904 https://gist.github.com/1185904

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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