我是如何设计后台框架里那些锦上添花的动画效果

CSS3 的 transformtransition 让开发者可以轻松实现转场、过渡的动画效果,但这并不代表谁可以做出一个流畅、清晰的动画效果。

在这篇文章里,我尝试在 Fantastic-admin 后台框架里去增加一些锦上添花的动画效果,并会分享我的设计思路。

本文观点为作者主观看法,有不同见解欢迎友好讨论。

准备工作

首先动效是属于设计的活,对于开发来说,其实是不擅长的,包括我也一样。那怎么办呢?一种就是请教设计大佬,但这种机会比较少,我的办法就是参考大厂出的一些设计规范,而我这次参考的就是几年前的 Material Design 。

然后就是参考同类产品,看看他们在那些地方都加了动效,并以使用者的角度去感受动效是否合理,是否会破坏用户的操作体验。

最后关于动效执行时间,在简单阅读了 Material Design 后,我大致理解为,移动端长动画大约在 300ms 到 400ms ,短动画大约在 150ms 到 200ms ,而桌面端动画大约在 150ms 到 200ms ,可以看到所有动画执行时长都不会超过 400ms ,设置大部分都会控制在 300ms 以内,因为过长的动画会让人感觉迟钝,相反,过短的动画也会让人觉得难以看明白。

所以我最终确定的整体思路就是,页面中尽量避免元素突然出现或消失,也就是说动态载入和动态删除的元素尽量通过动效进行缓进和缓出,然后页面上的固定元素如果需要位移或者变更尺寸等操作,则必须使用动效进行过渡。而动画执行时长控制在 150ms 到 300ms 之间,因为有些大区域的动画使用 200ms 会显得太短,甚至看不出有动画效果。

接下来就是依次改造了。

吸顶层

这是一个很常见的场景,通过 position: fixed; 固定在顶部的模块不会随着页面滚动而移动,因为固定在内容区的上方,所以使用 box-shadow 模拟出悬浮的效果,然后再配合 js 动态计算页面 scrollTop 的距离,从而动态增加阴影效果。

部分代码:

1
2
3
4
.breadcrumb-container {
transition: box-shadow 0.2s;
box-shadow: 0 10px 10px -10px #ccc;
}

面包屑导航

面包屑导航用来展示当前页面所在的层级,所以当路由切换时,面包屑导航也会随之变化。这里我没有使用淡入淡出的效果,而是从右侧做了一个位移的效果,同时配合文字的倾斜,给用户传递“进入页面”的意思。

你会发现,这里其实是没有移出动画的,只做了进入的效果。因为用户操作的时候视觉是跟随鼠标的,而面包屑导航的变化一般是在点击侧边栏导航进行路由切换时才会变化,用户并不太会注意到面包屑导航,加上本身又是个短动画,要控制好执行时长,一出一进显得有点拖沓,所以就把移出动画去掉了,当然最终效果还是可以接受的。

部分代码:

1
2
3
4
5
6
7
8
.breadcrumb-enter-active {
transition: all 0.2s;
}
.breadcrumb-enter,
.breadcrumb-leave-active {
opacity: 0;
transform: translateX(30px) skewX(-50deg);
}

标签栏

标签栏是参考了 chrome 浏览器的界面,新增和关闭的动画从原本横向展开的形式,改成了上下升降的形式。

有人会问,这里为什么又有移出的动画了?其实还是上面说的那个思路,用户操作的时候视觉是跟随鼠标的,而标签栏上操作的相对比较频繁的,因为会在多个标签页面之间切换,所以这块移出动画不可少。同时升降的形式也避免了标签元素在执行各自动画时的重叠。

部分代码:

1
2
3
4
5
6
7
8
9
10
11
12
.tab-animate {
display: inline-block;
transition: transform 0.2s ease, opacity 0.2s ease;
}
.tabbar-enter,
.tabbar-leave-to {
opacity: 0;
transform: translateY(30px);
}
.tabbar-leave-active {
position: absolute;
}

主题

主题切换需要注意的就是动画执行时间,因为使用的是 ElementUI 里的 Menu 组件,它自带了 transition 的设置,并且时长是 300ms ,所以为了统一,导航的动画时长我都调整成了 300ms ,这样在切换主题的时候,过渡效果就显得比较整体,不然就会出现这样的情况:

导航栏

导航栏折叠的效果难点其实和上面的一样,就是注意动画执行时长,与 ElementUI 的 Menu 组件保持一致。

内容区

内容区也就是业务页面,过渡没用使用 transform 处理,因为考虑到内容区里的元素不可控,而 transform 会导致 position: fixed; 定位失效。

同时将 <transition> 组件的 mode 设置为 mode="out-in" ,因为不设置的话,进来的元素和出去的元素动画是同时执行的,就会出现动画执行时它俩是一上一下的位置,知道上面的元素完全移出后,下面的元素突然被顶了上来,效果不理想,除非进入的元素设置成 position: absolute; ,将其覆盖在移出元素上方,但脱离文档里就会有太多不可控的因素。

所以最终内容区的动效我采用 margin-left 进行处理,并且模式是先出后进,为了避免两个动效执行总时长过长,移出的动画为 200ms ,进入的动画为 150ms ,总时长控制在 400ms 以内,因为不能使用 transform 所以也就不能进行 GPU 加速,过短的时长偶尔会出现掉帧的情况。

部分代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.main-enter-active {
transition: all 0.2s;
}
.main-leave-active {
transition: all 0.15s;
}
.main-enter {
opacity: 0;
margin-left: -20px;
}
.main-leave-to {
opacity: 0;
margin-left: 20px;
}

最后

这就是整体的一个效果演示了。

当然如果你感兴趣,你可以去 Fantastic-admin 实际操作体验一下,这是我写的一个中后台系统框架,基于 Vue 和 ElementUI 。

参考