CSS3中的动画属性窥探

@keyframes 规则动画

box 从红色过度到黄色,间隔 5 秒。

1
2
3
<body>
    <div class="box"></div>
</body>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
.box{
    width:100px;
    height:100px;
    animation: myfirst 5s;
}
@keyframes myfirst {
    from {
        background: red;
    }

    to {
        background: yellow;
    }
}

也可以用百分比来规定变化发生的时间,关键词 “from” 和 “to”,等同于 0% 和 100%。

例如:当动画为 25% 及 50% 时改变背景色,然后当动画 100% 完成时再次改变:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
 @keyframes myfirst {
    0% {
        background: red;
    }

    25% {
        background: yellow;
    }

    50% {
        background: blue;
    }

    100% {
        background: green;
    }
}

CSS3 过度动画

CSS3 过渡是元素从一种样式逐渐改变为另一种的效果。要实现这一点,必须规定两项内容:

  • 指定要添加效果的CSS属性
  • 指定效果的持续时间。

例如:我们来修改一个 box 的宽度。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
.box {
    width: 100px;
    height: 100px;
    background: red;
    transition: width 2s; 
    -webkit-transition: width 2s; /* Safari */ 
}

.box:hover{
    width: 200px;
}

鼠标放上去后会逐渐变宽,然后移开鼠标就会逐渐恢复到之前的宽度。

CSS3 3D转换

1
rotate3d(x,y,z,angle)

x:用来描述元素围绕X轴旋转的矢量值; y:用来描述元素围绕Y轴旋转的矢量值; z:用来描述元素围绕Z轴旋转的矢量值; a:是一个角度值,主要用来指定元素在3D空间旋转的角度,如果其值为正值,元素顺时针旋转,反之元素逆时针旋转。

1
2
3
4
5
<body>
    <div class="out-box">
        <div class="box">测试3D</div>
    </div>
</body>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
.out-box{
    background: black;
    width:100px;
}
.box {
    width: 100px;
    height: 100px;
    font-size: 24px;
    color:white;
    text-align: center;
    line-height: 100px;
    background: red;
}

围绕 X 轴旋转 45 度的样子。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 .box {
    width: 100px;
    height: 100px;
    font-size: 24px;
    color:white;
    text-align: center;
    line-height: 100px;
    background: red;
    transform: rotate3d(1, 0, 0, 45deg);
}

试想一下,如果我们围绕 X 轴旋转 90 度应该就成了一个看不见的线了,我们旋转 89 度看看效果。

1
transform: rotate3d(1, 0, 0, 89deg);

接下来我们来试试围绕 Y 轴分别旋转 45 度和 89 度的效果:

重点是 Z 轴的旋转,我们来看看效果,下面对 X, Y, Z 轴的效果对比如下:

假设我们将上面的所有 1 改为 -1 则表示旋转的方向相反(这就是矢量方向):

根据上面的测试我们可以假设出一个坐标:

上面的测试已经可以验证 Z 轴的矢量方向(右手定则),和我们的假设坐标是一致的,我们来同时变化一下 XY, YZ, ZX, XYZ 的旋转来验证一下这两个轴的矢量方向。

很显然,修正后的坐标应该是这样的:

案例

接下来我们看一个案例,我们让下面的小人跑起来:

布局文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<body style="background: black;">
    <div class='container'>
        <div class='person'>
            <div class='head'></div>
            <div class='part arm one'></div>
            <div class='part arm two'></div>
            <div class='torso'></div>
            <div class='part leg one'></div>
            <div class='part foot one'></div>
            <div class='part leg two'></div>
            <div class='part foot two'></div>
        </div>
    </div>
</body>

CSS 样式:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
.container {
    height: 300px;
    width: 300px;
    margin: 50px;
}

.person {
    position: absolute;
    height: 75px;
    width: 0;
    color: #fff;
    left: 150px;
    top: 159px;
    transform-origin: 50% 50% 0px;
}

.person .head:before {
    content: "";
    position: absolute;
    top: 0px;
    left: -6px;
    height: 2.7px;
    width: 42px;
    border-radius: 20%;
    border: 4px solid white;
    background-color: #fff;
    transform-origin: 50% 100% 0px;
    z-index: 90;
}

