动画的原理
人脑的bug
定义
- 由许多精致的画面(帧)
- 以一定的速度(如每秒30张)连续播放时
- 肉眼因视觉残象产生错觉
- 而误以为是活动的画面
概念
- 帧:每个静止的画面都叫做帧
- 播放速度:每秒24帧(影视)或者每秒30帧(游戏)
一个简单的CSS动画例子
将div从左往右移动
- 一个坏处,setInterval计时器他不会停止
- 解决办法,替换成var id = setInterval·····,else{clearInterval(id)}
原理
- 每过一段时间(用setInterval做到)
- 将div移动一小段距离
- 直到移动到目标地点
注意性能
-
绿色表示重新绘制了(repaint)了。什么是绿色,在开发者工具里任意一个tap,按一下esc,点击出现的控制台左边三个点按钮,找到Rendering(渲染),勾选Paint flashing就能看到绿色了,代表在重新渲染
-
CSS渲染过程依次包含布局、绘制、合成
-
其中布局和绘制有可能被省略
-
拓展:换一个实现方式
css:
#demo:{
xxx
transition: all 1s linear;
}
#demo{
transform: translateX(200px);
}
js:
setTimeout(()=>{
demo.classList.add('end');
},3000);
结论就是,通过开发者工具可以看到这个动画过程只在起点和终点渲染了,中途没有进行渲染,是正面优化
浏览器渲染原理
- 掌握浏览器第一手资料,就去看谷歌、火狐等团队的文章
浏览器渲染过程
- 步骤
- 根据HTML构建HTML树(DOM)
- 根据CSS构建CSS树(CSSOM)
- 将两棵树合并成一颗渲染树(render tree)
- Layout布局(文档流、盒模型、计算大小和位置)
- Paint绘制(把边框颜色、文字颜色、阴影等画出来)
- Composite合成(根据层叠关系展示画面)
更新过程
- 一般我们用JS来更新样式
- 比如 div.style.background ='red'
- 比如 div.style.display = 'none'
- 比如 div.classList.add('red')
- 比如 div.remove()直接删除节点
- 加样式不如加类,因为写类效率更高
-
那么这些方法有什么不同吗
- 有三种不同的渲染方式
- JS>S>L>P>C 比如用了remove()
- JS>S>P>C 比如布局没变
- JS>S>C 比如用了transform
-
那么我怎么知道每个属性触发什么流程:自己一个一个尝试吧
-
这里有个网址 csstriggers.com查看,第一列是chrome,第二个是firefox,第三个是苹果,第四个是IE
前端高手不用left做动画
- 用transform
- 原理
- transform:translateX(0=> 300px)
- 直接修改会被合成,需要等一会修改
- transition过渡属性可以自动脑补中间帧
- 注意性能
- 并没有repaint(重新绘制)
- 比改left性能好
提升:CSS动画优化
没什么技术含量
- 答案都在Google写的文章里,谁看完谁牛X
JS优化
- 使用requestAnimationFrame代替setTimeout或setInterval
CSS优化
- 使用will-change或translate
没错
- 完全就是死记硬背
transform全解
最好的办法就是去看MDN
四个常用功能
- 位移 translate
- 缩放 scale
- 旋转 rotate
- 倾斜 skew
ps:可以用空格隔开组合使用
经验
- 一般都需要配合transition过渡
- inline元素不支持transform,需要先变成block
tranform之translate
常用写法
- translateX()
- translateY()
- translate(,?)问号表示可以省略
- translateZ()且父容器perspective
- translate3d(x,y,z)
经验
- 要学会看懂MDN的语法示例
- translate(-50%,-50%)配合top,left可做绝对定位元素的居中
tranform之scale
- 很简单,用的比较少,因为变形容易变模糊
tranform之rotate
常用写法
- rotate([<angle|<zero])angle是角度的意思
- rotateZ([<angle|])
- rotateX([<angle|<zero])
- rotateY([<angle|<zero])
- rotate3d太复杂,无法用语言表述
- 不能补全尖括号,掘金会吞掉
经验
- 一般用于360度旋转制作loading
- 用到时再搜索rotate MDN看文档
tranform之skew
常用写法
- skewX([<angle|<zero])
- skewY([<angle|<zero])
- skew([<angle|<zero],[<angle|<zero]?)
经验
- 用得较少
- 用到时再搜skew MDN 文档
transform实践:跳动的❤
源代码
心得
- CSS需要你有想象力,而不是逻辑
- CSS给出的属性都很简单,但是可以组合得很复杂
transition 过渡
作用
补充中间帧
语法
- transition:属性名 时长 过渡方式 延迟
- transition:left 200ms linear
- 可以用逗号分隔两个不通水性
- transition:left 200ms,top400ms
- 可以用all代表所有属性
- transition:all 200ms
- 过渡方式有: linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier|step-start|step-end|steps,具体含义要靠数学知识
注意
- 并不是所有属性都能过渡
- display:none=>block 没法过渡
- 一般改成visibility:hidden=>visible(不要问为什么)
- display和visibility的区别自己搜一下
- background颜色可以过渡吗?可
- opacity透明度可以过渡吗?可,不推荐
过渡必须要有起始和结尾
如果除了起始,还有中间点
两种办法
使用两次transform
- .a===transform ===>.b
- .b===transform ===>.c
- 如何知道到了中间点呢?
- 用setTimeout或者监听transitionend事件
使用animation
- 声明关键帧
- 添加动画
- 使用forward实现“不回去”
animation的keyframes 完整语法
- 标准语法
- 搜索keyframesMDN讲得很清楚
- 一种写法是from to
- 另一种写法是百分数
animation
缩写语法
animation:时长|过渡方式|延迟从|次数|方向|填充模式|是否暂停|动画名;
- 时长:1s或者1000ms
- 过渡方式:跟transition取值一样,如linear
- 次数:3或者2.4或者infinite
- 方向:reverse|alternate|alternate-reverse
- 填充模式:none|forwards|backwards|both
- 是否暂停:paused|running
- 以上所有属性都有对应的单独属性