【CSS3动画思维系列】时间轴动画

【CSS3动画思维系列】第二篇,第一篇《【CSS3动画思维系列】GIF转CSS3优化》,上篇挖了个坑:

再如果,在这个场景还想制作其它的动画,比如这笔 是从哪来,在干什么,要去哪里,笔生三连?
转化为人话,即是 考虑元素的入场动画,循环动画,出场动画,它又可以怎么去表达呢?

用自己的理解来表达的话,就是:剧本 应该怎么写,而这次刚好有个项目活动,就是一个比较长的剧本,SO,我填坑来了...(如果觉得文章写得不错的话,可以关注我的博客 陈在真 偶尔写写随书笔记,疑难杂bug~)

说到电影,一般会联想到 摄影、场面调度、剪辑、声音、表演、故事、编剧、意识形态构成,而制作一个H5,可以理解为制作一部电影,整个体验流程,与剧本相呼应,这个故事感不感人,最终表现为转发留存转化率,交互体验流畅可以提升用户的留存,而体验只是一个表达方式,跟故事本身是两码事,怎么将两码事结合在一起,就成了程序猿应该考虑的事情。

按惯例,先上体验链接(常规手机机型适配):体验传送门

loading进入后通过滑屏操作,滑滑滑,讲一个叙事故事,接着民国与现代的对比,然后切出选择层,选中item后,出现分享卡片,引导用户分享。

太直白了有没有,一点技术情怀都木有,那我们换一种解析方式:
当用户进入到H5后,授权跳转回归,回到Loading页面,页面底板跟后续的背景一直延续,所以这里的背景处理,采用渐隐渐显,效果如下:


loading

代码如下:

@keyframes a_loading-bg {
    0%{ opacity: 0.3; }
    25%{ opacity: 0.1; }
    50%{ opacity: 0.8; }
    75%{ opacity: 0.2; }
    100%{ opacity: 0.3; }
  }

看起来很普通的建议渐显,只不过尺寸做了手脚:

background-size: 105% 110%;

背景图尺寸放大,跟原尺寸产生视差,上层渐隐的时候,就出现了斑驳闪动的效果;
而Loading后面的 “...” 则是通过延迟循环视差:

@keyframes a_loading-txt {
    0%{ opacity: 1; }
    50%{ opacity: 0.2; }
    100%{ opacity: 1; }
  }

.txt-2{
  animation: a_loading-txt 1.6s 0.4s ease-in-out both infinite;
}
.txt-3{
  animation: a_loading-txt 1.6s 0.6s ease-in-out both infinite;
}
.txt-4{
  animation: a_loading-txt 1.6s 0.8s ease-in-out both infinite;
}

当loading结束后,loading层渐隐消失,与首页层呼应,首页层元素再按序显示,避免一次同时显示整个画面,就像电影一样,用户需要挨个消化角色,凹凸曼需要挨个打怪,效果如下:


loading切换到index

动画层次的切换,通过 loading-hide 与 wrap-show 类名权重控制,动画通过类名触发,元素隐藏即停止动画,避免隐藏元素消耗无谓性能,基础动画就不多添赘言了,mask操作还是可以说下的:


主标题mask动画

具体图片如下:
mask切图

mask可能会出现跨域的问题,可以转成base64直接引入解决:

mask: url("data:image/png;base64,xxx");

注意带上mask-size这个小跟班,便可以做到自定义形状蒙版的效果,mask平时还可以用gradient来使用,具体可以度娘一下;

主页入场后,需要滑动浏览页面故事,与往常滑动滚屏方式不同的是需要手指拖动控制动画进退,即通过手指拖动进度条的感觉,采用的是 TweenMax ,打了一个TimelineMax绑定Slider模块制作动画时间轴,主轴完成后便是往上面 K帧 打关键点位,也就是按剧本安排元素的动作,我称之为:元素的进场,循环,出场。

最常见最直白的 进场,莫过于 block,循环保持,出场莫过于 none,
渐隐渐显的话,出场则是opacity 0~1,循环保持,出场opacity 1~0,transiton状态修改刚好,
如果加上animation,Tween缓动的话,元素的动作将会变的多元化,因为keyframe里面可以有无限的可能,
不要元素一出来就给个v-if -show,或者给<transiton> 把结构跟样式绑太死,类名控制其实可操作性会更强些。

时间轴中故事区域滑屏的效果如下:


故事线动画

TimelineMax只是提供了滑动距离与时间轴的呼应,手指一放,就停止,显的 有点不太友好,所以对其增加了一个惯性滑动的计算,大致算法:获取手指touchstart的位置与时间,touchend的位置与时间,得到位移距离与时间差,可以获取到手指离开屏幕时的速度,如果速度超过某个阈值,则判定用户是滑开,不是放开,给予时间轴一个衰减的参数,参数根据划屏速度衰减到0,实现惯性效果如下:


正常情况下滑动

惯性参数调整为10倍后,chua chua chua效果如下:


惯性10倍下滑动

回到剧本,首页标题区域占据了大幅的屏幕比例,所以title需要上移减少占比,元素逐个消失,腾出空间切换故事stage内容,元素Timeline一般以Y轴做渐隐偏移,元素时间做差值 即 -=0.1 处,制作视差效果,比如某个代码如下:

threeDTimeline.fromTo(abc, 0.3, {
  y: 20,
  autoAlpha: 0,
}, {
  y: 0,
  autoAlpha: 1,
}, '-=0.1');

表示元素由Y轴从下往上(回归原位),透明度从0~1渐显,具体其它写法大部分跟CSS3呼应,可以参考上面链接查看API文档

至于元素的进场顺序,故事线stage的排序是 标题 - 背景 - 主体,主体在TweenMax的入场出场基础上,做CSS3动画循环,避免画面在用户手指停止时完全静止太过干燥,动画需要用step帧式动画,用正常linear ease会有过渡的渐隐渐显(就算是49.9~50%套路,也会闪动),具体效果如下:


人物帧动画

具体代码如下:

.stage-1 .human{
  animation: a_human 2s 1.1s steps(1) infinite;
}

stage2与stage1类似,stage2与stage3的过渡手的动作需将transform-origin设置在5% 95%做rotate,在手即将消失时,stage3元素做缩放位移进场,transform-origin设置在65% 10%,具体效果如下:


场景3动画

具体代码如下:

threeDTimeline.fromTo(a_stage3, 0.6, {
  scale: 1.5,
  x: -20,
  y: 50,
  autoAlpha: 0,
}, {
  scale: 1,
  x: 0,
  y:0,
  autoAlpha: 1,
}, '-=0.6');

只不过在stage3容器进场的时候,子元素也依次渐隐进场,只做透明度变化,不做位移,因为容器已经在位移,子元素的位移反而显得累赘,人物主体归位后,纸屑与slogan进场,肯定是要坐稳了才派传单喊口号的是伐,纸屑进场代码如下:

threeDTimeline.fromTo(a_paper, 0.6, {
  scale: 0,
  autoAlpha: 0,
}, {
  scale: 1,
  autoAlpha: 1,
}, '-=0.5');

纸屑没有做位移进场,而是缩放进场,一丢丢从小变大,回拖时从大变小,还是挺卡哇伊的涅~
stage4的切换跟stage1的human主体一致,图片帧step切换,只不过最后一帧发现画面还不够满,所以做了个scale放大渐隐的调整过渡到image-area切换对比区域,story stage四屏引入至此结束,image-area切换效果如下:


图片模块切换动画

image-area内元素剧本切换顺序按 背景、主体、标题、详情,旧背景与主体做视差滚动,沿Y轴从下往上渐显,归位后,标题从上往下弹性出现,稍作停留后弹性出场,新背景视差切换,主体则定位渐隐切换,不做视差滚动,主体切换完毕后,新标题弹性出现,详情文案渐隐弱化出现;依次进行3屏对比屏切换,直至最后渐隐出现跳转按钮,时间轴动画结束。具体效果如下:


选择层动画

这里有个纠结的地方,是否要用按钮来实现跳转,还是滑动到最后直接跳转?
按钮跳转,用户多一步操作,可能导致转化率变低,而直接跳转,用户如果是手抖滑走到下一屏,则不能返回时间轴动画?

选择页可以随机选择盲盒,点击触发step帧动画,TIPS: 如果首次加载发现单图片切换background-image出现step动画图片闪动的话,可以合并雪碧图后切换background-position,step就正常不会闪动了;

点击守护按钮后,出现分享卡层,如果用户是手抖点了,或是出现的卡片不喜欢,想重新选择,可以戳 重选一次 ,或者背后蒙版 渐隐返回到盲盒页重选,最后两个按钮则是引导分享与渠道引导,调整到 腾讯医典问诊医生,而保存下来的卡片二维码是该H5的地址,分享引流实现H5分裂闭环,至此整个H5剧本完结。

每个页面元素都有其各自的生命周期,所有元素都在同一个舞台上面进行着各自的生命周期,怎么安排好各自的生命周期,让它们有序且相互配合,这便是创作了一个剧本,如果页面出现了卡顿,或者体验不流畅,也许,是剧本中元素的出现了干扰,当捋顺了剧本,也就捋顺了页面。

Keyframe里可以有无限的可能...

-- 陈在真

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容