.person .head {
    position: absolute;
    top: -30px;
    left: -6px;
    height: 30px;
    width: 30px;
    border-radius: 50%;
    border: 4px solid white;
    transform-origin: 50% 100% 0px;
    z-index: 90;
}

.person .head:after {
    content: "";
    position: absolute;
    top: -12px;
    left: 9px;
    height: 12px;
    width: 15px;
    border-radius: 30%;
    border: 4px solid white;
    background-color: #fff;
    z-index: 90;
}

.person .torso {
    position: absolute;
    height: 60px;
    width: 0;
    border-left: 2px solid white;
    left: 0px;
    top: 15px;
    z-index: 90;
}

.person .part {
    position: absolute;
    left: 0;
    top: 75px;
    z-index: 90;
}

.person .part.arm {
    position: absolute;
    border-left: 3px solid white;
    border-bottom: 3px solid white;
    height: 45px;
    width: 39px;
    top: 15px;
    right: 300px;
    transform-origin: 0% 0% 0px;
}

.person .part.arm.one {
    transform: rotate3d(0, 0, 1, -90deg);
}

.person .part.arm.two {
    transform: rotate3d(0, 0, 1, -90deg);
    animation-delay: .5s;
}

.person .part.leg {
    height: 57px;
    width: 60px;
    border-right: 3px solid white;
    border-top: 3px solid white;
    transform-origin: 0% 0% 0px;
}

.person .part.leg.one {
    transform: rotate3d(0, 0, 1, 90deg);
}

.person .part.leg.two {
    transform: rotate3d(0, 0, 1, 80deg);
    animation-delay: .5s;
}

.person .part .foot {
    position: absolute;
    top: 90px;
    left: 0;
    width: 3px;
    height: 3px;
    background-color: #ffffff;
    z-index: 900;
    border: 3px solid red;
}

CSS3 动画:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@keyframes run {
    0% {
        transform: rotate3d(0, 0, 1, -5deg);
    }

    50% {
        transform: rotate3d(0, 0, 1, 150deg);
    }

    100% {
        transform: rotate3d(0, 0, 1, -5deg);
    }
}

@keyframes bob {
    0% {
        transform: rotate3d(0, 0, 1, 5deg);
    }

    25% {
        transform: rotate3d(0, 0, 1, -30deg) skew(15deg, 0deg);
    }

    50% {
        transform: rotate3d(0, 0, 1, 5deg);
    }

    75% {
        transform: rotate3d(0, 0, 1, -30deg) skew(15deg, 0deg);
    }

    100% {
        transform: rotate3d(0, 0, 1, 20deg) skew(-15deg, 0deg);
    }
}

@keyframes pump {
    0% {
        transform: rotate3d(0, 0, 1, 80deg);
    }

    50% {
        transform: rotate3d(0, 0, 1, -70deg);
    }

    100% {
        transform: rotate3d(0, 0, 1, 80deg);
    }
}

例如上面我们让小人的腿动,可以给 leg 添加 run 动画, 动画间隔 1 秒,无限循环,两个 leg 的动画间隔通过 animation-delay: .5s; 来设置。

1
2
3
4
5
6
7
8
 .person .part.leg {
    height: 57px;
    width: 60px;
    border-right: 3px solid white;
    border-top: 3px solid white;
    transform-origin: 0% 0% 0px;
    -webkit-animation: run 1s infinite ease-in;
}

最后我们给小人添加一个移动动画就是跑起来的感觉了:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
.person {
    position: absolute;
    height: 75px;
    width: 0;
    color: #fff;
    left: 150px;
    top: 159px;
    transform-origin: 50% 50% 0px;
    -webkit-animation: sprint 2s infinite ease-in;
}
 @keyframes sprint {
    0% {
        transform-origin: 50% 50% 0px;
        transform: translate(-200px, 0px);
    }

    100% {
        transform: translate(0px, 0px);
        transform-origin: 50% 50% 0px;
        transform: translate(1300px, 0px);
    }
}