9月的时候,为单页试图引擎 Cyra 2.1.0 版本增加了一个创建视图切换动画的功能,使得 i 版页面之间切换也可以有一个滑入滑出的效果。一直没有时间做一个梳理,现在记录一下。最终的效果如图:
其实思路比较简单,就是在 Router 中控制。首先,将所有视图容器 position
都设置为 absolute
。当切入视图完全渲染出来后(也就是执行完 willAppear
钩子函数),设置当前展示视图和即将展示的视图两者的 animation CSS 属性,在 animation 中修改视图容器的 translateX
来实现动画效果。
因为每个视图容器是单例的(Mix 页除外),当项目中出现循环路径,如:
View A -> View B -> View C -> View A
或者当 A 和 C 是同一个视图,只是数据不同。这种情况下,如果视图右滑,也就是用户主动通过点击“返回”按钮进入(返回)前一个视图时,当前视图向右滑出。如果滑出后不修改它的样式,就还要记录每个视图容器当前位置。
鉴于上面的原因,考虑只保留两个位置:
这样,所有动画抽象为4个类型,对应的 animation @keyframes 分别为:
left-move-in
:视图从屏幕左侧滑入屏幕; left-move-out
:视图从屏幕内滑出到屏幕左侧; right-move-in
:视图从屏幕右侧滑入屏幕; right-move-out
:视图从屏幕内滑出到屏幕右侧。 注意:因为所有非当前视图都需要堆叠在屏幕外左侧,所以对于 right-move-out
需要特殊处理,即在动画执行到 99% 时就要将视图完全滑出到屏幕外,最后再将视图移动到屏幕外左侧。四个动画对应的 CSS 如下:
@keyframes left-move-in{ from{ transform: translateX(-100%); opacity: 0; } to{ transform: translateX(0); opacity: 1; } } @keyframes left-move-out{ from{ transform: translateX(0); opacity: 1; } to{ transform: translateX(-100%); opacity: 0; } } @keyframes right-move-in{ from{ transform: translateX(100%); opacity: 0; } to{ transform: translateX(0); opacity: 1; } } @keyframes right-move-out{ from{ transform: translateX(0); opacity: 1; } 99%{ transform: translateX(100%); opacity: 0; } to{ transform: translateX(-100%); } }
以上样式需要业务手动添加到自己的项目代码中。然后,在下一个视图执行 willAppear
之后,根据用户是点击“返回”按钮进入新页面还是通过 switchRoute
执行跳转进入新页面,判断当前视图和新视图即将移动的方向 direction
并设置对应的动画,最后的 CSS 设置为:
animation: CyraConfig.ANIMATION_PREFIX + direction + '-move-in ' + CyraConfig.SWITCH_DURATION + 'ms' + CyraConfig.ANIMATION_FUNC + ' forwards' animation: CyraConfig.ANIMATION_PREFIX + direction + '-move-out ' + CyraConfig.SWITCH_DURATION + 'ms ' + CyraConfig.ANIMATION_FUNC + ' forwards'
其中 ANIMATION_PREFIX
用来为上述4个 keyframes 加前缀避免混淆, SWITCH_DURATION
设置动画时间, ANIMATION_FUNC
设置 timing function。它们都可以通过传入参数进行配置。最后添加一个开关用来打开或关闭动画效果。
其实,还有两个功能可以后续优化:
translateX
属性,可以通过参数进行配置; 这就是此次实现视图切换动画的全部思路和实现, Cyra 2.1.0 开始支持。