动画
1.定义
- 由许多静止的画面(帧),以一定的速度连续播放时,因肉眼产生的错觉。
- 播放速度:每秒24帧(影视),每秒30帧(游戏)。
- 一个div从左向右移动的例子: 使用setInterval。
- 使用浏览器的paint flshing(右上角more tools =>rendering => paint flashing).发现重绘了(repaint)。
- css渲染过程依次包括布局、绘制、合成。其中布局和绘制可能会省略
性能问题,使用transform
- demo
- transform会自动脑补中间帧
- 没有repaint重绘,性能好
2.文档流相关
3.浏览器渲染原理
相关文章
浏览器渲染过程
- 步骤
- 根据HTML构建HTML树(DOM)
- 根据CSS构建CSS树(CSSOM)
- 将2棵树合并成一颗渲染树(render tee)
- Layout布局(文档流、盒模型、计算大小和位置)
- paint绘制(把边框颜色、文字颜色、阴影等画出来)
- compose合成(根据层叠关系型展示画面)
- 三棵树
如何更新样式
- 用JS更新样式
- div.style.background='red'
- div.style.display='none'
- div.classList.add('red')
- div.remove()
三种更新方式
- 第一种:全更新
- div.remove()会触发当前消失,其他元素relayout
- 第二种: 跳过layout
- 改变背景颜色,直接repaint + composite
- 第三章: 跳过layout和paint
- 改变transform,只需要composite
- csstriggers.com/ 所有属性
性能优化
1. css优化:使用will-change 或translate 2. js优化:使用requestAnimationFrame代替setTimeout或者setInterval. 3. 背下来就行
4.transform 全解
- 四个常用功能
- 位移translate
- translateX()
where = | ),加问号表示可以省略 - translateY()
- translateZ() 且父容器perspective
- translate(,?)
- translate(x,y,z)
- demo
- 经验
- translate(-50%,-50%)可以做绝对定位元素得居中
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>translate 50% 50% </title>
</head>
<body>
<div class="wrapper">
<div id="demo">
</div>
</div>
</body>
</html>
#demo{
width:100px;
height:100px;
border:1px solid red;
position:absolute;
left:50%;/* 左边缘处于黑框的中间 */
top:50%;/* 上边线处于中线 */
transform:translateX(-50%) translateY(-50%); /* 向左,向上回半个身位。中线对准 。可以缩写为transform:translate(-50%,-50%)。除了IE,是绝对剧中的完美答案*/
}
.wrapper{
border:1px solid black;
position:relative;
height:500px;
}
- 不会的看文档
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
#demo{
width: 100px;
height: 200px;
border: 1px solid red;
margin: 50px;
}
#demo:hover{
xtransform: translateX(50px);
xtransform: translateY(-50px);
transform: translateZ(-200px);
}
.wrapper{
perspective: 1000px;
border: 1px solid black;
}
</style>
</head>
<body>
<div class="wrapper">
<div id="demo"></div>
</div>
</body>
</html>
- scale 缩放
- scaleX() (number倍,如1.5倍)
- scaleY()
- scale(<number,?)
- 用得少,因为容易出现模糊
- rotate旋转
- rotate([ | ])
- rotateX([ | ])
- rotateY([ | ])
- rotateZ([ | ])
- 一般用360°旋转制作loading
- 代码
- skew倾斜
- 用的少
- 代码
- 代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class="wrapper">
<div id="demo"></div>
</div>
</body>
</html>
#demo{
width:100px;
height:200px;
border:1px solid red;
margin:50px;
transition:all 1s;/*加入动画效果,1s变大 */
}
#demo:hover{
/* transform:scale(1.5);hover上去,变为原来的1.5被 */
transform:rotate(45deg);/* 默认以垂直屏幕的轴转动 */
}
- 经验
- 一般需要配合transition过度
- inline元素不支持transform,需要先变为block
- translate(50%)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>translate 50% 50% </title>
</head>
<body>
<div class="wrapper">
<div id="demo">
</div>
</div>
</body>
</html>
#demo{
width:100px;
height:100px;
border:1px solid red;
position:absolute;
left:50%;/* 左边缘处于黑框的中间 */
top:50%;/* 上边线处于中线 */
transform:translateX(-50%) translateY(-50%); /* 向左,向上回半个身位。中线对准 。可以缩写为transform:translate(-50%,-50%)。除了IE,是绝对剧中的完美答案*/
}
.wrapper{
border:1px solid black;
position:relative;
height:500px;
}
- transform多重效果
- transform:scale(0.5) translate(-100%, -100%);
- transform:none ;取消所有
- 练习:跳动的心
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>跳到的心</title>
<style type="text/css">
*{
box-sizing:border-box;
padding:0px;
margin:0px;
}
#heart{
margin:100px;
position:relative;
/* border:1px solid black; */
display:inline-block;
transition:all 0.5s;
}
#heart:hover{
transform:scale(1.5)
}
#heart > .bottom{
height:50px;
width:50px;
/* border:1px solid red; */
background:red;
transform:rotate(45deg);
}
#heart > .left{
height:50px;
width:50px;
/* border:1px solid green; */
background:red;
border-radius:50% 0 0 50%; /* 四个值,试一下 */
position:absolute;
bottom:100%;
right:100%;
transform:rotate(45deg) translateX(31px);/* j具体需要试一下 */
}
#heart > .right{
height:50px;
width:50px;
/* border:1px solid red; */
background:red;
border-radius: 50% 50% 0 0;
position:absolute;
bottom:100%;
left:100%;
transform:rotate(45deg) translateY(31px);
}
</style>
</head>
<body>
<div id="heart">
<div class="left"></div>
<div class="right"></div>
<div class="bottom"></div>
</div>
</body>
</html>
5. transition过渡
文档
作用
补充中间帧
语法
- transition:属性名 时长 过渡方式 延迟
- transition: left 200ms linear ;
- 可以用逗号分隔两个不同的属性, transition:left 200ms, top 400ms;
- 可以用all代表所有属性,transition: all 200ms;
- 过渡方式有: linear | ease | ease-in | ease-out | ease-in-out | cubic-bezier |step-start | step-end |steps. 具体查文档。 linear:线性 ease:缓动
demo
并不是所有属性都可以过渡
- display:none => block没法过渡
- 一般改成visibility:hidden => visible
- background渐变:可以过渡
- opacity:可以过渡,但不建议用
- 过渡必须要有起始。一般只有1次或2次动画。如hover和非hover状态的过渡。
过渡有中间点怎么办
- 使用2次transform
- .a === transform ===> .b
- .b === transform ===> .c
- 使用setTimeout或者监听transitionend事件知道到中间点
- 使用animation
- 声明关键帧
- 添加动画
animation
- 一种是from, to
- 一种是百分比
@keyframes XXX{
from {
transform: translateX( 0% );
}
to {
transform: translateX( 100% );
}
}
@keyframes XXX{
0% {
top:0;
left:0;
}
30% {
top:50px;
}
68%, 80%{
left:50px;
}
100% {
top:100px;
left:100%;
}
}
- 缩写语法
animation:时长 | 过渡方式 |延迟 | 次数 | 方向 | 填充模式 | 是否暂停 | 动画名;
时长: 1s或者1000ms
过渡方式: 同transition取值
次数: 3 | 4.2 | infinite
方向:reverse | alternate | alternate-reverse
填充模式: none | forwards | backwards | both
是否暂停: paused | running
以上都可以单独设置,具体查看文档
- 如何让动画停止在最后一帧
答: animation加forward - 跳动的心重做
demo
重点
#heart{
margin:100px;
position:relative;
/* border:1px solid black; */
display:inline-block;
animation:heart 1s infinite alternate 800ms;
}
@keyframes heart{
0%{
transform:scale(1.0);
}
100%{
transform:scale(1.2);
}
}
- 跳动的心另一种写法
demo - 注意了解下transform-origin(www.cnblogs.com/nyw1983/p/1…)