还记得一个月前财付通首页的那套动画吗?作为设计湿抑或程序猿,你有没为她的实现感到好奇?今天,我们就搭乘时空车,穿梭回去探个究竟吧。温馨提示:抓紧扶手哦 Part1:每个人都有一颗童心(设计理念) 从我们耳熟能详的童话故事入手,将“快捷”、“移动”、“安全”、“轻松”融入其中,寓情于景、寓教于乐,于无形中将财付通的品牌理念植入用户心中 Part2:立体贺卡,你收到了吗(动画方式) 动画的进入效果,模仿的是立体贺卡的展开:基本背景先映入眼帘人物近景、事物远景从纸面上(画面的地面上)站立起来装饰物(文字)从另一空间出现(从屏幕上方坠落),如图: 其中,近景和远景的分开翻转,使立体感、层次感更分明,动画更饱满;时间顺序上,由远及近、由上到下,更贴近立体贺卡的感觉。 Part3:没有flash我照样儿活(动画实现) 1。基本属性 2。疑难杂症 2。13D翻转立体效果 3D动画没有立体效果,像2D一样2B?有没有遇到过?你是怎么处理的? 开始讨论这个问题之前,我们先来了解一下基本动画旋转。css3中的旋转有绕x轴、绕y轴和绕z轴旋转三种,坐标系如下图: 如果非要举个例子的话,体操运动员的单杠运动是绕x轴旋转: jolin姐姐跳钢管舞是绕y轴旋转: 旋转飞刀的特技表演是绕z轴旋转: 由坐标系和图图可以看出,z轴是垂直于屏幕的,绕z轴旋转是在平行于屏幕的平面上旋转,因此旋转是2D的,旋转的属性是rotate();而绕x轴和y轴旋转是在垂直于屏幕的平面上旋转,是3D的,旋转的属性分别是rotateX()和rotateY()。 回到主题,我们动画中的前后景翻转,实则是绕着x轴旋转90度。初步测试时,设好了旋转的属性和角度值,前后景可以翻转了,但是却毫无立体感可言,不是从地面上“翻”起来,而像是从地面上“冒”出来似的,纵深方向上(即z轴方向)没有距离感。查阅资料后发现,原来3D效果是要设置透视参数的(没有透视,不成3D),常用的两个透视属性如下: perspective:设置镜头到元素平面的距离(所有元素默认都放置在z0的平面即屏幕上)。比如perspective(500px)表示,镜头距离元素表面的位置是500像素。此时你看该元素,就好像你的眼睛距离该元素500像素远时看到的效果。示例如下: 原图: 不设透视时,元素绕y轴旋转45度: 透视距离设为500px时,元素绕y轴旋转45度: 有图有真相,这下明白了吧?不过,透视距离到底设多少才合适呢? 各位看官想想,既然镜头模拟的是我们的眼睛,那么,我们的眼睛距屏幕有多远,是不是透视距离就该为多少呢?答案是肯定的。鉴于目前主流的屏幕分辨率在16801050上下,而眼睛距离显示器的距离大约为1。2个显示器的宽度,故透视距离大致应设为1680px1。22016px2000px。 perspectiveorigin:规定镜头在平面上的位置,默认放在元素的中心。 示例如下: 在我们的动画中,透视距离perspective设的是2000因视线垂直屏幕即可,故不需设置perspectiveorigin。 2。2Safari穿透bug Safari下图片会透过图片穿过来,就像电影里,鬼可以穿过人的身体一样。难道,真的见鬼了?!! 版本首次发布后,发现Safari下前景会穿过后景翻转起来(线上存在几个小时,有同学可能还记得当时的现象)。检查动画的实现方式,没有问题;检查图片的zindex,也正常;而且同为Webkit内核,Chrome下完全正常,只有Safari有此问题(我了个去,Safari是不是Webkit家族的呀,血统不正啊)。理论很丰满,展现很骨感;同内核不同表现;唉 阿拉水平有限,没有找到根本原因,最终采取了一种伪方法来解决: 将后景图在z轴方向上向着屏幕内平移一定距离,使前景和后景图贴在地面上时不会有叠在一起的部分,简单示意如下: 原图: 平移示意图: 平移后前后景是不会交叠在一起了,但后景图片变小了(沿着z轴向屏幕内,渐行渐远,渐行渐小),需把它恢复正常大小才行啊,肿么办?缩放属性scale()。平移后图片缩小至原来的多少分之一,我们就把它通过scale属性再放大多少倍。 用代码说话:transform:translateZ(350px)scale(1。17,1。17); 这样,前后景图贴在地面上时不会交叠,翻转时自然就不会穿透了。 2。3动画不流畅,怎么办? 元素移动的动画怎么实现,如果不流畅怎么办?用飘柔吗? 动画中实现元素的移动,通常有两种方法,一种就是我们熟知的绝对定位,即将要移动的元素绝对定位,然后通过topbottomleftright值来控制元素的动态位置;另一种是css3动画中专有的移动属性translate。 首页动画中文字的坠落和移出,最初是通过绝对定位后调整top值实现的,如坠落部分的动画代码: 后发现动作有些许的咔,调整时间和位移值后依然无效,换用translate后流畅了许多: 备注:已为元素设置默认状态:{position:top:600} 关于定位(top等)和位移(translate),就我目前的经验来说,translate在流畅度方面要好些,而且,移动的速度越慢,translate在流畅度方面的优势就越明显。但是,Firefox对translate的支持不是很好,某些速度下会像流星一样拖着长长的尾巴。So,究竟何去何从,还请各位具体问题具体分析,测试后再行定夺。 2。4Firefox和IE10不能触发重播动画?! 动画隐藏后再显示,Firefox和IE10下不能触发重播动画,点解? 如大家所见,我们的动画是4幅轮播的形式,当前播放的只有1幅,对于当前没有播到的动画,需将其隐藏起来。如果是你,你会怎么隐藏?用我们惯用的hide(display:)吗,播放时再通过show(display:)将其显示出来?这样可以吗?当然可以理论上!实际上,Firefox和IE10下,若将节点hide后再show,是不能触发重播动画的。 好吧,退一步海阔天空,最终通过透明度来控制动画容器节点的显隐。 3。差异化体验 支持动画的浏览器有Chrome、Safari、Firefox和IE10,对于不支持动画的浏览器,采取差异化体验,仅将图片淡入淡出。 Part4:我如此飞奔,就是为了让你慢下脚步(性能优化) 1。首幅特殊处理 第一副图片的动画播放时,页面往往还在加载资源,这时动画就会出现不流畅的现象。怎么处理呢?先出背景,让banner有个可以看的画面,待首屏加载完毕后再开始播放动画。 2。延时加载 为了实现动画,一张图片被切成了45张,4幅下来,将近20张,虽然图片压了又压,总大小也500k有余了。如果网速低的话,全部加载完毕菊花都转疼了,带着拯救菊花的愿景,我们开始折腾了: 除第一幅动画所需的图片外,其他动画所需图片延时2s加载。你可能会问,那会不会播放到某幅动画的时候,或者用户点了某幅动画对应的轮播按钮时,该动画所需资源还没加载到啊?恭喜你,问对了会!如果这个时候该播的动画资源还没加载到,banner就要空白了(如下图),怎么办呢? 不怕,道高一尺,魔高一丈,哪里有问题,哪里就有解决方案: 为了优化体验,出现这种情况时,需让动画暂时停留在上一幅的状态,待相应动画的资源加载完毕后再切换。可问题是,css3中的动画播放完毕后,是会回到动画播放前的状态的,而非停留到动画最后一帧的状态。据前文“Firefox和IE10不能触发重播动画?!”部分所述,动画播放前整个动画容器是通过透明度隐藏的,是不可见的,那么,“让动画暂时停留在上一幅的状态”只能是YY了。 就这么放弃吗?不!绝不!动画特性不支持,我们还有伪方法: 将动画拆分成in、out两段将动画拆分成in、out两段,其中in包含两个状态:进入和停留,将in的时间设置得很长(通过帧控制使进入时间不变,只是停留的时间长了,如将in设为50s,其中进入0。5s,停留49。5s),out时长不变。若到了轮播切换(周期为10s)的时候,或者用户点击了某轮播按钮时,如果下一幅要播放的动画素材已加载完毕,则js将动画切换至out状态,否则继续停留,直至下一幅播放动画的素材加载完毕才切换。(有点滑动门的赶脚,不过是时间方面的,有木有!) 以背景淡入淡出为例,动画方面代码说话: 拆分前: 拆分后: