2017京东集团开年大会在 2 月 10 日终于开始了,当然,也结束了。

微信朋友圈里纷纷表示:

成功保持工作几年来从来没有中过奖的记录。撇嘴

完美错过所有大奖微笑,新的一年大家工作顺利。

一如既往,成功避开所有奖项快哭了快哭了快哭了

虽然没有中奖,但是大家在年会等待开奖期间还是有不少好玩的东西可以消遣的。下面就为大家介绍两个基于 CSS3 做的动画效果:一个是在朋友圈广为扩散、略显逼格的「京彩AR」,一个是严肃认真、指导场内人员的「员工参会电子手册」。

先睹为快吧:

京彩AR        电子手册

京彩AR

要做好一个 CSS3 动画,既要关注性能,流畅不卡顿,适配各种分辨率的手机屏幕,还需要关注作品是否自然,动画过渡流畅生动。在接到项目需求时,我们的内心是崩溃的,不过幸好有友爱的设计师和强力的前端指导,最终完成了所有动画效果。

设计师 「 陈秀峰 」美女给的设计稿如下,包括初始加载动画、仿微信锁屏消息通知、仿微信聊天界面以及一个加载动画的 gif 演示图。

京彩AR设计稿

页面中存在宇航员 Joy、星球、消息块以及若干修饰元素。根据页面所需动画效果的粒度和页面结构,我们将设计稿按下面指示切出素材。

京彩AR设计稿切图

宇航员 Joy

宇航员 Joy 部分的动画最为复杂,它的元素很多,组织好各个元素的出场,在场及退场的时间和顺序是一个极具挑战的。首先我们将元素分布画出来:

load场景概要

我们将距离屏幕最近的左下角星球作为太空运行中心,其余的星球和流星围绕中心运转。对于星球、流星、火箭等这里基本采用的是直线运动,主要是控制运动的速度和直线的角度,还有就是元素前后关系。两点决定一个直线的的轨迹,所以设定各个元素的起始点、终止点以及帧动画运动的时间,例如流星位移利用 translate3d 更改 X 和 Y 的坐标值,将元素移出视窗外。

而宇航员 Joy 脚下的火焰,则利用了精灵动画来处理,首先切一个完整的精灵图,然后用背景图的位移 background-position 来控制动画效果。

精灵图火焰

我们利用 animation属性的 steps 函数做关键帧的划分,这个函数和接下来要讲的贝塞尔函数是 animation-timing-function 的两个可选函数,实际使用中我们经常会忽略 steps 函数的使用。

steps 函数是一个阶跃函数,它对 @keyframes 里的两两关键帧之间进行等分。steps(5) 对0%和100%两个关键帧进行5等分切分,每个等分时间间隔内的动画保持不变。可以这么理解,steps 函数是在 animation-timing-function: linear 时,均匀取了5个点的动画状态,5个动画状态持续时间各占整个帧转换时间的1/5。

需要注意的是,如果 @keyframes 里定义了3个或更多的关键帧,那么 steps 是对所有前后关键帧进行切分。

关于steps更详细的介绍请参考W3C标准博客

微信锁屏消息通知

锁屏消息通知模拟的是 WeChat6.5.4 在 iPhone 下的锁屏通知效果,消息的提示框由中心往外层弹出,它是一个3D动画,我们利用 transform 属性的 scale3d 方法,编写了一组关键帧动画。

要贴近 iPhone 的动画效果,我们就需要对动画的速度曲线有良好的模拟。animation 属性的速度曲线函数属性是 animation-timing-function,它可以接受一个三次贝塞尔(Cubic Bezier)函数。

用一个定义在二维平面的贝塞尔曲线的斜率来描述动画的速度,由于贝塞尔曲线很平滑,那么速度的变化就很平滑。下面是弹出消息的贝塞尔曲线。

cubic-bezier(0.4,0,0,1)

这条曲线结合 @keyframes infoTwo 关键帧信息,可以得到消息通知弹出动画的具体效果:

  • 动画开始时,以一个小于平均速度的方式显现(斜率小于1)

  • 然后快速扩大(斜率远大于1)

  • 等快结束动画时,缓慢下来(斜率小于1)

这样,动画显示出来不显得突兀,同时又能给人一种冲击感,最后缓和下来,不让动画干扰用户提前阅读消息。

微信锁屏消息通知的动画场景转换不多,接下来的聊天界面却充满了各种场景转换,我们将在这一节详细介绍如何进行场景转换的。

微信聊天界面

聊天界面场景转换需要考虑每条信息弹出时的间隔,信息超过屏幕高度时自动上移显示最新一条消息。下面是场景和时间线的规划:

场景规划

