Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
457 views
in Technique[技术] by (71.8m points)

java - 如何通过路径为圆设置动画? 扑(How to animate a circle by a path ? Flutter)

first,thks a lot for watch my question;

(首先,请多多注意我的问题;)

i want to make a Bezier path by startClickPosition&endPosition , and draw a circle go with it.

(我想通过startClickPosition&endPosition绘制Bezier路径,并绘制一个圆圈。)

among the code,i used _path.computeMetrics(),and get a PathMetrics,then i use pms.elementAt(0) to get the PathMetric,but i found a error in there is pms.length is 0. there is my Code:

(在代码中,我使用_path.computeMetrics()并获取PathMetrics,然后使用pms.elementAt(0)来获取PathMetric,但是我发现pms.length为0时出错。我的代码是:)

  Path getPath(){
    Path path = Path();
    path.moveTo(widget.startOffset.dx, widget.startOffset.dy);
    // i'm ensure this 4 var got value and is right value,below this line.
    double startX = widget.endOffset.dx / 2; 
    double startY = widget.startOffset.dy;
    double endX = widget.endOffset.dx;
    double endY = widget.endOffset.dy;
    path.quadraticBezierTo(startX,startY,endX ,endY);
    return path;
  }

    startAnimation(){
    _path  = getPath();
    if(_path == null) print("path is null");
    PathMetrics pms = _path.computeMetrics(forceClosed: false);
    // here pms.length is always 0;
    PathMetric pm = pms.elementAt(0); 
    double pathLen = pm.length;

    _animation = Tween(begin: 0.0,end: pathLen).animate(_controller)
          ..addListener((){
            setState(() {
              _fraction = _animation.value;
              print("fraction  _____ $_fraction");
            });
          })
          ..addStatusListener((status){
            if(status == AnimationStatus.completed){
              _controller.stop();
            }
          });
  _controller.forward();

  }

thks a lot.

(非常高兴。)

:)

(:))

the whole code :

(整个代码:)

class ParabolaAnimation extends StatefulWidget{

  Size screenSize;
  Offset startOffset;
  Offset endOffset;

  ParabolaAnimation(this.startOffset,this.endOffset,this.screenSize);

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return ParabolaAnimationState();
  }

}

class ParabolaAnimationState extends State<ParabolaAnimation> with SingleTickerProviderStateMixin {

  AnimationController _controller;
  Animation _animation;
  double _fraction = 0.0;
  int _seconds = 3;
  Path _path;

  GlobalKey _key = GlobalKey();

  @override
  void initState() {
    // TODO: implement initState
    _controller = AnimationController(vsync: this,duration: Duration(seconds: _seconds));
    super.initState();


  }

  @override
  void dispose() {
    // TODO: implement dispose
    _controller.dispose();
    super.dispose();

  }


  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    WidgetsBinding.instance.addPostFrameCallback((_){
      startAnimation();
    });
    return CustomPaint(
      painter: PathPainter(_path, _fraction),
//      child: Container(
//        width: widget.screenSize.width,
//        height: widget.screenSize.height,
//      ),
    );
  }

  startAnimation(){
    _path  = getPath();
    print("path   ${_path.toString()}  ___ ");
    if(_path == null) print("path is null");
    PathMetrics pms = _path.computeMetrics(forceClosed: false);
    if(pms.length == 0) return;
    int plen = pms.length;
    //only one path
    PathMetric pm = pms.elementAt(0);
    double pathLen = pm.length;

    print("path len : $pathLen");

    _animation = Tween(begin: 0.0,end: pathLen).animate(_controller)
          ..addListener((){
            setState(() {
              _fraction = _animation.value;
              print("fraction  _____ $_fraction");
            });
          })
          ..addStatusListener((status){
            if(status == AnimationStatus.completed){
              _controller.stop();
            }
          });
  _controller.forward();

  }

  Path getPath(){
    print("start offset ${widget.startOffset.toString()}");
    print("end offset ${widget.endOffset.toString()}");
    Path path = Path();
    path.moveTo(widget.startOffset.dx, widget.startOffset.dy);
    double startX = widget.endOffset.dx / 2;
    double startY = widget.startOffset.dy;
    double endX = widget.endOffset.dx;
    double endY = widget.endOffset.dy;
    path.quadraticBezierTo(startX,startY,endX ,endY);
    return path;
  }


}


class PathPainter extends CustomPainter{

  double fraction;
  Path _path;
  List<Offset> _points = List();

  PathPainter(this._path,this.fraction);

  Paint circleP = Paint()
      ..color = Colors.orange
      ..style = PaintingStyle.fill;

  @override
  void paint(Canvas canvas, Size size) {
    if(_path == null) return;
    print("fraction  paint _____ $fraction");
    PathMetrics pms = _path.computeMetrics();
    PathMetric pm = pms.elementAt(0);
    double pathLen = pm.length;
    double circleR = 10;

    Offset circleCenterOffset;
    Tangent t = pm.getTangentForOffset(fraction);// 圆心
    circleCenterOffset = t.position;
    print("circle center ${circleCenterOffset.dx} + ${circleCenterOffset.dy}");
    canvas.drawCircle(circleCenterOffset, circleR, circleP);

  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }

}
  ask by Joey translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...