# 共享元素动画

原生 App 中我们常见到这样的交互,如从商品列表页进入详情页过程中,商品图片在页面间飞跃,使得过渡效果更加平滑,另一个案例是朋友圈的图片预览放大功能。在 Skyline 渲染模式下,我们称其为共享元素动画,可通过 share-element 组件来实现。

在连续的 Skyline 页跳转时,页面间 key 相同的 share-element 节点将产生飞跃特效 樱花视频在线,开发者可自定义插值方式和动画曲线,通常作用于图片,为保证动画效果,前后页面的 share-element 子节点结构应该尽量保持一致。

# 立即体验

扫码打开小程序示例 樱花视频高清,交互动画 - 基础组件 - 共享元素动画 即可体验。

# 使用方法

属性类型默认值必填说明最低版本
keystring映射标记,页面内唯一2.29.2
transition-on-gesturebooleanfalse手势返回时是否进行动画2.29.2
shuttle-on-pushstringto指定 push 阶段的飞跃物2.30.2
shuttle-on-popstringto指定 pop 阶段的飞跃物2.30.2
rect-tween-typestringmaterialRectArc动画插值曲线2.30.2
on-frameworklet callback动画帧回调2.30.2

假定 A 页和 B 页存在对应的 share-element 组件

  1. push 阶段:通过 wx.navigateToA 进入 B,称 A 为源页面(from 页),B 为目标页(to 页)
  2. pop 阶段:通过 wx.navigateBackB 返回 A,此时 B 为源页面 (from 页), A 为目标页(to 页)

# 指定飞跃物

开发者可以指定选定源页面或目标页的 share-element 作为飞跃物。

由于涉及两个页面的组件,这里以目标页 share-element 组件指定的属性为准 樱花视频.

  1. push 阶段:默认采用 B 页的 share-element 组件进行飞跃,设置属性 shuttle-on-push=from 可切换成 A 页的。
  2. pop 阶段:默认采用 A 页的 share-element 组件,设置属性 shuttle-on-pop=from 可切换成 B 页的。

需注意的是 on-frame 回调总是在指定为飞跃物的 share-element 组件上触发。

# 动画帧回调 (樱花视频在线)

共享元素动画就是以源页面 share-element 所在矩形框为起点,目标页 share-element 所在矩形框为终点 樱花视频高清,进行插值计算的过程,动画时长与页面路由时间一致。

___JX5_PROTECTED_code_49___

开发者可通过 on-frame 回调来自定义插值方式 樱花视频免费观看ShareElementFrameData 中包含了始末位置,以及框架按照指定的动画曲线 rect-tween-type 和当前进度 progress 计算的 current 位置。

默认插值方式为对 RectLTWH 分别进行线性插值 樱花视频网站,当 on-frame 返回 undefined 时,当前帧飞跃物的实时位置由 current 决定,开发者可返回按其他方式计算的 Rect 对象进行改写。

___JX5_PROTECTED_code_61___

# 动画插值曲线

除了可以自定义插值方式外,还可以自定义动画曲线,默认的动画曲线为 cubic-bezier(0 樱花视频,4, 0,0, 0,2, 1,0),记作 fastOutSlowIn。。

rect-tween-type 设置为如下类型时 樱花视频在线,默认的插值方式为对 RectLTWH 分别进行线性插值。

此外,rect-tween-type 还支持两类特殊的枚举值,对于这两个值,动画曲线仍是 fastOutSlowIn,但插值方式有所不同 樱花视频高清,运动轨迹为弧线。

# 工作原理

下面以 push 过程为例介绍共享元素动画的各个阶段。

注意:实际上动画过程中 share-element 节点自身不进行动画,移动的是其子节点 樱花视频网站

# 动画开始前

目标页还未渲染,在所有页面之上创建 overlay 层,飞跃物将在 overlay 层进行动画。

# 动画开始时刻

调用 wx.navigateTo 推入新页面时动画触发,progress = 0 时刻发生如下动作

  1. 目标页首帧渲染,框架计算出目标 share-element 节点位置大小。
  2. share-element 节点离屏(不显示)。
  3. 将目标 share-element 节点移至 overlay 层,作为飞跃物,位置大小同源 share-element 节点。

# 动画过程中

根据指定的插值方式和动画曲线,目标 share-elementoverlay 层进行动画,从起点向终点位置过渡。

# 动画结束时刻

progress = 1 时刻,将目标 share-elementoverlay 层移动到目标页面,出现在终点位置。

# 注意事项

  • Skyline 版本 share-element 无需结合 page-container 使用
  • share-element 组件设置 paddingjustify-content 等影响子节点布局的样式将无法生效
  • 可结合页面生命周期 onRouteDone 在路由完成时刻做一些状态恢复工作

# Q & A (樱花视频)

# Q1: 设置了相同的 key,但没有看到飞跃动画

共享元素动画需保证下一个页面首帧即创建好 share-element 节点,并设置了 key,用于计算目标位置。

如果是通过 setData 设置的,可能会错过首帧。针对这种情况,可以 使用 Component 构造器构造下一个页面,只要在组件 attached 生命周期前(含)通过 setData 设置上去,就会在首帧渲染。

# Q2: 飞跃过程中,子节点不会跟随放大/缩小

动画过程中,飞跃物容器会不断变化大小和位置,如果子节点想自适应跟随变化,就需要通过百分比布局,而非写死固定宽高。

___JX5_PROTECTED_code_94___

# Q3: 多个 share-element 一起动画,覆盖层级问题

飞跃物在 overlay 层进行动画,层级在所有页面之上。飞跃物间按其在页面组件树的定义顺序(DFS 遍历),越往后的层级越高。

# Q4: 自定义路由手势返回时,未看到返回动画

首先须给组件设置 transition-on-gesture=true 属性。同时自定义路由手势返回时,只有调用 startUserGesture 接口后才会触发共享元素动画。

樱花视频 - # Q5: 共享元素动画与路由动画关系

共享元素跟随页面路由动画一同开始和结束。如果设置自定义路由的页面进入曲线和 rect-tween-type 一致,则 onFrame 返回的 progress 值也与 PrimaryAnimation.value 的值始终保持一致。

# 示例用法

# 基础用法

商品列表页

___JX5_PROTECTED_code_103___

商品详情页

___JX5_PROTECTED_code_104___

示例代码片段-基础

可在开发者工具中体验效果,这里需要注意图片 mode 不同带来的影响。

樱花视频在线 - # 进阶用法

以仿朋友圈图片预览放大功能为例,介绍通过帧回调解决图片 mode 不同带来的跳变问题。相关功能已封装成 aniamted-image 组件,开发者可在此基础上进行修改。

这里简要介绍核心思路:

  1. 始终以 listshare-element 为飞跃物
  2. 通过 on-frame 改写飞跃物容器的位置大小,使其充满 overlay
  3. 以图片实际占据空间确定始末容器的位置大小,而不是 share-element 节点占据的空间
  4. 飞跃过程中使用缩略图,高清图下载完成后进行替换

默认计算方式,以 share-element 节点占据空间确定始末位置,会产生跳变。

以图片实际占据空间确定始末位置,始终采用单一 mode 效果,不会产生跳变。

使用最新 nightly 工具预览,移动端安卓 8.0.33 版本。

"樱花视频" 示例代码片段-进阶