我有一个带有
AnimationController
的 Flutter Web 应用程序,需要根据鼠标的位置将动画设置为新值,并且动画需要有一条曲线。我通过在 animateTo
的 onPointerHover
回调中调用 Listener
来更新动画。但是,动画在鼠标移动时不会更新,只有在鼠标移动后静止时才会更新。
这是一个最小的可重现示例,我正在网络上运行:
import 'package:flutter/material.dart';
void main() {
runApp(const MouseAnimationApp());
}
class MouseAnimationApp extends StatefulWidget {
const MouseAnimationApp({Key? key}) : super(key: key);
@override
State<MouseAnimationApp> createState() => _MouseAnimationAppState();
}
class _MouseAnimationAppState extends State<MouseAnimationApp>
with SingleTickerProviderStateMixin {
late final _controller = AnimationController(vsync: this);
void _updatePosition(double globalPosition) {
_controller.animateTo(
globalPosition / MediaQuery.of(context).size.height,
curve: Curves.easeOutQuart,
duration: const Duration(milliseconds: 700),
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Listener(
onPointerHover: (event) => _updatePosition(event.position.dy),
child: AnimatedBuilder(
animation: _controller,
builder: (_, __) => ColoredBox(
color: Color.lerp(Colors.red, Colors.black, _controller.value)!,
),
),
),
);
}
}
结果
预期结果:随着鼠标移动,背景颜色会平滑地变化。
实际结果: 背景颜色仅在鼠标停止移动时才会出现动画。
首先我正在考虑添加一个监听器并使用curveAnimation的value属性来尝试实现你想要的,但你也可以尝试使用animations lerp方法。 试试这个,我想你会明白的。
class MouseAnimationApp extends StatefulWidget {
const MouseAnimationApp({Key? key}) : super(key: key);
@override
State<MouseAnimationApp> createState() => _MouseAnimationAppState();
}
class _MouseAnimationAppState extends State<MouseAnimationApp>
with SingleTickerProviderStateMixin {
late final AnimationController _controller;
late final CurvedAnimation _curvedAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 700),
);
_curvedAnimation = CurvedAnimation(
parent: _controller,
curve: Curves.easeOutQuart,
);
}
void _updatePosition(double globalPosition) {
_controller.animateTo(globalPosition / MediaQuery.of(context).size.height);
}
Color _getColorFromAnimationValue(double animationValue) {
return Color.lerp(Colors.red, Colors.black, animationValue)!;
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Listener(
onPointerHover: (event) => _updatePosition(event.position.dy),
child: AnimatedBuilder(
animation: _controller,
builder: (_, __) {
final color = _getColorFromAnimationValue(_curvedAnimation.value);
return ColoredBox(color: color);
},
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}