HarmonyOS APP<玩转React>开源教程三十:特效与动画

张开发
2026/5/3 13:02:14 15 分钟阅读
HarmonyOS APP<玩转React>开源教程三十:特效与动画
第30次特效与动画本文不讲抽象动画理论而是直接结合项目现有实现来看。当前项目中最有代表性的动画和特效主要集中在Index.ets的新年烟花效果以及FloatingButton.ets中的浮动菜单展开动画。为什么这个项目里的动画值得单独讲很多教程会把动画写成和业务完全脱节的“花活”但当前项目里的动画至少有两个很好的特点动画是附着在真实业务页面上的动画有明确的触发条件和退出机制这就说明它不是“为了炫技而炫技”而是在增强节日氛围、提升交互反馈。Index.aboutToAppearcheckNewYearPeriodshowFireworks truestartFireworkslaunchFirework 多次发射粒子setInterval 持续 updateParticles5秒后 fadeOutFireworks动画结束并清理定时器一、节日烟花效果是怎么做出来的Index.ets里实现了一个完整的烟花粒子系统。核心思路不是直接播放视频而是自己维护粒子状态粒子位置x / y速度vx / vy颜色大小透明度生命周期然后通过定时器不断刷新这些状态让粒子看起来像爆炸、扩散和下落。这种做法的好处是动画完全可控可以随机生成不会死板不依赖额外视频资源对于鸿蒙声明式 UI 来说这是一种很有教学价值的动画实现方式。二、为什么烟花动画要有“触发条件”动画不是一进应用就无脑播放而是先调用checkNewYearPeriod()只在设定时间范围内开启。也就是说这个动画本质上是一个“节日主题活动层”不是常驻效果。这种设计非常成熟因为它说明作者考虑了动画的出现时机动画对主界面的影响动画结束后的清理逻辑真正好的动画永远不是到处乱飞而是知道什么时候该出现、什么时候该收回。三、为什么FireworksOverlay()要单独作为一个层烟花效果并没有塞进首页内容区而是放在最外层Stack()中作为一个覆盖层出现。这样做有几个明显好处不会破坏原本页面布局。可以在任意时刻整体显示或隐藏。便于统一控制透明度和点击关闭。这是一种很典型的“视觉特效层”设计方式。你以后做欢迎动画、全局提示、节日皮肤、庆祝弹层时都可以参考这种写法。四、为什么动画一定要处理退出和清理当前代码里有几个很重要的清理动作aboutToDisappear()中停止定时器fadeOutFireworks()中逐步降低透明度dismissFireworks()中主动关闭并清空粒子数组这说明动画不是只管开始不管结束。尤其在移动端动画如果不处理好生命周期就会带来内存泄漏定时器残留页面切走后仍在消耗性能所以教程里必须强调动画系统一定要考虑“清理”这和写业务逻辑一样重要。五、浮动菜单动画为什么也是很好的示例除了烟花效果FloatingButton.ets中的FloatingActionMenu也提供了一个很实用的小型动画案例。它的核心思路是主按钮点击后切换isExpanded根据状态决定是否显示搜索和收藏入口展开的子按钮分别加了不同delay使用Curve.EaseOut提升展开观感这虽然只是一个简单菜单但它很好地体现了“动画服务于交互反馈”的原则。用户点了主按钮就应该明显感觉到界面进入了新状态而不是突然多出几个按钮。六、动画与业务边界应该怎么拿捏这一篇最值得你记住的一点是动画要增强业务而不是抢业务的戏。在当前项目里烟花动画只在节日时触发并且可点击关闭浮动菜单动画只是辅助入口展开技能树节点、卡片等视觉状态也只是轻量强化这说明动画设计是克制的。移动端学习应用尤其需要这一点因为用户的核心目标是学习内容不是看特效。七、图文结合看一张动画层示意图业务内容层 Tabs / 首页 / 列表覆盖层 StackFireworksOverlay半透明背景粒子 Circle 列表节日文案这张图能帮助你理解真正稳定的动画往往不是直接改业务层而是额外叠一层视觉层。八、自己动手时怎么验证最有效打开Index.ets先看烟花相关状态定义。顺着checkNewYearPeriod - startFireworks - updateParticles - fadeOutFireworks读一遍。再看FireworksOverlay()如何把粒子渲染成多个Circle()。打开FloatingButton.ets观察展开菜单的动画写法。思考如果你要把动画移除哪些业务仍然能正常工作。做到这里你对动画与业务之间的边界就会更清晰。九、本篇常见坑1. 动画没有退出逻辑这是最常见也最危险的问题。2. 动画直接写进业务布局覆盖层设计通常更安全、更清晰。3. 动画太重影响主要流程学习应用尤其要避免喧宾夺主。4. 所有按钮同时弹出没有层次像浮动菜单那样加轻微延迟体验会更自然。本篇小结当前项目里的特效与动画给了我们两个很实用的范例大型节日视觉层烟花粒子动画小型交互反馈层浮动菜单展开动画两者共同说明了一件事动画不是孤立功能而是服务于产品氛围和操作反馈的辅助手段。跟着真实源码继续往下看烟花动画发射粒子的真实代码如下privatelaunchFirework(x:number,y:number):void{constcolors[#ff6b6b,#ffd93d,#6bcb77,#4d96ff,#ff6bd6,#61DAFB];constparticleCount30;for(leti0;iparticleCount;i){constangle(Math.PI*2*i)/particleCountMath.random()*0.5;constspeed3Math.random()*4;浮动菜单展开动画的真实代码如下if(this.isExpanded){Column(){FloatingButton({icon:,size:48,onTap:(){this.isExpandedfalse;this.onSearchTap();}})}.animation({duration:200,curve:Curve.EaseOut})}按这个顺序动手打开Index.ets搜索launchFirework和updateParticles。再打开FloatingButton.ets看isExpanded如何控制菜单展开。观察动画状态和业务状态是不是清楚分开了。课后练习想一想如果要把烟花效果改成“完成模块时触发一次庆祝动画”最适合由哪个页面触发。观察FloatingActionMenu的延迟配置思考为什么两个按钮不同时出现更自然。说明为什么动画清理逻辑应该被视为功能的一部分而不是附属细节。

更多文章