Vue在移动端如何仿原生过场动画?

1,649 阅读4分钟

论开发效率,那当然是 H5 最快、最高效。

论用户体验,还得是原生 App 最丝滑、最流畅。

那,当 App 遇上 H5,它们又会迸发出什么样的火花?

体验真的那么差?

因为 H5 跨端的特性,很多业务都会选择 H5 来快速上线,那我们这边也不例外。

但是以前的 H5 项目逐渐被小程序所替代,就是因为小程序的体验比原生 H5 开发要好。

虽然底层逻辑有原生 App 的支撑,让一些动画效果会比 transform 更流畅,比如小程序的过场动画、地图组件等。

以往的 H5 多页面项目切换页面时都是重新加载各种资源重新渲染过,白屏硬切换,用户体验自然很差劲,App 中嵌入的网页一下子就能感觉到是 H5。

那我们纯 Web 单页面应用就没有办法提升用户体验了吗?

自从有了单页面应用之后,我们可以利用 SPA(Single Page Application) 的特性做我们自己的过场动画。

怎么实现?

所有单页应用对于过场动画的实现应该都是相通的。

这里我主要以 Vue 为主来介绍一下如何实现过场动画。

技术点:

  • Vue Router
  • <transition>

首先我们来看一下动画效果

demo.gif

没错,接下来我们就要对上面的动画进行拆解

Push 动画

  • Next 页面在上,Home 页面在下
  • Next 页面从左侧完全移入
  • Home 页面从原始位置向右移出 50%,逐渐变透明至 0.4
  • Next 页面左侧增加阴影

Pop 动画

  • Next 页面在上,Home 页面在下
  • Next 页面从左向右移出
  • Home 页面从 -50% 位置从左侧向右完全移入,逐渐变不透明至 1
  • Next 页面左侧增加阴影

这个时候大家有没有发现,动画一拆解,大家就都有思路了呢?

其实动画实现就是这样,分步考虑清楚,各种转场动画随我们怎么实现。

遇到的一些问题

  • Q: 页面切换的时候,默认文档流布局会让我们的 Home 与 Next 页面呈上下排布

    Aposition: absolute

  • Q: Pop 动画结束的时候,Next 页面的阴影会突变(translateX(100%)后隐藏时,左侧阴影还在视觉范围内)

    AtranslateX(102%)(这里只是举个栗子,保证阴影部分也滑到页面可视范围之外即可)

这里贴出 css 部分大家参考一下

.slide-right-enter-active,
.slide-left-enter-active,
.slide-right-leave-active,
.slide-left-leave-active {
    box-shadow: -20px 0 20px 0px rgba(0, 0, 0, 0.1);
    will-change: transform;
    transition: all 0.3s ease-out;
    position: absolute;
}

.slide-right-enter-from {
    opacity: 0;
    transform: translateX(-50%);
}
.slide-right-leave-to {
    z-index: 100;
    transform: translateX(102%);
}

.slide-right-leave-from {
    box-shadow: -20px 0 20px 0px rgba(0, 0, 0, 0.1);
}
.slide-left-enter-from {
    z-index: 100;
    transform: translateX(100%);
    box-shadow: -20px 0 20px 0px rgba(0, 0, 0, 0.1);
}
.slide-left-leave-to {
    opacity: 0.4;
    transform: translateX(-50%);
}

如何根据页面路由选择合适的动画?

这里我先抛出几个场景需要解决的问题:

  1. 页面 push 的时候执行 slide-left,页面 pop 的时候执行 slide-right
  2. 页面刷新的时候不执行动画
  3. Tab 切换页面的时候不执行动画

其实一开始我想的通过页面传参来判断动画的 name,显式的告诉 router 我是 push 还是 pop

这就出现了个问题,我刷新的时候,动画依然会执行,所以这个方案 pass

后面又有一个思考,自己来维护路由栈,通过自行提供的 push 与 pop 方法来完成页面切换

这种方案在移动端还可控,但是浏览器端就很难控制

最终,采取了在路由表中设置好页面的深度关系(depth),动画也通过页面间的深度关系来自动选择动画的 name

浅入深用 push,深入浅用 pop,同级不执行动画

这也是我 Demo 中采取的方案,大家可以看源码是如何做到的。

Demo在线演示

Demo源码地址

喜欢的小伙伴别忘记点个 Star 哦~

后记

H5 加入过场动画嵌入 App 之后,运营商务的小伙伴有些人甚至都不知道这部分功能是 H5 实现的(当然这也离不开 Hybrid 的支持,让双端可以无缝通信),这点让我对 Web 动画有了充足的信心

在手机性能对浏览器的支持逐渐增强的今天,我们 Web 开发也可以好好利用动画让我们 H5 交互也变的和原生一样丝滑

对于过场动画的思考我就分享到这里,希望大家有好的想法也能多多反馈,让我们将 H5 体验做的更好