You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter实现圆形组件水平移动时动态缩放的动画问题求助

Flutter实现同步的3D旋转式圆形移动缩放动画

你的核心问题在于用Timer控制位置移动、AnimationController控制缩放,两者独立运行导致同步失效。解决关键是用同一个AnimationController统一驱动位置和缩放动画,让两者进度完全绑定,彻底解决时间同步问题。

重构后的代码如下:

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({super.key});

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> with TickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _positionAnimation;

  double childSize = 0;
  double screenWidth = 0;
  double centerLeft = 0;
  double maxMoveDistance = 0;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    screenWidth = MediaQuery.of(context).size.width;
    childSize = screenWidth / 4;
    centerLeft = (screenWidth - childSize) / 2;
    maxMoveDistance = centerLeft; // 中心到左/右边缘的距离

    // 统一动画控制器,周期3秒,来回重复
    _controller = AnimationController(
      duration: const Duration(milliseconds: 3000),
      vsync: this,
    )..repeat(reverse: true);

    // 位置动画:0对应左边缘,1对应右边缘
    _positionAnimation = Tween<double>(begin: 0, end: 1).animate(
      CurvedAnimation(parent: _controller, curve: Curves.linear),
    );
  }

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

  @override
  Widget build(BuildContext context) {
    // 根据动画值计算当前left位置
    double currentLeft = (screenWidth - childSize) * _positionAnimation.value;
    // 计算当前位置到中心的距离比例
    double distanceRatio = (currentLeft - centerLeft).abs() / maxMoveDistance;
    // 缩放值:中心时1,边缘时0.25
    double scale = 1 - distanceRatio * 0.75;

    return Scaffold(
      body: Center(
        child: Stack(
          children: [
            Positioned(
              left: currentLeft,
              top: (MediaQuery.of(context).size.height - childSize) / 2,
              child: SizedBox(
                height: childSize,
                width: childSize,
                child: Transform.scale(
                  scale: scale,
                  child: Image.network(
                    "https://example.com/btc-image.png", // 替换为你的图片URL
                    fit: BoxFit.fitWidth,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

关键改进说明

  • 统一动画驱动:用单个AnimationController控制位置和缩放,两者进度完全同步,彻底解决时间错位问题。
  • 位置计算:通过Tween定义从左到右的位置动画,直接映射到屏幕坐标,避免Timer逐帧更新的性能开销和状态混乱。
  • 动态缩放逻辑:基于当前位置与屏幕中心的距离计算缩放值,距离越远缩放比例越小,精准匹配"中心全尺寸、边缘缩小"的视觉需求。
  • 精简代码结构:移除冗余的Timer、AnimatedPositioned等组件,代码更简洁易维护。

内容的提问来源于stack exchange,提问作者Android

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 07:10:27