transform实现动画,transform中的四个常用功能
位移translate:translate(x,y),translateX(x),translateY(y)等
#demo {
width: 100px;
height: 100px;
border:1px solid red;
/* transition过渡属性可以自动补充中间帧 */
transition: all 1s linear;
}
#demo.end {
/* 元素在x轴方向向右平移200px */
transform: translateX(200px);
}
缩放scale:scale(x[,y]?)
#demo:hover{
/* 直接变大 */
transform: scale(1.5);
}
旋转rotate:rotate(angle)
#demo:hover{
/* 直接变大 */
/* transform: scale(1.5); */
/* 顺时针旋转 */
transform: rotate(45deg);
}
倾斜skew:skewX(angle),skewY(angle)
#demo:hover{
transform: skewX(15deg);
}
- 一般都需要配合transition过渡
#demo {
width: 100px;
height: 200px;
border:1px solid red;
margin:50px;
/* 加动画效果 */
transition:all 1s;
}
- inline元素不支持transform,需要先变成block
绝对定位元素的居中
#demo {
width: 100px;
height: 100px;
border:1px solid red;
position: absolute;
/* 以下三行为重点,绝对居中的完美答案 */
left:50%;
top:50%;
/* transform: translateX(-50%) translateY(-50%); */
transform: translate(-50%,-50%);
}
.wrapper {
border:1px solid black;
position: relative;
height: 500px;
}
<div class="wrapper">
<div id="demo"></div>
</div>
浏览器渲染原理
- 浏览器渲染过程:
- 根据HTML构建HTML树(DOM)
- 根据CSS构建CSS树(CSSOM)
- 将两棵树合并成一棵渲染树(render tree)
- Layout布局(文档流、盒模型、计算大小和位置)
- Paint绘制(把边框颜色、文字颜色、阴影等画出来)
- Compose合成(根据层叠关系展示画面)
如何更新样式
- div.style.background = 'red'
- div.style.display = 'none'
- div.classList.add('red')
- div.remove()直接删掉节点
三种不同的更新(渲染)方式
- 第一种,全走:div.remove() 会触发当前消失,其他元素relayout
- 第二种,跳过layout:改变背景颜色,直接repaint + composite
- 第三种,跳过layout和paint:改变transform,只需composite。注意必须全屏查看效果,在iframe里看有问题
transform实现红心
<style>
*{
margin:0;
padding:0;
box-sizing: border-box;
}
#heart{
margin: 100px;
position: relative;
display: inline-block;
transition: all .5s;
}
#heart:hover{
transform: scale(1.5);
}
#heart>.bottom{
width:50px;
height: 50px;
/* border:1px solid red; */
transform: rotate(45deg);
background: red;
}
#heart>.left{
width: 50px;
height:50px;
/* border:1px solid red; */
background: red;
border-radius: 50% 0 0 50%;
position: absolute;
bottom: 100%;
right: 100%;
transform: rotate(45deg) translateX(41px);
}
#heart>.right{
width: 50px;
height: 50px;
/* border:1px solid red; */
background: red;
border-radius: 50% 50% 0 0;
position: absolute;
bottom: 100%;
left: 100%;
transform: rotate(45deg) translateY(41px);
}
</style>
<body>
<div id="heart">
<div class="left"></div>
<div class="right"></div>
<div class="bottom"></div>
</div>
</body>
transition
作用:补充中间帧 过渡必须要有起始,一般只有一次动画,或者两次。比如hover和非hover状态的过渡
transition: 属性名 时长 过渡方式 延迟
transition: all 1s;
并不是所有属性都能过渡
- display:none=>block没法过渡
- 一般改成visibility:hidden=>visible
- background颜色可以过渡
- opacity透明度可以过渡
<style>
#demo {
width: 100px;
height: 100px;
border:1px solid red;
transition: all 1s;
/* opacity: 1; */
visibility: visible;
}
/* #demo:hover {
width: 200px;
height: 200px;
} */
#demo.end{
width: 200px;
height: 200px;
/* opacity: 0; */
visibility: hidden;
}
</style>
<body>
<div id="demo"></div>
<button id="x">start</button>
</body>
<script>
x.onclick = ()=>{
demo.classList.add('end')
// setTimeout(()=>{
// demo.remove()
// },1000)
}
demo.ontransitionend = ()=>{
demo.remove()
}
</script>
animation
animation:时长|过渡方式|延迟|次数|方向|填充模式|是否暂停|动画名
- 声明关键帧
- 添加动画
<style>
#demo {
width: 100px;
height: 100px;
border:1px solid red;
margin:50px;
}
/* 声明关键帧 */
@keyframes xxx {
0% {
transform: none;
}
66.66% {
transform:translateX(200px);
}
100% {
transform: translateX(200px) translateY(100px);
}
}
#demo.start{
/* animation: xxx 1.5s forwards; */
animation: 1.5s ease 1s infinite alternate forwards xxx ;
}
</style>
<body>
<div class="wrapper">
<div id="demo"></div>
<button id="button">开始</button>
<button id="xxx">暂停</button>
<button id="yyy">恢复</button>
</div>
</body>
<script>
button.onclick = ()=>{
demo.classList.add('start')
}
xxx.onclick = ()=>{
demo.style.animationPlayState = 'paused'
}
yyy.onclick = ()=>{
demo.style.animationPlayState = 'running'
}
</script>
animation实现红心
<style>
*{
margin:0;
padding:0;
box-sizing: border-box;
}
#heart{
margin: 100px;
position: relative;
display: inline-block;
/* transition: all .5s; */
animation: heart 1s infinite alternate linear;
}
@keyframes heart {
0% {
transform: scale(1.0);
}
100%{
transform: scale(1.5);
}
}
/* #heart:hover{
transform: scale(1.5);
} */
#heart>.bottom{
width:50px;
height: 50px;
/* border:1px solid red; */
transform: rotate(45deg);
background: red;
}
#heart>.left{
width: 50px;
height:50px;
/* border:1px solid red; */
background: red;
border-radius: 50% 0 0 50%;
position: absolute;
bottom: 100%;
right: 100%;
transform: rotate(45deg) translateX(41px);
}
#heart>.right{
width: 50px;
height: 50px;
/* border:1px solid red; */
background: red;
border-radius: 50% 50% 0 0;
position: absolute;
bottom: 100%;
left: 100%;
transform: rotate(45deg) translateY(41px);
}
</style>
<body>
<div id="heart">
<div class="left"></div>
<div class="right"></div>
<div class="bottom"></div>
</div>
</body>
资料来源:饥人谷