AnimationController 重复曲线动画
AnimationController repeat with curve animation
如何制作重复但以曲线动画启动的 AnimatedController。
代码:
AnimationController :
var _animating = false;
AnimationController _rotationAnimationController;
Animation<double> _animation;
@override
void initState() {
super.initState();
_rotationAnimationController = AnimationController(
duration: Duration(milliseconds: 2000),
vsync: this,
);
_animation =
Tween<double>(begin: 0, end: 4 * pi ).animate(_rotationAnimationController)
..addListener(() {
setState(() {});
});
}
@override
void dispose() {
_rotationAnimationController.dispose();
super.dispose();
}
Button :
GestureDetector(
onTap: () {
Duration startStopTime = Duration(seconds: 3);
if(_animating) {
_rotationAnimationController.animateBack(1, duration: startStopTime, curve: Curves.easeOut);
setState(() {});
} else {
_rotationAnimationController.repeat() //This needs to start with a curve
}
setState(() {
_animating = !_animating;
});
},
child: [...]
),
如果你也可以做到 repeat 停止时,它会以曲线的方式进行,那也太棒了:)
感谢您的帮助:D
我最好理解你的问题,你想要 CurvedAnimation
对吗?这意味着您的动画将重复但遵循特定的曲线。所以这里是我能为您做的最好的事情:
像这样定义你的 AnimationController
:
Animation<double> _animation;
AnimationController _animationController;
@override
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: Duration(seconds: 2))
..addListener(() {
setState(() {});
});
final Animation curve =
CurvedAnimation(parent: _animationController, curve: Curves.easeOut);
_animation = Tween<double>(begin: 0, end: pi * 4).animate(curve);
}
你的 GestureDetector
是这样的:
GestureDetector(
onTap: () {
if (_animationController.isAnimating)
{
_animationController.animateBack(0,duration: Duration(seconds: 2), curve: Curves.easeIn);
}
else {
_animationController.repeat();
}
},
child: [...]
),
编辑 :
我用了一个TweenAnimationBuilder
来达到你想要的效果:
import 'package:flutter/material.dart';
import 'dart:math' as math;
class TweenAnimatedBuilderRotate extends StatefulWidget {
TweenAnimatedBuilderRotate({Key key}) : super(key: key);
@override
TweenAnimatedBuilderRotateState createState() =>
TweenAnimatedBuilderRotateState();
}
class TweenAnimatedBuilderRotateState
extends State<TweenAnimatedBuilderRotate> {
double _newAngle = 0;
Curve curveThatChanges = Curves.easeIn;
bool isAnimating = false;
int _millsecs = 2000;
void onCompletion() {
if (isAnimating) {
_newAngle += 4 * math.pi;
curveThatChanges = Curves.linear;
_millsecs = 1000;
setState(() {});
} else {
_newAngle = 0;
_millsecs = 2000;
}
}
void onContainerTap() {
if (isAnimating) {
isAnimating = false;
_newAngle = _newAngle;
setState(() {});
} else {
curveThatChanges = Curves.easeIn;
_newAngle += 4 * math.pi;
isAnimating = true;
setState(() {});
}
}
@override
Widget build(BuildContext context) {
return TweenAnimationBuilder(
tween: Tween<double>(begin: 0, end: _newAngle),
duration: Duration(milliseconds: _millsecs),
onEnd: () => onCompletion(),
curve: curveThatChanges,
builder: (
BuildContext ctx,
double angle,
Widget child,
) {
_newAngle = angle;
return Center(
child: Transform(
transform: Matrix4.identity()..rotateZ(_newAngle),
alignment: FractionalOffset.center,
child: GestureDetector(
child: Container(
color: Colors.blueGrey,
width: 200,
height: 200,
),
onTap: () => onContainerTap(),
),
),
);
});
}
}
您可以参考 this Medium 文章来了解 TweenAnimationdBuilder
的工作原理。您还可以修改 _millsecs
变量来加速 up/down 动画。在 Scaffold(...)
.
的 body
参数中传递 TweenAnimatedBuilderRotate()
如何制作重复但以曲线动画启动的 AnimatedController。
代码:
AnimationController :
var _animating = false;
AnimationController _rotationAnimationController;
Animation<double> _animation;
@override
void initState() {
super.initState();
_rotationAnimationController = AnimationController(
duration: Duration(milliseconds: 2000),
vsync: this,
);
_animation =
Tween<double>(begin: 0, end: 4 * pi ).animate(_rotationAnimationController)
..addListener(() {
setState(() {});
});
}
@override
void dispose() {
_rotationAnimationController.dispose();
super.dispose();
}
Button :
GestureDetector(
onTap: () {
Duration startStopTime = Duration(seconds: 3);
if(_animating) {
_rotationAnimationController.animateBack(1, duration: startStopTime, curve: Curves.easeOut);
setState(() {});
} else {
_rotationAnimationController.repeat() //This needs to start with a curve
}
setState(() {
_animating = !_animating;
});
},
child: [...]
),
如果你也可以做到 repeat 停止时,它会以曲线的方式进行,那也太棒了:)
感谢您的帮助:D
我最好理解你的问题,你想要 CurvedAnimation
对吗?这意味着您的动画将重复但遵循特定的曲线。所以这里是我能为您做的最好的事情:
像这样定义你的 AnimationController
:
Animation<double> _animation;
AnimationController _animationController;
@override
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: Duration(seconds: 2))
..addListener(() {
setState(() {});
});
final Animation curve =
CurvedAnimation(parent: _animationController, curve: Curves.easeOut);
_animation = Tween<double>(begin: 0, end: pi * 4).animate(curve);
}
你的 GestureDetector
是这样的:
GestureDetector(
onTap: () {
if (_animationController.isAnimating)
{
_animationController.animateBack(0,duration: Duration(seconds: 2), curve: Curves.easeIn);
}
else {
_animationController.repeat();
}
},
child: [...]
),
编辑 :
我用了一个TweenAnimationBuilder
来达到你想要的效果:
import 'package:flutter/material.dart';
import 'dart:math' as math;
class TweenAnimatedBuilderRotate extends StatefulWidget {
TweenAnimatedBuilderRotate({Key key}) : super(key: key);
@override
TweenAnimatedBuilderRotateState createState() =>
TweenAnimatedBuilderRotateState();
}
class TweenAnimatedBuilderRotateState
extends State<TweenAnimatedBuilderRotate> {
double _newAngle = 0;
Curve curveThatChanges = Curves.easeIn;
bool isAnimating = false;
int _millsecs = 2000;
void onCompletion() {
if (isAnimating) {
_newAngle += 4 * math.pi;
curveThatChanges = Curves.linear;
_millsecs = 1000;
setState(() {});
} else {
_newAngle = 0;
_millsecs = 2000;
}
}
void onContainerTap() {
if (isAnimating) {
isAnimating = false;
_newAngle = _newAngle;
setState(() {});
} else {
curveThatChanges = Curves.easeIn;
_newAngle += 4 * math.pi;
isAnimating = true;
setState(() {});
}
}
@override
Widget build(BuildContext context) {
return TweenAnimationBuilder(
tween: Tween<double>(begin: 0, end: _newAngle),
duration: Duration(milliseconds: _millsecs),
onEnd: () => onCompletion(),
curve: curveThatChanges,
builder: (
BuildContext ctx,
double angle,
Widget child,
) {
_newAngle = angle;
return Center(
child: Transform(
transform: Matrix4.identity()..rotateZ(_newAngle),
alignment: FractionalOffset.center,
child: GestureDetector(
child: Container(
color: Colors.blueGrey,
width: 200,
height: 200,
),
onTap: () => onContainerTap(),
),
),
);
});
}
}
您可以参考 this Medium 文章来了解 TweenAnimationdBuilder
的工作原理。您还可以修改 _millsecs
变量来加速 up/down 动画。在 Scaffold(...)
.
body
参数中传递 TweenAnimatedBuilderRotate()