2014-01-24 83 views
1

我试图编写一些动画,但我很难理解期货是如何在飞镖上工作的。飞镖期货(CSS动画)

主要问题是动画本身是一个异步过程,如果我试图链接几个点,它们堆积起来,精灵直接移动到最后一个点。我看过的所有例子都是在函数返回一个值的时候工作的,但是在处理动画的时候并不是这样。

我希望能够检测到动画已完成,以触发下一个动作,但到目前为止我还没有真正成功。

这里是我的代码:

class MovingThing { 
    String   name; 
    DivElement  sprite = new DivElement(); 

    MovingThing(this.name){ 
    sprite.id = name; 
    sprite.text = name; 
    sprite.style..width  = "30px" 
       ..height  = "30px" 
       ..border  = "1px solid black" 
       ..position = "absolute" 
       ..transition = "all 2000ms ease-in-out"; 
    querySelector("body").children.add(sprite); 
    } 

    Future move(Point p) { 
    sprite.style..top = p.y.toString() + "px" 
       ..left = p.x.toString() + "px"; 

    return Future.wait([sprite.onTransitionEnd.first]); 
    } 
} 

main() { 
    List<Point> points = [ 
    new Point(20, 20) 
    , new Point(200, 20) 
    , new Point(20, 200) 
    , new Point(100, 100) 
    ]; 

    MovingThing mt = new MovingThing("MT"); 
    Future.forEach(points, (Point p) => mt.move(p)); 
} 
+0

新增示例 –

回答

1

我几件事情

  • Future.wait()onTransitionEnd被触发并立即返回,没有。
  • Future.wait用于等待多于一个Future因此List参数。 你可以用return sprite.onTransitionEnd.first;代替这一行。
  • 您应该将您的操作添加到mt.move(p).then((v) => doThisAfterTransitionEnd);
  • 我试过了您的代码,并且onTransitionEnd未被解雇。

不完美,但你应该展示如何开始。

new Future()仅用于给事件循环时间做它的工作而不是链接动画。 动画的下一次迭代从onSubscriptionEnd事件开始。

import 'dart:html'; 
import 'dart:async'; 

class MovingThing { 
    String   name; 
    DivElement  sprite = new DivElement(); 
    List<Point> points; 

    MovingThing(this.name){ 
    sprite.id = name; 
    sprite.text = name; 
    sprite.style 
     ..top  = "30px" 
     ..left  = "30px" 
     ..width  = "30px" 
     ..height  = "30px" 
     ..border  = "1px solid black" 
     ..position = "absolute" 
     ..transition = "all 1.5s ease-in-out"; 

    document.body.children.add(sprite); 
    } 

    void move(int idx) { 

    if(idx >= points.length) { 
     return; 
    } else { 
     var f = sprite.onTransitionEnd.first.then((TransitionEvent e) { 
     new Future(() { 
     print('transitionEnd$idx'); 
     move(idx + 1); 
     }); 
     }); 

     sprite.style 
     ..top = '${points[idx].x}px' 
     ..left = '${points[idx].y}px'; 
     sprite.text = '$idx'; 

    } 
    } 
} 

main() { 
    List<Point> points = [ 
    new Point(120, 120) 
    , new Point(200, 20) 
    , new Point(20, 200) 
    , new Point(100, 100) 
    , new Point(150, 30) 
    , new Point(30, 150) 
    , new Point(20, 20) 
    , new Point(120, 120) 
    ]; 

    MovingThing mt = new MovingThing("MT"); 
    mt.points = points; 
    new Future(() => mt.move(0)); 
} 
+0

非常感谢!您的解决方案非常完美,我学会了使用期货的一种方法。另一方面,我仍然试图理解如何创建一个从'onTransitionEnd'事件返回'Future'的方法。 – Daniel

+0

这不会有太大的区别。 'then()'(在'first'后面)是未来调用的方法。你也可以'返回sprite.onTransitionEnd.first;'然后接收者调用他从'move'得到的返回值。这只会改变代码的结构,但不会改变语义(可能会使代码对于这种用例更加复杂)。通过'new Future()',您可以开始一系列事件,这些事件会沿着不同的(虚拟并行)路径,然后是主程序流。 –