准备工作
为了能更容易理解,在开始之前,我们要先达成4个共识。
这 4个共识 是
唱 跳 rap 打篮球
... 咳咳咳 不好意思,跑题了
下面 真的开始了 :
1. transition 和 animation
让我们回忆下是怎么用使用动画的:
(1)transition
.foo { width: 100px; trantions: 1s; }
.foo:hover { width: 120px;}
设置元素 两个不同的状态 和 过渡的时间。
当我们触发变化,浏览器看到样式变化之后,为我们创建动画
(2)animation
@keyframes cardaniIn {
0%,
39%,
100% {
-webkit-animation-timing-function: cubic-bezier(1, 0, 0.47, 1);
animation-timing-function: cubic-bezier(1, 0, 0.47, 1);
}
0% {
-webkit-transform: rotateY(0deg) scale(0.8) translate3d(0, 0, 0);
transform: rotateY(0deg) scale(0.8) translate3d(0, 0, 0);
}
39% {
-webkit-transform: rotateY(0deg) scale(0.8) translate3d(0, -50px, 0);
transform: rotateY(0deg) scale(0.8) translate3d(0, -50px, 0);
}
100% {
-webkit-transform: rotateY(180deg) scale(1) translate3d(0, 0, 0);
transform: rotateY(180deg) scale(1) translate3d(0, 0, 0);
}
}
animation 允许我们写多个状态值,为我们解锁了一次告诉浏览器多个状态变化的能力。
共同点就是,
告诉浏览器我们想要的样式,并让浏览器看到样式的变化。
浏览器看东西的方式和我们不太一样,
浏览器一秒有很多帧,每一帧浏览器都会做很多事情,
其中包括计算style的变化,
2个帧之间
因为我们的修改 导致 元素的样式不一样的时候,浏览器就看到了样式的变化,并创建动画。
我们要达成的第 1 个共识就是:
我们创建动画,实际是在告诉浏览器 不同帧之间 元素样式的变化。
2. 动画尽量只用 transform 和 opacity
浏览器1s有很多帧,每一帧浏览器都会做大量的工作。
其中 layout 重新布局 paint 绘制 是最耗时的两个工作。
transform 和 opacity 的只会触发 composite合成的这一个步骤,
了解这一点 是我们创建流畅动画的关键
我们要达成的第 2 个共识就是:
动画尽量只用 transform 和 opacity
3. display 和 visibility
display:none;
和 visibility: hidden;
都会让元素不可见,
(1)display:none;
不可见,不占据空间,更彻底,会把元素从render tree移走,发生一次重排。
(2)visibility: hidden;
让元素视觉上不可见,并且不可点击交互。但是仍然占据空间,可以获得位置等相关信息,切换visibility不会发生重排。
所以在特定的情况下,比如我们将要写的动画中(下面会说,需要元素不可见,但是需要位置信息),可以用visibility: hidden;
来隐藏元素。
我们要达成的第 3 个共识就是:
可以考虑用visibility控制元素的显隐
6. 996 的压力会让人数学和记忆能力变差
FLIP
让我们开始吧
我们把动画分成2个部分,第一个部分,整体的位置和大小变化
还记得我们的第 1 条共识吗,
我们创建动画,实际是在告诉浏览器 不同帧之间 元素样式的变化。
现在一样,这个动画包括宽高和位置变化,我们需要告诉浏览器2个帧的 width offsetTop offsetLeft
FISRT
获取第一帧的样式
var fisrtDom = params.fisrtDom;
var fisrtReact = fisrtDom.getBoundingClientRect();
console.log( fisrtReact )
LAST
获取最后一帧的样式
var lastDom = params.lastDom;
var lastReact = lastDom.getBoundingClientRect();
console.log( lastReact );
Invert
现在让我们计算两个状态的差值,并把差值应用在要动画的元素上。
还记得我们的第 2 和 第 3 条共识吗,
动画用 transform ,元素的显隐用visibility
所以这里我们用的是 transform 和 元素的显隐用visibility。
play
最后,让它动起来吧。
当我们 取消 transform 的值的时候,元素的transform将会变回 默认的 translate3d(0,0,0) scalce(1),
浏览器看到样式的变化 和 transtion 就会为我们创建动画了。
实际上,这是一种叫做 FLIP 的技术。
first (第一帧) L (最后一帧) I (倒转) P (播放)
专门用于创建这种动画
第二部分动画比较简单,留给大家自由发挥。
web Animations Api
有一个叫做 web Animations Api 的api, 对我们创建动画有很大的帮助,
让我们能用编程的方式创建动画。
像我们的例子中,可以这样用
web Animations Api 最棒的地方在于, 能把动画实例保存起来,
我们在做卡片收起动画的时候,不用再次计算。
直接 animateInstance.reverse() 就可以反转播放动画。
web Animations Api 不是本文的重点,可以自行去了解一下 它 和 它的 poyFill 低版本兼容的插件。
参考资料
CSS动画你应该知道的10件事 www.yuque.com/cssconf/5th…
FLIP相关 www.w3cplus.com/animation/h…
FLIP相关 www.w3cplus.com/javascript/…
... ...
动画虽然完成了,但是由于 个人能力 和 项目的进度,
已经不允许我,去解决路由和分享页面的问题了,很遗憾,没上到正式环境
心塞,为了不拖项目进度,每天起早一个小时写这个东西,还是流产了。以后闲下来可以会再捡起来
... ...
这不是一篇严谨的教程,更多的是我个人的总结和分享,
文中可能会有错误遗漏的地方,请多多见谅,权当抛砖引玉。
加 coco 的qq群 418766876,一起交流鸭...
. . . 苹果的动画好细腻精致 . . .