Fabric.js animate object/image

笑着哭i 提交于 2019-12-06 07:53:10

The problem you're facing is that the animation functions don't block each other, so when your fireAnimation() function runs, it's starting both animations at the same time, and each animation change is applied on each frame, which means that both animations occur simultaneously.

One way to resolve this would be to chain the animation calls using the animation .onComplete event. Doing this might lock you into a bit of a hellish situation if you need to update the order of your animations.

Given that you proposed perhaps having a list of animations to apply one after another you may be served better by creating a generic function that applies animations based on an input list of animation parameters like this (explanation in comments in code):

function startAnimationQueue(animationQueue){
    // queues up the animations for the shape

    var runningDuration = 0; // variable that adds up the animationQueue durations
    for (var i=0; i<animationQueue.length; i++){
        var animationDefinition = animationQueue[i];

        // Create a closure around the animationDefiniton so that each setTimeout gets sequential animationDefinition inputs
        var fn = (function(animationDefinition){
            return function(){
                triangle.animate('left', animationDefinition.left, {duration: animationDefinition.duration, onChange:canvas.renderAll.bind(canvas)})
                triangle.animate('top', animationDefinition.top, {duration: animationDefinition.duration, onChange:canvas.renderAll.bind(canvas)})
                // Note: you can animate additional attributes here if you want, just add additional attributes to the objects in
                //   the animationQueue list. You could also have one of those inputs be the object to be animated in case you want
                //   to animate multiple objects using the same queue.
                };
            })

        // Create the timeout that will apply the transformations sequentially
        // If you want you could set the window.setTimeout to a variable that you could destroy if you need 
        // to interrupt the animation queue after you create it (but before it finishes)
        window.setTimeout(fn(animationDefinition), runningDuration);

        // set the next setTimeout duration to be .duration later than the previous one
        // this makes the second animation fire after the first one completes
        runningDuration += animationDefinition.duration;
    }
}

document.onreadystatechange = function () {
  if (document.readyState == "complete") {

    // I put the canvas init stuff in here because of (I think) a failed race condition or something that caused
    // your original method to fail in Chrome
    window.canvas = new fabric.Canvas('scene');

    window.triangle = new fabric.Triangle({
        width: 30
      , height: 30
      , fill: 'red'
      , left: 30
      , top: 0
    });

    window.canvas.add(window.triangle);
    window.canvas.renderAll();

    // Create a list of animations to apply
    var animationQueue = [
        {"left": "+=0", "top": "+=100", "duration": 1000},
        {"left": "+=55", "top": "+=0", "duration": 2000}

    ]

    // Apply the animations in sequence using window.setTimeout
    startAnimationQueue(animationQueue);
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!