gpt4 book ai didi

flutter - 如何通过路径制作圆的动画? flutter

转载 作者:太空宇宙 更新时间:2023-11-04 09:15:07 29 4
gpt4 key购买 nike

首先,非常感谢您观看我的问题;我想通过 startClickPosition&endPosition 制作一条贝塞尔路径,并用它画一个圆圈。在代码中,我使用 _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();

}

非常感谢。 :)

整个代码:

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

}

最佳答案

class Circle extends StatefulWidget {
@override
_CircleState createState() => _CircleState();
}

class _CircleState extends State<Circle> with SingleTickerProviderStateMixin {
double _fraction = 0.0;
Animation<double> _animation;
AnimationController _controller;
@override
void initState() {
super.initState();

_controller =
AnimationController(duration: Duration(milliseconds: 300), vsync: this);

_animation = Tween(begin: 0.0, end: 1.0).animate(_controller)
..addListener(() {
setState(() {
_fraction = _animation.value;
});
});

_controller.forward();
}

@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: AspectRatio(
aspectRatio: 1.0,
child: Padding(
padding: const EdgeInsets.all(24.0),
child: CustomPaint(
painter: CirclePainter(fraction: _fraction),
),
),
),
),
);
}

@override
void dispose() {
_controller.dispose();
super.dispose();
}
}

class CirclePainter extends CustomPainter {
final double fraction;
var _circlePaint;

CirclePainter({this.fraction}) {
_circlePaint = Paint()
..color = circleColor
..style = PaintingStyle.stroke
..strokeWidth = 12.0
..strokeCap = StrokeCap.round;
}

@override
void paint(Canvas canvas, Size size) {
var rect = Offset(0.0, 0.0) & size;

canvas.drawArc(rect, -pi / 2, pi * 2 * fraction, false, _circlePaint);
}

@override
bool shouldRepaint(CirclePainter oldDelegate) {
return oldDelegate.fraction != fraction;
}
}

关于flutter - 如何通过路径制作圆的动画? flutter ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59125485/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com