在上一篇文章《在小程序中实现原生相册》中,我们学习了自定义路由搭配共享元素实现的原生相册效果,共享元素可以让用户在体验小程序时视觉关联性更强。
除了相册实现之外,常见的卡片转场也非常适合。
⬆️ 演示效果:默认动画 vs 卡片转场动画
👇 下面我们来看看卡片转场中通过 共享元素 + 自定义路由 来实现无痕跳转。
这里的转场稍微有点复杂,涉及到以下 3 个点
- 旧卡片:图片放大、内容渐隐
- 新页面:按比例放大、页面渐显
- 手势搭配
1、旧卡片:图片放大、内容渐隐
在本示例中,列表页采用的是 scroll-view 瀑布流布局的实现。
这里我们的共享元素是卡片,即 grid-view 中的内容 card,卡片包括 图片、内容描述。
默认情况下,共享元素是整个节点进行飞跃的,由于前后页面的图片元素一致但文本内容不一致, 导致在第一帧或者最后一帧会有跳动的效果。
为了让转场动画更加自然,我们需要在飞跃的过程中渐隐旧卡片的内容描述。
在这里,我们需要先用 this.applyAnimatedStyle 来给对应的节点绑定 worklet 驱动动画。
- .card_wrap 节点:整个卡片按比例放大
- .card_desc 节点:内容描述渐隐
关于动画执行的时机,我们可以通过配置项修改。
- immediate:设置是否立即执行驱动动画
- flush:shareValue 更新时,applyAnimatedStyle 的 updater 函数刷新时机
在本例中,需要保证共享元素的图片与目标页面图片位置重叠,所以 flush 设置 sync 在当前时间片刷新。
绑定完驱动动画之后,我们需要给共享元素绑定帧回调事件,根据当前动画进度改变共享变量的值来驱动共享动画
2、新页面:按比例放大、页面渐显
新页面在路由中的动画,需要在自定义路由中进行配置。关于自定义路由的更多介绍,可参考《小程序页面转场动画》
在路由动画过程中,我们将上一步的共享元素帧回调拿到 begin、end 的值,然后结合动画进度 t 计算得出新页面的位置、缩放比例。
还有根据动画进度,设置页面渐显,与前面的卡片渐隐承接。
3、手势搭配
学习过我们前面的文章的同学都知道,自定义路由经常需要结合页面手势,来实现手势返回,关于手势的基础知识可参考《小程序页面转场动画》
这里我们希望手势缩小整个当前页面,所以这里手势返回时只在当前页面做手势动画即可。
在页面详情页的最外层,嵌套一个手势组件 pan-gesture-handler,当手势拖动时根据手势的位置改变整个页面(通过 #fake-host 控制)的位置和大小来达到拖动的效果。
同样绑定页面驱动动画,通过 applyAnimatedStyle 给 #fake-host 绑定驱动动画,当共享变量 transX、transY 等变化时则自动改变 transform 来驱动 #fake-host 缩小。
接着绑定手势事件,根据手势拖动时拿到位置信息改变共享变量 transX、transY 的值。
最后我们需要设置背景颜色透明,来达到类似把卡片拖回列表的视觉效果,更好的减少页面切换感~
一个自定义路由的页面会有 3 层可以设置到背景色,要做到透明的效果需要将 3 个背景色都设置为透明。更多自定义路由背景色的详情参考官方文档。
想要试试卡片转场的无恒效果~扫描 ⬇️ 下方小程序码即可体验。
如果你也想在小程序中实现卡片转场动画,mark 下这个 源码 直接接到到你的小程序吧~