如何沿着从起点到终点的弯曲贝塞尔曲线路径为小部件设置动画?
How to animate widget along a curved bezier path from start point to end point?
如何沿着弯曲的贝塞尔曲线路径将小部件位置从一个位置移动到另一个位置?我想要的效果类似于 Hero 动画跨页面转换的工作方式 - 但我只想使用弯曲的贝塞尔曲线路径将小部件从一个位置移动到另一个位置,而不是像 Hero 动画那样跨页面工作。
我知道如何使用 AnimatedPostioned 小部件将小部件从一个位置移动到另一个位置,但我不知道如何执行此操作,所以路径是 curved/bezier。
其实我刚才也问过类似的问题:
但是现在我们有了 null-safety,所以我修改了那里的代码,并为您做了一个快速演示。
完整源代码:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: MyHome()));
}
class MyHome extends StatefulWidget {
@override
State<MyHome> createState() => _MyHomeState();
}
class _MyHomeState extends State<MyHome> {
Offset _end = Offset(300, 300);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Demo'),
),
body: Stack(
children: [
TweenAnimationBuilder(
tween: BezierTween(
begin: Offset(0, 0),
control: Offset(0, 300),
end: _end,
),
duration: Duration(seconds: 1),
builder: (BuildContext context, Offset value, Widget? child) {
return Positioned(
left: value.dx,
top: value.dy,
child: FlutterLogo(),
);
},
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_end = Offset.zero;
});
},
),
);
}
}
class BezierTween extends Tween<Offset> {
final Offset begin;
final Offset end;
final Offset control;
BezierTween({required this.begin, required this.end, required this.control})
: super(begin: begin, end: end);
@override
Offset lerp(double t) {
final t1 = 1 - t;
return begin * t1 * t1 + control * 2 * t1 * t + end * t * t;
}
}
如何沿着弯曲的贝塞尔曲线路径将小部件位置从一个位置移动到另一个位置?我想要的效果类似于 Hero 动画跨页面转换的工作方式 - 但我只想使用弯曲的贝塞尔曲线路径将小部件从一个位置移动到另一个位置,而不是像 Hero 动画那样跨页面工作。
我知道如何使用 AnimatedPostioned 小部件将小部件从一个位置移动到另一个位置,但我不知道如何执行此操作,所以路径是 curved/bezier。
其实我刚才也问过类似的问题:
但是现在我们有了 null-safety,所以我修改了那里的代码,并为您做了一个快速演示。
完整源代码:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: MyHome()));
}
class MyHome extends StatefulWidget {
@override
State<MyHome> createState() => _MyHomeState();
}
class _MyHomeState extends State<MyHome> {
Offset _end = Offset(300, 300);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Demo'),
),
body: Stack(
children: [
TweenAnimationBuilder(
tween: BezierTween(
begin: Offset(0, 0),
control: Offset(0, 300),
end: _end,
),
duration: Duration(seconds: 1),
builder: (BuildContext context, Offset value, Widget? child) {
return Positioned(
left: value.dx,
top: value.dy,
child: FlutterLogo(),
);
},
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_end = Offset.zero;
});
},
),
);
}
}
class BezierTween extends Tween<Offset> {
final Offset begin;
final Offset end;
final Offset control;
BezierTween({required this.begin, required this.end, required this.control})
: super(begin: begin, end: end);
@override
Offset lerp(double t) {
final t1 = 1 - t;
return begin * t1 * t1 + control * 2 * t1 * t + end * t * t;
}
}