前段时间大家有被《你的人格主导色》这个 H5 刷屏了吧
你的人格主导色-录屏
还没玩的朋友可以在云音乐 APP 搜索关键词「颜色测试」
或者 用云音乐 APP 扫这个二维码(不要用微信,被屏蔽了)
https://st.music.163.com/st-color-quiz (二维码自动识别)
今天我来和大家聊聊这个项目中动效设计是怎么落地的。这个 H5 从结构上来说很简单,8 个页面 8 道选择题,每个页面有一段声音,用户选择自己认为这个声音是什么,然后系统根据选择结果分析用户的人格「成分」并呈现在结果页。这里的动效也主要是每个页面内的动效和转场动效等几个部分。
页面内的动效,大部分是用一个带音频的视频作为背景动效,少部分用代码完成。这样的好处是如果背景动效需要修改,只需要调整视频内容,输出并替换资源就好,兼容性也是相对较好。
但是选项按钮部分,因为不同用户点击的不一样,就还是需要结合代码来做效果了。这里主要用到的是 CSS 动画。
我们先来看看翻页效果:
这个效果我们是模拟的幕布从一边被拉出并遮盖整个页面的效果,材质还是有点弹性的那种,这个形状是在 canvas 中绘制的,绘制方法其实和我们平时在作图软件里的原理一样,是由几段闭合的贝塞尔曲线或直线组成的形状:
//绘制从点 p1(x,y) 到点 p2(x,y) 的一段贝塞尔曲线 ctx.bezierCurveTo( p1(起始顶点)的控制点 2 的 x 坐标, p1 的控制点 2 的 y 坐标, p2(下一个顶点)的控制点 1 的 x 坐标, p2 的控制点 1 的 y 坐标, p2 的 x 坐标, p2 的 y 坐标);
形状的运动实际上就是构成它的顶点的运动,这块「布」是由这些点构成的:
在用户没有操作的时候,所有的点,包括 P2 的控制点,都贴着屏幕右边沿,这样构成的图形是一条看不见的线(P1、P5 重合,P3、P4 重合,且这四个点的控制点都是他们本身)。当用户点击操作之后,点 P2 先向屏幕左边移动,它的两个控制点也以相同速度移动,这时看到的就如上图般被扯出一块布的效果;P2 移动一段距离后,P1 和 P3 也开始移动,做出被「拉扯」出来的感觉,最后都移动到屏幕左边沿,然后 P2 再在水平位移上做几次回弹效果:
转场 demo:https://codepen.io/bigxixi/pen/yLMvmEL
其实一开始我们设计了可以用手拖拽翻页的效果,但由于一些音视频播放的兼容性问题,无奈简化成了点击触发~
拖拽翻页演示
我们再来看看页面里的动效。
这一页背景视频里的雨主要是用 AE 自带的 CC Rainfall 效果器制作:
三个选项按钮就是三张图片,点击之后「被选中」状态的图片透明度渐现覆盖掉黑字。透明度动画我通过定义 fadeIn 和 fadeOut 两个简单的动画 class,在点击的时候添加到对应的 dom 上就好了。
.fadeOut{
animation: fadeKey 0.3s ease 0s 1 reverse both;
}.fadeIn{
animation: fadeKey 0.3s ease 0s 1 normal both;
}@keyframes fadeKey {
from{opacity: 0;}
to{opacity: 1;}
}
详情参见:
下雨-选项 demo:https://codepen.io/bigxixi/pen/zYZVpWe
这一页,火焰背景同样是视频
主要通过 AE 里的「分型杂色」+「置换图」效果器模拟火焰动画。
而几个选项的动效则用 CSS+图片资源来完成。其中火焰拖尾是画好的一张图,我把图的锚点定在图片靠上的位置:
transform-origin: 50% 22.5%;
选项向上飞入画面的过程中做了个 Y 方向从 50%到 100%的缩放。当然还有透明度的变化。
@keyframes optionTileInAniP2Key { 0%{ opacity: 0; transform: scaleY(0.5); } 20%{ opacity: 1; } 100%{ opacity: 0; transform: scaleY(1); } }
三个选项用了三张 png 图片来呈现,虽然看起来是「黑字」+「红色影子」的组合,实际上图片资源用的是「红字」,在 CSS 里直接用 filter:saturate(0) 把它的饱和度降为 0,这样就呈现黑色了,而选项背后的红色影子,其实是用的图还是前面的同一张图,这时就不必着色了直接用本来的颜色,同时同样通过 filter 添加模糊和投影效果,也顺便降低一点透明度。
.optionShadow { filter: opacity(0.5) blur(0.5vw) drop-shadow(0px 0px 1px rgb(255, 155, 93)); }
这样就可以做到「字、影分离」——他们的浮动是有个微小的错位的——的同时只用到一张图片资源,而原图用红字的原因是把图中黑色部分填充为红色效果不好(至少我没试出很好的方法),但红色变成黑色却很方便。
详情可以参考 demo:https://codepen.io/bigxixi/pen/qBryRJM
我们再看看这一页
背景视频是个简单的三维物体旋转动画,用金属材质+环境光泽的反射渲染。
选项动画也很简单,每个选项我们拆分为选项(A、B、C)和内容描述,把他们的锚点定位到他们相接的线条上:
选项:
transform-origin: 100% 50%;
文字:
transform-origin: 0% 50%;
然后对文字添加一个 skewY 和 scaleX 的动画,它就看起来像是进行了一个 3d 旋转,被「按」进屏幕了。
颜色变深的效果,其实是同一层做同一个动画的纯色 div 在点击后叠加了一个透明度动画。
.optionChoosenAni{ animation: optionChoosenAniKey 0.5s cubic-bezier(.38,1.5,.5,1.01) 0s 1 normal both; } @keyframes optionChoosenAniKey { 0%{ transform: skewY(0) scaleX(1); } 100%{ transform: skewY(-15deg) scaleX(0.5); } }
详情可以参考 demo:https://codepen.io/bigxixi/pen/oNZrqYq
鲸鱼这个页面
背景视频部分我们主要使用了 AE 自带的 分型杂色 + 毛边 效果器,通过调整亮度、对比度,模拟科考船用声呐扫描海底的图像效果。
选项部分的背景是分别用了三张 apng 动图,而文字则是 CSS 精灵图。
在用户未做出选择时,精灵图静止于第一帧;用户点击对应选项后,精灵图动画开始播放,文字「散开」
.choosenAni_A{
animation: whaleOptionASprAniKey 1s steps(1) 0s 1 normal both;
}
@keyframes whaleOptionASprAniKey {
0% { background-position: 0 0; }
3.45% { background-position: -387px 0px; }
6.90% { background-position: -774px 0px; }
……
96.55% { background-position: -3096px -200px; }
100.00% { background-position: -3483px -200px; }
}
同时调整色相 filter:hue-rotate() 为背景动图「着色」
.chooosenBG_A{ transition: all 0.2s linear; filter:hue-rotate(120deg); }
详细可以看下 demo:https://codepen.io/bigxixi/pen/ZEedxJL
这个页面的背景视频里
布帘被风吹起动画使用了简单的 C4D 的动力学来完成
三个选项随风摆动的效果则是简单粗暴的用了三个 apng 动图
选项飘动的扭曲是用 AE 的「置换图」制作。
不过他们的飘入、飘出,以及选中的着色都还是 CSS 做的。这个「着色」动画也是用了之前火焰那个页面的小技巧,三个原图都是被选中后的橙色,默认未选状态使饱和度 filter:saturate(0) 和亮度 brightness(0) 设为零将他们变成黑色,选中后再回复成 1,这样就「变成」橙色了
.selectedAni_p6{ animation: selecetedKey_p6 0.2s linear 0s 1 normal both; } @keyframes selecetedKey_p6 { 0%{ filter: saturate(0) brightness(0); } 100%{ filter: saturate(1) brightness(1); } }
详情可以参考风吹-选项 demo:https://codepen.io/bigxixi/pen/OJpevEL
最后的这个页面
我们可以看到背景视频里有很多泡泡,首先在 C4D 里做一个简单的肥皂泡
然后给她加一个 displacer 变形器,用 noise 驱动制作变形动画模拟肥皂泡在空气中的挤压变形效果,并导出为一段循环的序列帧(注意渲染时间和 noise 中的循环时间对上)
然后在 AE 里导入这个序列帧, 复制多个,改变尺寸大小等让他们看起来各自稍微不同。这里我各自对他们的位移加入了随机表达式 wiggle
//循环 wiggle 表达式 loopTime = 10; //循环周期 freq = 0.5;//频率 amp = 25;//振幅 t = time % loopTime; wiggle1 = wiggle(freq, amp, 1, 0.5, t); wiggle2 = wiggle(freq, amp, 1, 0.5, t - loopTime); linear(t, 0, loopTime, wiggle1, wiggle2)
而泡泡的缩放则是先将音频的振幅转换为关键帧,再用表达式与缩放关联起来起来,并各自错开一点时间
vol = thisComp.layer("音频振幅").effect("两个通道")("滑块").valueAtTime(time-0.05*index)+90; [vol, vol*0.8]
这样泡泡们就看起来像是比较自然地被音频驱动而震动了。
而两个选项,是先把选项文字图片导入 AE 用 湍流置换 效果器模拟 C4D 中做泡泡时的扭曲动画,注意循环得勾上,后面就直接放上泡泡的序列帧,导出为 apng 动图。
点击之后的泡泡碎裂,则是如之前的鲸鱼那页,直接切到一个精灵图动画播放,因为模拟的泡泡破碎的效果,是一个瞬间的事情,所以这里就直接切过去了。
泡泡破碎动画主要是用了 AE 里的 「CC Mr.Mercury」这个效果器来制作。
详情参阅泡泡-选项 demo:https://codepen.io/bigxixi/pen/eYvwMwy
除了 CSS,有些动效还是需要 JS + Canvas 这个万能组合,除了一开始介绍的翻页效果外,有些页面里也在使用。这是表现力最丰富,相对来说门槛也比较高的一个方向,幸好有很多前辈高人做了很多 JS 库并开源给我们使用。比如键盘声这一页
这页主要用了 Matter.js 进行物体下落效果的物理模拟,可以看看 Matter.js 官网直接就有类似例子,我们只需要依葫芦画瓢替换成对应的视觉资源,控制物体下落的时机等参数就好。
Matter.js Demo · code by @liabru:https://brm.io/matter-js/demo/#sprites
这个页面的选项是藏在背景里的,点击之后实际上是换了张图片资源表示「按下」。
详情可以参考(演示版,选项只有 A 可以点)键盘-demo:https://codepen.io/bigxixi/pen/dyvBeoL
云彩这一页主要是前端同学在实现效果,具体细节讲解我就不越俎代庖了,有机会可以把话筒递给前端小哥哥哈
最后说下结果页,结果页会根据我们的选择,生成不同的关键词、文案及背景色动画
这里的背景色动画使用的是 GLSL Shader 动画,基本原理是根据用户的选择结果,生成一张渐变贴图(视觉同学绘制了很多渐变图,覆盖了每个关键词),贴图再经过 fragment shader 中的 noise 通过不同参数扭曲得到动画,这部分参考了 MartinRGB 大神的案例,详细原理可以参考他在 Droidcon 2019 上海站的分享:https://github.com/MartinRGB/Droidcon_Shanghai_Keynote/releases/tag/0.4
这里因为不同关键词也会对应不同的音乐,最初我们也是希望背景渐变动画能和音频有关联,实际上我也写了一些 demo:http://bethe.top/163/color-quitz-simplified/end.html
但由于一些兼容性问题,研发没有足够的时间来处理,而没有和音频关联的效果也可以接受(结果页最重要的还是关键词和对应的文案),最后没有用上。
好了,这个项目的动效部分大概就和大家分享这些,大家如果对最后的结果是如何生成的感兴趣,可以看下这篇文章:https://zhuanlan.zhihu.com/p/376712328
作为一个的动效设计师,我们除了设计动态效果,如何帮助研发将动效在产品中落地实现也是非常重要的一个工作内容,不然再好的设计最后只能沦为自嗨的空中楼阁,岂不可惜。
有的设计师可能想,这不应该是研发的指责吗?其实对于设计师,多了解一些动效实现原理也是有好处的。
一方面在设计动效方案时可以对实现难度有个预估,面对无法实现的可能性要有「优雅降级」的能力,不然不断返工折磨的也是自己;另一方面可以从更多维度作为设计出发点,有的效果设计师想破脑袋想不出来如何表达,研发那边可能就一行代码的事儿…
这是个不断妥协,也在不断突破自我的过程,在这个过程中我们可能更迷茫,但一拨开云雾,对设计对动效的认知也更清晰。
这个专题我也将分享这几年的项目里的一些落地经验,主要是 H5 项目,可能涉及到一些 web 前端的代码知识,由于我不是专业的程序员,有写的不对的地方,恳请大家不吝斧正,谢谢!
复制本文链接 文章为作者独立观点不代表优设网立场,未经允许不得转载。
热评 王亚洲