1

我正在尝试编写一些动画,但我无法理解 Futures 在 Dart 上的工作方式。

主要问题是动画本身是一个异步过程,如果我尝试链接几个点,它们会堆积起来,精灵会直接移动到最后一个点。我见过的所有示例都在函数返回值时起作用,但在处理动画时并非如此。

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

这是我的代码:

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

1 回答 1

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)); 
}
于 2014-01-24T09:47:53.820 回答