Fabric.js动画对象/形象 [英] Fabric.js animate object/image

查看:1825
本文介绍了Fabric.js动画对象/形象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,这是code的香港专业教育学院一直使用。它的动作从A的目的是B.我所试图做的是有多个点,它会移动。因此,从起始位置A - > B,再从B - > C等。也许有一些变量,将包含坐标集,这将得到送入一些动画的功能作为参数。但任何事情我想只导致在执行的最后一个命令,所以会从A直接转向 - > C,无视B.任何意见/ AP演示preciated

的JavaScript

  VAR帆布=新fabric.Canvas(场景,{的backgroundColor:'绿色'});VAR三角=新fabric.Triangle({
    宽度:30
  ,高度:30
  填写:红
  左:30
  ,顶:0
});canvas.add(三角形);功能animateTop(){
  triangle.animate('顶','+ = 55',{
    时间:1000,
    的onChange:canvas.renderAll.bind(画布)
  });
}功能animateLeft(){
  triangle.animate('左','+ = 100',{
    时间:1000,
    的onChange:canvas.renderAll.bind(画布)
  });
}功能fireAnimation(){
  animateTop();
  animateLeft();
}document.onreadystatechange =功能(){
  如果(document.readyState ==完成){
    fireAnimation();
  }
}

HTML

 <!DOCTYPE HTML>
< HTML和GT;
< HEAD>
  <间的charset =UTF-8>
  <标题> JS斌< /标题>
  &所述; SCRIPT SRC =htt​​p://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js>&下; /脚本>
< /头>
<身体GT;
  <帆布ID =场景WIDTH =400HEIGHT =400/>
< /身体GT;
< / HTML>


解决方案

您所面临的问题是,动画功能不会阻止对方,所以当你的 fireAnimation()功能运行时,它开始在同一时间既动画和每个动画更改应用于每一帧,这意味着同时出现两个动画上。

要解决这将是连锁使用动画 .onComplete 事件动画调用一个方法。这样做的可能的锁你进入一个有点地狱般的情况下,如果你需要更新你的动画的顺序。

既然你提出了也许有动画列表通过创建一个采用基于动画参数,如在code注释本(解释的输入列表上的动画泛型函数陆续申请一个你可能会担任好):

 函数startAnimationQueue(animationQueue){
    //排队的形状动画    变种runningDuration = 0; //变量,增加了animationQueue持续时间
    对于(VAR I = 0; I< animationQueue.length;我++){
        VAR animationDefinition = animationQueue [I]        //创建围绕animationDefiniton封闭,使每个setTimeout的顺序获得输入animationDefinition
        VAR FN =(函数(animationDefinition){
            返回功能(){
                triangle.animate(左,animationDefinition.left,{时间:animationDefinition.duration,的onChange:canvas.renderAll.bind(画布)})
                triangle.animate('顶',animationDefinition.top,{时间:animationDefinition.duration,的onChange:canvas.renderAll.bind(画布)})
                //注意:您可以在这里动画的附加属性,如果你想,只是添加附加属性的对象
                //将animationQueue列表。你也可以有这些输入中的一个是对象的情况下,进行动画要
                //使用同一队列动画多个对象。
                };
            })        //创建一个将应用变换顺序超时
        //如果你愿意,你可以在设置window.setTimeout如果你需要,你可以摧毁一个变量
        //中断动画队列创建(但它完成之前),
        window.setTimeout(FN(animationDefinition),runningDuration);        //设置下的setTimeout持续时间也可以大于previous个随后.duration
        //这使得第二个动画火第一个完成后
        runningDuration + = animationDefinition.duration;
    }
}document.onreadystatechange =功能(){
  如果(document.readyState ==完成){    //我把画布上的init东西在这里,因为(我认为)导致失败的竞争条件或某事
    //你原来的方法在Chrome中失败
    window.canvas =新fabric.Canvas(场景);    window.triangle =新fabric.Triangle({
        宽度:30
      ,高度:30
      填写:红
      左:30
      ,顶:0
    });    window.canvas.add(window.triangle);
    window.canvas.renderAll();    //创建动画的列表,以应用
    VAR animationQueue = [
        {左:+ = 0,顶:+ = 100,时间:1000},
        {左:+ = 55,顶:+ = 0,时间:2000}    ]    //使用window.setTimeout应用动画序列
    startAnimationQueue(animationQueue);
  }
}

Hello everyone this is code that ive been working with. It moves an object from A to B. What i am trying to do is have multiple points to which it would move. So from starting position A -> B, then from B -> C and so on. Maybe have some variable which would contain sets of coordinates, which would get fed into some animate function as parameters. But anything i tried resulted only in executing the last command, so it would move straight from A -> C, ignoring B. Any advice/demo appreciated.

Javascript

var canvas = new fabric.Canvas('scene', { backgroundColor: 'green'});

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

canvas.add(triangle);

function animateTop() {
  triangle.animate('top', '+=55', {
    duration: 1000,
    onChange: canvas.renderAll.bind(canvas)
  });
}

function animateLeft() {
  triangle.animate('left', '+=100', {
    duration: 1000,
    onChange: canvas.renderAll.bind(canvas)
  });
}

function fireAnimation() {
  animateTop();
  animateLeft();
}

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

HTML

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js"></script>
</head>
<body>
  <canvas id="scene" width="400" height="400" />
</body>
</html>

解决方案

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);
  }
}

这篇关于Fabric.js动画对象/形象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