2014-01-24 89 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()',您可以開始一系列事件,這些事件會沿着不同的(虛擬並行)路徑,然後是主程序流。 –