根据鼠标位置更新动画

问题描述 投票:0回答:1

我有一个带有

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)!,
          ),
        ),
      ),
    );
  }
}

结果

预期结果:随着鼠标移动,背景颜色会平滑地变化。

实际结果: 背景颜色仅在鼠标停止移动时才会出现动画。

flutter flutter-animation
1个回答
0
投票

首先我正在考虑添加一个监听器并使用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();
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.