blogs
blogs copied to clipboard
我理解的前端动画
主题分享(我理解的动画)
撇开技术去理解前端,前端实际为布局、行为/交互、资源和数据、跨端和兼容这四大类。
所以心血来潮之下想另开几个大坑,去整理和表述出自己现在所能构想到的前端蓝图。
本系列包含动画、布局、交互、媒介四个方面,分别梳理我所理解的前端。
前言
在 Behance 2020 设计趋势中有描述,2020 年度趋势为 Motion Design & Animations。
原文:https://mp.weixin.qq.com/s/EvtTSCkN6IxcY1nw1oePRA
伴随 5G 的来临,前端也需要更多思考交互响应与性能问题,
低延时下能解决大多数加载问题,就算本机性能差,也有云设备同步方案。
当不再有 loading 时,突然地数据显示变化是否会显得突兀呢。
在 imgCook 这类弱 AI 应用崛起时,网站开发者可以如何突围。
本文以动画为切入点,尝试探究整理其概念与意义。
前端动画的价值
首先,我想先理清交互的含义,它的概念很大,也可能存在些误解。
理清它有助于理解动画在交互中的作用。
交互,即人机交互,不同于机器反馈的单方面运行,
就好比输入输出中的输入不只有函数的变量传入,还有用户的操作行为带来的输入。
其实可见,交互设计并不是艺术设计,美感那是界面设计的事情(即下篇布局)。
交互更侧重于用户行为上的考量,通常也是分析大于设计,其实非常工程学。
而动画一定程度上是同时为美感和行为赋能,
你可以给按钮加上小动效,让画面更灵动,也可以为交互服务引导用户操作。
这是我理解的前端做动画的价值。
程序员通常是一个差的设计师和差的管理者。 —— 交互设计之父:Alan cooper
之后将介绍动画类型分类、如何实现动画、以及动画设计原则,与君共勉。
单动画
最基本的动画构成,只需要 起始态,结束态,时长 和 节奏
function anim(start, target, duration, options = {}) {
let time = +new Date();
const every = options.every;
const cubicBezier = options.cubicBezier;
const finish = options.finish;
(function loop() {
const t = +new Date() - time;
let per = cubicBezier ? cubicBezier(t, duration) : (t / duration);
const res = start + per * (target - start);
every && every(res, per);
if (per >= 1) return finish && finish();
requestAnimationFrame(loop);
})();
}
示例:https://codepen.io/foreverZ133/pen/QWwWRVY
假如结束态如果是跳跃式的怎么办,比如从屏幕右侧滑出,却从屏幕左侧出现。这是我没有整理进去的。
可见这确实只是我个人的动画观,并不见得正确,所以过程中有其他想法可以随时说出来。
目标思维和过程思维
其实这也能看出动画的两种思维方式,
起止数值与业务有明确关系,从何开始从何结束即为元素实际表现;
起止数值只与时间有关,其实只是想获得已运动的百分比,与元素现有状态无关。
普通的起点到终点用目标思维会很简便,只需要把 now 值赋上去就行了,
但如果要实现跳跃式动画,如下,从 50-250 重复 5 次的效果
(先不管写进 finish 回调的拓展性功能哈)
示例:https://codepen.io/foreverZ133/pen/eYmmjNm
// 基于目标值的运算
var every = (now) => ($el.style.left = 50 + (now - 50) % ((1050 - 50) / 5) + 'px');
anim(50, 1050, 3e3, { every });
// 基于运动过程的运算
var every = (now, per) => ($el.style.left = 50 + (per % 0.2) * 1000 + 'px');
anim(0, 1000, 3e3, { every });
TweenJS:http://www.createjs.cc/tweenjs/docs/modules/TweenJS.html
jquery.transit:http://www.jq22.com/demo/jquery.transit-master20161220/
对比两类插件的使用,目标思维使用更为便捷,过程思维更为灵活。
单独讲讲 cubic-bezier
cubicBezier(t, start, changeBy, duration, a, b, c, d)
其中,t 为 nowDate - startDate,changeBy 为 target - start,abcd 为两个曲线句柄。
曲线句柄即为两个曲率标记点,可见下方 CSS 式节奏 的效果。
而 js 式的就是其曲线函数。至于两者怎么转换,我还暂时没研究。
CSS 式节奏:http://yisibl.github.io/cubic-bezier/
JS 式节奏:https://cdn.bootcss.com/jquery-easing/1.4.1/jquery.easing.js
https://codepen.io/foreverZ133/pen/NWPPzvY
可见,节奏实则为时间与变化量的关系,在数学的坐标系中即为各种曲线。
动画链
动画链包含:间隔/延时、暂停、反转、重复 和 同时动画/动画组
示例:https://codepen.io/foreverZ133/pen/LYEYKEj
图形动画
这里不加入线条动画的讨论哈,我个人感觉会比较难讲,仅论述图形就好。
图形动画的本质其实就是多个单点动画,只是点的存储方式可以有些不同。
这个过程其实非常复杂,比如从三角形变四边形从三个点出发会有三种不同的动画。
暂且不论这种,单说图形就是一个整体元素的类型。
CSS 是一个 transform 怼上去就行了,让人觉得很简单,但其实这其中还能有些思考。
比如之前分享的 FLIP.js,或者 rotate 180° 后再 scale 的诡异表现。
对称中心问题
https://forever-z-133.github.io/demos/single/edit-size-box2.html
而旋转到颠倒后再缩放的诡异表现,则是原本的对称中心变更了。
对称中心在图形动画中会产生相当大程度的影响,所以动画过程中不容忽视。
其实也很容易发现,图形每多一维就会多一个对称中心。
比如三维世界里,除了物体本身的对称中心,还会多一个世界中心,也就是摄像机视点。
结果反推过程
FLIP 动画与传统 transition 动画的区别就在于,
举个栗子,transition 式的动画,是先计算该帧的 rotate 值,再反推该帧各点的位置。
而 FLIP 动画则是先得到最终 rotate 值对应的 matrix 值,然后每帧只需要乘以 matrix 相关值就行了。
很明显,FLIP 动画性能会更佳,但需要一点数字知识才能完成改造。
另一方面,FLIP.js 将动画从 css 中抽离到 js 中,css 只管状态结果,动画由 js 补充_(与上文的 Tween 也不同)_。
这也还是目标思维与过程思维的不同,在这个对比中得到充分的展现。你品,你细品。
(当然,现阶段并不支持反推旋转/斜切过程哈)
动画类型
当图形动画作为单动画时,以上概念就都会演变成某个起始值,
其实这合并了计算过程,比如四个点旋转 30 度,实则是将旋转角度进行动画,再计算点的位置;
当然也有另一种方式,直接计算旋转结果时点的位置,然后对点位进行动画。
可能用惯了 css 动画,方法二相对较少地被认知,
但相对来说性能更佳,也是 matrix 性能更佳的原因之一。
其他的动画也是相似的,图形动画中会被抽象成某个特定的值去进行动画,
比如渐变肯定不能由我们去处理每个点的动画吧。有利有弊,仅思维上要认知到还有第二种方式。
然后再进一步合并动画类型,就会出现大家熟悉的名词了,
比如:晃动、闪烁、翻转、弹簧 等等。
动画的其他影响因素
当查看其他动画效果的源码时,你会很容易发现还有很多变量来影响动画节奏。
比如:摩擦(friction),节制(dampening),重力(gravity),惯性(inertia) 等等。
示例:https://forever-z-133.github.io/demos/single/coolHover.html
动画的触发
在淘宝大佬 winter 的图形三部曲的 bindingX 中,有着 手势、动画、滚动、陀螺仪 这种类型。
https://alibaba.github.io/bindingx/guide/cn_guide_base
仔细回忆一下,关于动画的触发应该会分为两种,即时反馈式动画 和 播放式动画。
其实还有 条件式动画,实为反馈过程中满足某条件产生的,也算是及时性动画的一种。
播放式动画也算是一劳永逸,未来应该还会有更多的及时性动画出现,比如视频播放/VR等 。
元素组动画
即多个元素都要进行动画,但它们之间就会有着一定的规律。
比如,拖动 A 则 B 也动,或者拖动 A 则 B稍后再动 之类的。
可以总结为 相似、相反、延时、减弱、**其他 ** 这几类联动形式。
https://mp.weixin.qq.com/s/54acdnB6QQltm9vMcKpYpw
动画设计原则
什么样的动画才算是好动画呢,虽然 UX 设计并不属于前端范畴,但我个人一直很想探讨这方面。
很多时候都是别人想好了效果丢给前端去实现,但大多公司都不见得有 UX 设计这个岗位或概念,
或者当在做个人项目的时候,干巴巴的跳转和框架默认动画,都不够酷炫不够装逼,
想做类似 https://www.figma.com/ 这样的 IDE 的话。
国内可借鉴的案例并不多,那动画思路从哪来,怎么做好动画,这便是设计原则。
或者说,已成文的规律性总结,能帮我们更好地去理解自己正在做的事情。
流派壹
迪斯尼工作室的电脑角色动画 12 原则
其实没啥关系,看着乐下吧
- squash & stretch(挤压和拉伸)
- anticipation(预见)
- staging(分镜、风格、关键位置)
- straight ahead & pose to pose(连贯和关键动作)
- follow through & overlapping(跟随和叠加)
- slow in & slow out(渐快和渐慢)
- arcs(弧形运动)
- secondary action(附属动作)
- timing(节奏)
- exaggeration(夸张)
- solid drawings(手绘)
- appeal(吸引力)
流派贰
Material Design,谷歌对操作系统制定的设计语言
相关视频:https://www.youtube.com/watch?v=rrT6v5sOwJg&list=PL8PWUWLnnIXPD3UjX931fFhn3_U5_2uZG
主要文档:https://www.material.io/design/motion/understanding-motion.html
Informative(内容丰富) & Focused(有主体的) & Expressive(富有表现力的)
有反馈 & 有提示 & 表达有连续性的 & 有个性符号 & 运行是一致的
流派叁
iOS design,美学完整性,一致性,直接操作,隐喻,用户控制
相关视频:https://b23.tv/av66343171
主要文档:https://developer.apple.com/design/human-interface-guidelines/ios/overview/themes/
非线性动画,可交互的 & 可中断的 & 可重新定向的 & 可随时响应的
理解和实践
播放式动画,可以逐步积累动画模板,后期要考虑的就只是节奏和触发实际了,
同时也有着 FLIP.js 这类工具的存在,播放式动画也有不同的思维方式来制作播放式动画。
而即使反馈式动画则要考虑得多一点,如何抽象动画变量,如何计算或反推关键点结果,
比如像做个滚动回弹,行为上有点像甩溜溜球,那么就有甩力/拉力,然后反推加速度,再反推位移 之类的。
再往后,像 anim 方法可以按已有逻辑进行拓展到很美妙咯,
其次 bindingX 的模式也可以很好的借鉴过来,
再者哪怕不做前端,玩玩抖音,玩玩视频特性,也是很棒的。
哪怕这些都并不见得真的会用,但却让我有了很多奇思妙想。
在 imgcook 基础上,有两版设计稿,绑定上对应关系,结合 FLIP 和 bindingX,连动画也能 AI 做了。
在 vue 中有个 Transition
组件,非常棒,但 react 的现在还不太 OK。
vue 的 transition-group 是真的很棒,查看文档。