场景动画需要注意的问题是动画性能。大家都知道重排(reflow)比重绘(repaint)更耗性能,那么如何处理微信对话场景的元素出入问题呢?我们在首次加载时就把所有元素绘制在页面中,然后利用 opacitytransform 两个属性来处理元素的显现和移动。

  • 显现

  • 移动

  • 转场时间控制

我们使用 setTimeout 方法来处理转场中的一些细节动画,包括微信提示音、头部文字切换。CSS 动画时间和 JS 动画的时间线保持同步成为关键。JavaScript 的事件轮询机制不能保证 setTimeout 方法准确按预期时间延迟,所以,最严格的解决方案就是监听 animation 动画结束事件。

首先,我们对动画结束触发事件方法 animationend 做一个兼容处理:

然后,监听各个场景动画结束事件,比如监听场景6的结束事件:

微信对话是在手机一屏展示的,七、八、九场景是超出去屏幕的。当动画到场景六时候,就需要计算场景七的高度,采用 jQueryanimate  函数来处理上移的动画,八九场景也是一样的处理方法。这样就能完美的贴近真实的微信对话了。

整个京彩AR的动画演示:

ar

chat

是不是很赞呢?

员工参会电子手册

在以上的「京彩AR」动画中看到 CSS3 动画的能力,作为利器, 也可以配合 JS 实现更丰富的交互。长长的开年大会电子手册内容导航组件就是 CSS3 动画配合 JS 相得益彰的绝佳例子。

电子手册的导航菜单类似于一个转盘,当滑动页面到某一个章节时,导航菜单也会转到相应的菜单,并且高亮。

电子手册设计稿

导航菜单可以分为三部分,底部是转盘背景,它是固定不动的。上层分为图标 icon 和章节标题部分。在点击章节图标时,转盘转动。不对背景进行旋转的原因是背景的高光暗含转盘指针功能,因此保持背景不动。

很自然的,利用 transformrotate 属性来进行旋转,利用 transition 属性响应transform  属性变化。

div.wheel 代表一个图标 icon,每个图标 icon按顺序分配一个 wheel 属性,用于关联章节,比如 wheel="2"时,对应的是第二章节。.wheel.wheel-brightbackground-image 是普通状态和高亮状态的图标 sprite 图,用 [wheel='i'] 选择器调整它的 background-position 显示不同的章节图标 icon。

.wheel-layer为图标 icon 布局层,每个图标icon相对于 .wheel-layer 定义的 transform-origin 变换中心旋转。静态情况下,图标 icon 如设计稿一样均匀分布在转盘圆周上,点击时,用  JS 改变 .wheel-layertransform  属性,.wheel-layer 就会按照定义的动画效果相对于 .wheel-menu 旋转,所有的图标 icon也就随之旋转。

关键sass代码如下:

得到的分层结构如图:

wheel-layer

menu-wheel

在页面滚动和点击导航菜单时,如何确定菜单的旋转方向是一个难题!在渲染菜单时,我们已获取当前转盘的状态,因此,可以直接在 JS 里计算转动方向。

其中 fromIdx 是当前高亮的章节图标的 wheel 属性值,toIdx 是点击的章节图标 wheel 属性值或者滚动到的章节。将这个值赋给 .wheel-layertransform 属性后,动画工作就交给 transition属性吧。

测试时发现,有些浏览器转盘并未按预期转动,比如在某款小米手机上,必须加上 wheelLayer.style.webkitTransform属性,否则菜单会无法转动。当然了,我们也可以像给 animationend 事件做兼容处理一样,给这个 transform  属性做一个统一兼容处理。

最终效果:

电子手册转盘效果

总结

CSS3 中的 transform(变换)、transition(过渡)、animation(动画)属性能帮助我们实现很多不可思议的动画效果,减轻了我们的工作量。在2017京东集团开年年会项目中充分利用了这三个属性来完成各种动画交互,取得了不错的效果。

虽然 CSS3 能帮我们完成很多工作,但要保证动画能在各种设备上流畅自然,离不开对细节的不断孜孜追求。

开发者

京彩AR:汪楠

员工参会电子手册:刘佳 GitHub

参考资料

在线贝塞尔曲线函数编辑及效果演示:http://cubic-bezier.com/

CSS 动画帧数计算器:http://tid.tenpay.com/labs/css3_keyframes_calculator.htm

很火的动画库:https://github.com/daneden/animate.css/

更加丰富的 CSS 动画库 – Effeckt.css:http://h5bp.github.io/Effeckt.css/

animation-timing-function W3C 规范:https://www.w3.org/TR/2012/WD-css3-transitions-20120403/#transition-timing-function-property

喜欢(151) 评论(1) 分享
  1. 做这样的一个动画 大概需要多长时间啊?

Leave a Reply

© 2017 JDC. All Rights Reserved.