gpt4 book ai didi

animation - 如何链接多个 Controller /动画?

转载 作者:IT王子 更新时间:2023-10-29 06:35:57 27 4
gpt4 key购买 nike

问题

我在 flutter 中制作了一个椭圆加载动画,但必须在所有三个不同的 Controller 上使用 Timer。 (参见下面的示例...)

是否有任何小部件可以帮助链接三个不同的动画?

  • 我尝试对多条曲线使用 Interval 小部件,但它没有提供平滑的过渡。例如Interval(0.0, 0.3), Interval(0.3, 0.6), Interval(0.6, 0.9) 动画曲线。

示例

示例代码

import 'package:flutter/material.dart';
import 'package:flutter/animation.dart';
import 'dart:async';

void main() {
runApp(
new MaterialApp(
home: new Scaffold(
body: new CircleLoader(),
)
)
);
}

class CircleLoader extends StatefulWidget {
@override
_CircleLoaderState createState() => new _CircleLoaderState();
}

class _CircleLoaderState extends State<CircleLoader>
with TickerProviderStateMixin {
Animation<double> animation;
Animation<double> animation2;
Animation<double> animation3;
AnimationController controller;
AnimationController controller2;
AnimationController controller3;
int duration = 1000;
Widget circle = new Container(
height: 10.0,
width: 10.0,
decoration: new BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey[300],
),
);

@override
initState() {
super.initState();
controller = new AnimationController(
duration: new Duration(milliseconds: duration), vsync: this);
controller2 = new AnimationController(
duration: new Duration(milliseconds: duration), vsync: this);
controller3 = new AnimationController(
duration: new Duration(milliseconds: duration), vsync: this);

final CurvedAnimation curve =
new CurvedAnimation(parent: controller, curve: Curves.easeInOut);
final CurvedAnimation curve2 =
new CurvedAnimation(parent: controller2, curve: Curves.easeInOut);
final CurvedAnimation curve3 =
new CurvedAnimation(parent: controller3, curve: Curves.easeInOut);

animation = new Tween(begin: 0.85, end: 1.5).animate(curve)
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
} else if (status == AnimationStatus.dismissed) {
controller.forward();
}
});
animation2 = new Tween(begin: 0.85, end: 1.5).animate(curve2)
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller2.reverse();
} else if (status == AnimationStatus.dismissed) {
controller2.forward();
}
});
animation3 = new Tween(begin: 0.85, end: 1.5).animate(curve3)
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller3.reverse();
} else if (status == AnimationStatus.dismissed) {
controller3.forward();
}
});

controller.forward();
new Timer(const Duration(milliseconds: 300), () {
controller2.forward();
});
new Timer(const Duration(milliseconds: 600), () {
controller3.forward();
});
}

@override
Widget build(BuildContext context) {
return new Center(
child: new Container(
width: 100.0,
height: 50.0,
color: Colors.grey,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new ScaleTransition(scale: animation, child: circle),
new ScaleTransition(scale: animation2, child: circle),
new ScaleTransition(scale: animation3, child: circle),
],
),
),
);
}
}

最佳答案

诀窍在于您可以创建自己的补间。

简而言之,你想要的是一条平滑的曲线,从 0 到 1,然后从 1 到 0 平滑。您可以将其同化为 (sin(t * 2 * PI) + 1)/2,其中 0 <= t <= 1然后为每个 cicles 延迟该曲线。

class TestTween extends Tween<double> {
final double delay;

TestTween({double begin, double end, this.delay}) : super(begin: begin, end: end);

@override
double lerp(double t) {
return super.lerp((sin((t - delay) * 2 * PI) + 1) / 2);
}
}

允许做什么

_controller = new AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
)..repeat();

不必添加动画监听器并反转动画。

最终结果是

class CircleLoader extends StatefulWidget {
@override
_CircleLoaderState createState() => new _CircleLoaderState();
}

class _CircleLoaderState extends State<CircleLoader>
with SingleTickerProviderStateMixin {
AnimationController _controller;

@override
initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
)..repeat();
}

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

buildCircle(double delay) {
return new ScaleTransition(
scale: new TestTween(begin: .85, end: 1.5, delay: delay)
.animate(_controller),
child: new Container(
height: 10.0,
width: 10.0,
decoration: new BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey[300],
),
),
);
}

@override
Widget build(BuildContext context) {
return new Center(
child: new Container(
width: 100.0,
height: 50.0,
color: Colors.grey,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
buildCircle(.0),
buildCircle(.2),
buildCircle(.4),
],
),
),
);
}
}

class TestTween extends Tween<double> {
final double delay;

TestTween({double begin, double end, this.delay})
: super(begin: begin, end: end);

@override
double lerp(double t) {
return super.lerp((sin((t - delay) * 2 * PI) + 1) / 2);
}
}

关于animation - 如何链接多个 Controller /动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46720549/

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