红包弹窗必须用position: fixed+ v-if控制显隐,禁用uni.showToast;飞入动画用translate3d而非top/left;多端兼容推荐CSS动画为主、JS仅控制class切换,并注意动画结束后的资源清理。

uni-app里用uni.showToast做不了红包弹窗动画
红包弹窗不是普通提示,它要带位移、缩放、旋转、粒子飞入,甚至伴随音效和倒计时。而uni.showToast是平台原生 toast,样式和动效完全不可控,iOS 和 Android 表现还不一致,直接排除。
真正能自定义的只有 view + animation 或第三方库,但 uni-app 的 animation API 在 H5 和小程序端行为差异大,容易卡顿或不触发。
- 小程序端:优先用
createAnimation+transform,别用top/left动画(性能差、抖动) - H5 端:用 CSS
@keyframes更稳,但需注意transform: translateZ(0)强制 GPU 加速 - App 端(vue2):避免在
mounted里立刻开启动画,等$nextTick后再执行
红包弹窗必须用position: fixed且手动控制v-if显隐
不能用 v-show,因为红包动画常依赖元素从无到有的生命周期(比如入场缩放从 0.5→1),v-show 只切 display,节点始终存在,animation 不会重播;也不能用 display: none 写死在 class 里,否则 JS 拿不到真实尺寸做动态计算。
正确做法是:用 v-if 控制挂载/卸载,配合 $nextTick 确保 DOM 渲染完成后再触发动画。
- 红包容器加
style="position: fixed; top: 0; left: 0; width: 100%; height: 100%;",避免被父级overflow: hidden截断 - 动画开始前,先设
opacity: 0; transform: scale(0.7);,再用transition或animation过渡 - 关闭时别只靠
v-if=false,要加animationend监听,确保动画播完再销毁节点,否则可能中断收尾动作(比如红包飘散粒子没播完)
红包飞入动画要用transform: translate3d而不是top/left
用 top 和 left 做位移动画,uni-app 在微信小程序里会强制走 JS 动画帧(非 CSS 合成),60fps 都难保,尤其红包多的时候直接掉帧;translate3d(0, 0, 0) 能让浏览器启用 GPU 图层,H5 和小程序都兼容。
典型飞入路径:红包从屏幕右下角快速飞向左上红包图标位置,中间带轻微旋转和缩放变化。
- 起始状态写死:
transform: translate3d(100vw, 100vh, 0) rotate(20deg) scale(0.8); - 目标状态用 class 切换:
transform: translate3d(20px, 80px, 0) rotate(0) scale(1); - 过渡时间控制在
300ms左右,太慢像卡顿,太快用户来不及反应 - 多个红包同时飞入?别用同一个 class 触发,用
:class="{ 'fly-in': item.isFlying }"配合 key 强制重渲染,否则动画会错乱
uni-app里animation API 在不同平台表现不一致
微信小程序支持 uni.createAnimation 全套方法,但 H5 下部分属性(如 rotateZ)不生效;App 端(vue2)里如果在 onLoad 就调 createAnimation,可能拿不到真实节点尺寸,导致位移偏移。
最省心的方案其实是「CSS 动画为主,JS 仅控制开关」:把所有关键帧写进 class,用 JS 控制 class 名切换,避开 API 差异。
- 不要在
mounted里直接this.animation.translateX(100).step(),改用this.showRedPacket = true触发 class 切换 - 需要动态计算终点坐标?用
uni.createSelectorQuery().select('.target').boundingClientRect(),但必须等节点渲染后调($nextTick或setTimeout0) - 真要用 JS 动画 API:微信小程序可放心用;H5 改用
requestAnimationFrame+transform手写;App 端建议降级为 CSS 动画
实际开发中最容易被忽略的是红包关闭后的状态清理:比如倒计时还在跑、音频没 stop、粒子 canvas 没 destory——这些都会悄悄吃内存,尤其是用户频繁进出页面时。动画结束回调里该 clearTimeout 的 clearTimeout,该 removeEventListener 的 removeEventListener,一个都不能少。









