css3动画(1)-transition、transform、animation

4,449 阅读5分钟

transform

transform变形,可以控制元素的缩放、位移和旋转。

  1. scale(x, y)缩放, 以元素中心为中心,缩小或放大一定倍数。
.box {
    width: 200px;
    height: 200px;
    background: pink;
}
.box:hover {
    transform: scale(1.5, 1.5)
}

<div class='box'></div>
  1. translate(x, y) / translateX() / translateY()位移
    (1)x, y为数值时,移动一定位置
    (2)x, y为百分比时,百分比是相当于自己的宽高,移动一定距离
    第2点可以结合position用来实现水平居中
.box {
    width: 200px;
    height: 200px;
    background: pink;
}
.box:hover {
    transform: translate(100px, 100px);
    /*transform: translate(50%, 50%)*/
}

<div class='box'></div>
  1. rotate()旋转
.box {
    width: 200px;
    height: 200px;
    background: pink;
}
.box:hover {
    transform: rotate(60deg);
}

<div class='box'></div>

tranform-origin: 属性在变化时,默认中心是从元素的中心,如果想改变动画的中心,可以使用tranform-origin

/*绕着div的中心转*/
div {
    transform: rotate(0deg)
}
div.hover {
    transform: rotate(360deg)
}
/*绕着div的左边*/
div {
    transform: rotate(0deg);
    transform-origin: left center
}
div.hover {
    transform: rotate(360deg)
}

transition

transition过渡,是指元素的一个或多个属性从一个状态到另一个状态平稳过渡。transition是简写的,有四个属性值:

  1. transition-propery: 发生状态变化的属性值, 可以使用all来控制所有属性
  2. transition-duration:过渡持续时间, 单位s不可以省略
  3. transition-timing-function: 动画速度函数
  4. transition-delay: 动画延时时间,单位s不可以省略

实现一个div宽高变化。

<!DOCTYPE html>
<html>
  <head>
    <style>
    .box {
        width: 100px;
        height: 100px;
        background: pink;
        transition: width 1s linear 0s,
                    height 1s linear 0s;
    }
    .box:hover {
       width: 200px;
       height: 200px;
    }
    </style>
  </head>
  <body>
    <div class="box"></div>
  </body>
</html>

注意:
(我的理解)
transition起作用,一定是状态发生了变化,比如鼠标悬浮事件、点击事件、js触发,导致页面需要重新绘制,然后transition才会起作用。

动态创建的元素直接使用transition没有效果

<!DOCTYPE html>
<html>
    <head>
        <style>
            .box {
                width: 100px;
                height: 100px;
                background: pink;
                transition: all 2s linear 0s;
            }
        </style>
    </head>
    <body>
        <div id="wrap"></div>
        <script>
            window.onload = function() {
                let box = document.createElement('div');
                box.classList.add('box');
                document.querySelector('#wrap').appendChild(box);
                box.style.width = '200px'; // 直接显示200px,无过渡效果
            }
        </script>
    </body>
</html>

浏览器在渲染时,并不会一条一条执行css规则,而是会将多个css规则合并到一起渲染,所以动态添加的元素box相当于直接设置了宽度200px, 并不存在状态变化,所以设置transition无效。
解决办法:
强行让页面先绘制一次,不合并css规则

<script>
    window.onload = function() {
        let box = document.createElement('div');
        box.classList.add('box');
        document.querySelector('#wrap').appendChild(box);
        box.focus();  // !! 存在状态变化了
        box.style.width = '200px'; 
    }
</script>

animation

transition存在的缺点:
(1)必须通过事件来触发,所以不能在页面加载时奏效
(2)只有初始状态和结束状态两种,不能设置中间态
(3)不能持续动画,除非反复触发
animation则可以解决这些问题。

animation可以实现帧动画,如一个向下运动的效果:
aimation: down 1s 0s linear infinite forwards

各属性值如下:
(1)animation-name:动画名,使用keyframe标识

@keyframe down {
    0% {
        transform: translateY(50px)
    }
    50% {
        transform: translateY(100px)
    }
    100% {
        transform: translate(150px)
    }
}

规定了一个向下效果的帧,有3个状态, 0%,50%和100%,其中,0%可以写成from, 100%可以写成to; 在各个状态中就可以规定相关属性的值,可以规定多个属性。

(2)animation-duration: 动画持续时间,单位s不可省略,值不可省略,因为默认是0s

(3)animation-timing-function: 动画速度函数,与transition-timing-function作用一样,此时动画是平滑过渡;
可以使用steps()实现动画的分段过渡

<!--html-->
<div class="box animate"></div>

/*css*/
.box {
    position: absolute;
    top: 200px;
    left: 200px;
    width: 100px;
    height: 30px;
    background: pink;
    transform-origin: left center;
}
@keyframes breathe {
    from {
        transform: rotate(0deg)
    }
    to {
        transform: rotate(360deg)
    }
}

/*平滑过渡,div均匀的扫过一圈*/
.animate {
    animation: breathe 5s liner 0s; 
}
/*分段过渡,类似于等待加载转圈效果,div分5次转一圈*/
.animate {
    animation: breathe 5s steps(5) 0s; 
}

(4)animation-delay: 动画延时时间,单位s不可省略

(5)animation-iteration-count: 动画播放次数,默认为1次,可以3、5,也可以使用关键词infinite实现无限动画

/*无限次*/
animation: down 1s linear 0s infinite
/*3次*/
animation: down 1s linear 0s 3

(6)animation-fill-mode: 动画结束时停留的状态,默认回到初始状态,可以通过关键字设置不同状态

  • none: 回到初始状态
  • forwards: 回到结束状态
  • backwards: 回到第一帧状态
  • both: 根据animation-direction的值交替使用forwards和backwards

(7)animation-direction: 动画执行方向 对于动画

@keyframes breathe {
    from {
        transform: scale(1, 1)
    }
    to {
        transform: scale(1.5, 1.5)
    }
}

.animate {
    animation: breathe 1s liner 0s infinite
}
  • normal: 正常方向, 1s从1过渡到1.5,然后立即回到1,第2s仍然从1-1.5
  • alternate: 交替方向,1s从1过渡到1.5,第2s从1.5到1,依次交替
  • reverse: 与normal反向方向,1s从1.5过渡到1,然后立即回到1.5,第2s仍然从1.5-1
  • alternate-reverse: 与laternate反向方向,1s从1.5过渡到1,第2s从1到1.5,依次交替

animation的各个属性可以简写为:
animation: name duration timing-function delay iteration-count diraction fill-mode

(8)animation-play-state 有时候动画播放时突然停止,默认会回到初始状态:

div.hover {
    animation: breathe 5s 0s linear;
}

如果在5s内鼠标移除出去了,div会立刻回到动画未开始状态,可以设置animtion-play-state使动画突然停止时处于当前状态

div {
    animation: breathe 5s 0s linear;
    animation-play-state: paused
}
div.hover {
    animation-play-state: running
}

paused可以使动画停止在当前状态,running从停止状态继续动画。