Flutter实现点击触发蜜蜂图片跨页面飞行动画的方案咨询
Flutter页面跳转时实现蜜蜂跨页面飞行动画方案
要实现点击按钮后,Page1左上角的蜜蜂动画飞到Page2右下角的效果,可通过自定义页面路由过渡来实现,具体步骤如下:
1. 标记Page1中蜜蜂的位置
在Page1的状态类中添加GlobalKey,用来获取蜜蜂组件的全局坐标:
class _Page1State extends State<Page1> { final GlobalKey _beeKey = GlobalKey(); // 添加全局key @override Widget build(BuildContext context) { // ... 原有代码 // 给蜜蜂容器设置key Container( key: _beeKey, height: height / 8, child: RotationTransition( turns: AlwaysStoppedAnimation(-70 / 360), child: Image.asset( "assets/images/bee.png", fit: BoxFit.cover, ), ), ), // ... 原有代码 } }
2. 自定义带蜜蜂动画的页面路由
创建自定义PageRouteBuilder,在过渡过程中绘制蜜蜂的飞行动画:
class BeeFlyRoute extends PageRouteBuilder { final Widget child; final GlobalKey beeKey; BeeFlyRoute({required this.child, required this.beeKey}) : super( transitionDuration: const Duration(milliseconds: 800), // 动画时长可调整 pageBuilder: (context, animation, secondaryAnimation) => child, ); @override Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) { // 获取蜜蜂在Page1的全局位置与尺寸 final RenderBox beeBox = beeKey.currentContext!.findRenderObject() as RenderBox; final Offset startOffset = beeBox.localToGlobal(Offset.zero); final Size beeSize = beeBox.size; // 计算Page2右下角的目标位置(可根据需求调整边距) final screenSize = MediaQuery.of(context).size; final Offset endOffset = Offset( screenSize.width - beeSize.width - 20, screenSize.height - beeSize.height - 20, ); // 位置与旋转动画的Tween final positionTween = Tween<Offset>(begin: startOffset, end: endOffset); final rotationTween = Tween<double>(begin: -70 / 360, end: 0); // 让蜜蜂飞行时转正 return Stack( children: [ // 保留原有页面滑动过渡效果 SlideTransition( position: Tween<Offset>(begin: const Offset(1, 0), end: Offset.zero) .animate(CurvedAnimation(parent: animation, curve: Curves.easeInOut)), child: child, ), // 蜜蜂飞行动画层 Positioned( child: AnimatedBuilder( animation: animation, builder: (context, child) { return Transform( transform: Matrix4.identity() ..translate( positionTween.evaluate(animation).dx, positionTween.evaluate(animation).dy, ) ..rotateZ(rotationTween.evaluate(animation) * 2 * 3.14159), child: child, ); }, child: Image.asset( "assets/images/bee.png", width: beeSize.width, height: beeSize.height, fit: BoxFit.cover, ), ), ), ], ); } }
3. 修改跳转逻辑使用自定义路由
替换Page1中GestureDetector的onTap方法,使用自定义路由跳转:
GestureDetector( onTap: () { Navigator.push( context, BeeFlyRoute(child: const Page2(), beeKey: _beeKey), ); }, child: const ImageIcon( AssetImage("assets/images/Front_arrow.png"), size: 50, color: Colors.black, ) )
可选优化
- 如果需要蜜蜂沿曲线飞行,可使用
PathTween定义贝塞尔路径,替代线性的Offset过渡 - 若需精准定位Page2中的某个组件,可在Page2中添加
GlobalKey获取目标位置,再传递给自定义路由 - 调整动画曲线(如
Curves.fastOutSlowIn)让飞行更自然
内容的提问来源于stack exchange,提问作者ChiragGupta2111
相关产品推荐
相关产品推荐

