动画原理
动画是由许多静止的画面(帧)以一定的速度连续播放组成,由于人的肉眼因视觉残像产生错觉,而错以为是活动的画面。例如影视画面以每秒24帧播放,游戏以每秒30帧进行播放。
简单实例
使用demo.style.left = n / 100 * 300 + 'px'做动画, 移动Div
- 配合使用
SetInterval每隔一小段时间移动Div,知道移动到目的点 - 移动过程中
CSS一直在绘制repaint,耗费性能
使用transform: translateX(300px)做动画,移动Div
- 需要配合使用
SetTimeout计时器,因为直接运行,会直接合成 - 并没有
repaint,性能要比上面的例子好
浏览器渲染过程
过程
- 根据
HTML构建HTML树,为DOM - 根据
CSS构建CSS树,为CSSOM - 将上面两棵树合并为一颗树,为
render tree - 进入
Layout布局,包含构建文档流,盒模型,计算大小和位置 - 进入
Paint绘制,绘制边框,文字,背景等等 - 进入
Composite合成,根据不同层,和层叠关系组合最终画面展示
三种更新方式
- 第一种, 全过程
例如div.remove()会触发更新,经历布局,绘制,合成全过程 - 第二种
例如div.style.background='red会触发更新跳过布局,直接进入绘制,合成过程 - 第三种
例如改变
transform: translateX(300px)将触发更新,跳过布局,绘制,直接进入合成过程
使用JS更新样式
- 设置
Div的背景色div.style.background='red' - 设置
Div为不展示div.style.display='none' - 修改
Div类的名称div.classList.add('red') - 移除
Div节点div.remove()
CSS动画优化
JS优化 使用requestAnimationFram代替setTimeout或者setIntervalCSS优化 使用will-change或者Translate
Transform
transform属性允许你旋转,缩放,倾斜或平移给定元素。这是通过修改CSS视觉格式化模型的坐标空间来实现的。
Translate位移
transltateX(<length-percentage>)translateY(<length-percentage>)translate(<length-percentage>,<length-percentage>?)translateZ(<length>)父容器为perspectivetranslated3d(x,y,z)top:50%;top:50%,translate(-50%,-50%)可以做到绝对定位元素的居中
Scale缩放
用法
scaleX(<number>)scaleY(<number>)scaleY(<number>,<number>)- 容易出现模糊
Rotate旋转
用法
rotate([<angle>|<zero>])rotateZ([<angle>|<zero>])rotateX([<angle>|<zero>])rotateY([<angle>|<zero>])- rotate3D
- 用来旋转
360度查看文档
倾斜Skew
用法
skewX([<angle>|<zero>])skewY([<angle>|<zero>])skew([<angle>|<zero>],[<angle>|<zero>])
Transform多重效果
transform: scale(0.5) translate(-100%,-100%);transform: none;
注意事项
- 通常需要配合
transition过渡 inline元素不支持transforme,需要先转化为block,再使用
Transition过渡
transition属性是transition-property,transition-duration,transition-timing-function 和transition-delay的一个简写属性
用法
用来补充中间帧
语法
transition: (属性名 时长 过渡方式 延迟);transition:left 200ms linear;transition:left 200ms, top 400ms; 使用逗号,分割不同的两个属性transition:all 200ms; 可以用all代表所有属性- 过渡方式有:
linear | ease | ease-in | ease-out | ease-in-out | cubic-bezier | step-start | step-end | steps
注意事项
并不是所有的属性都能过渡
- 当
display:none转化为display: block不能过渡 - 这种情况可以设置
visibility:hidden转化为visibility:visible backgound的颜色可以过渡opacity的颜色可以过渡- 过渡必须要有开始和结束,动画为一次或者两次,例如
hover和非hover的过渡
过渡中间点
除了上述情况,还可以设置过渡的中间点
使用两次transform
.a===transform===>.b.b===transform===>.c- 使用
setTimeout或者监听transition事件得知到了中间点
使用animation
- 声明关键帧
- 添加动画
Animation
语法1
@keyframes slidein {
from {
transform: translateX(0%);
}
to {
transform: translateX(100%);
}
}
语法2
@keyframes identifier {
0% { top: 0; left: 0; }
30% { top: 50px; }
68%, 72% { left: 50px; }
100% { top: 100px; left: 100%; }
}
缩写语法
animation: 时长 | 过渡方式 | 延迟 | 次数 | 方向 | 填充模式 | 是否暂停 | 动画;
- 时长:
1s或者1000ms - 过渡方式: 和
transtion取值一样,如linear - 次数:
3或者2.4或则和infinite - 方向:
reverse | alternate | alternate-reverse - 填充模式:
none | forwards | backwards | both - 是否暂停:
paused | running - 以上所有属性都有对应的单独属性