目录
- 一、循环波浪
- 二、关键帧呼应
- 三、关键帧顺接
- 四、利用 transform-origin 做拉伸
- 五、大元素可拆分多个小元素联动
- 六、预留视觉缓冲
- 七、随机感:动画周期设置
- 八、抛物线:两个内外div实现x和y向量运动
今天我们主要学习动画实现要素。
一、循环波浪
利用 delay 时间差,导致波浪平滑错位。
可以使用 CSS Animation 和 animation-delay
属性来实现一排蓝色的 div 循环波浪效果。以下是一个示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Wave Animation</title>
<style>
.wave-container {
display: flex;
justify-content: space-between;
margin-top: 50px;
width: 100%;
}
.wave {
width: 50px;
height: 50px;
background-color: blue;
animation: wave 1s linear infinite;
}
.wave:nth-child(2) {
animation-delay: 0.2s;
}
.wave:nth-child(3) {
animation-delay: 0.4s;
}
.wave:nth-child(4) {
animation-delay: 0.6s;
}
.wave:nth-child(5) {
animation-delay: 0.8s;
}
@keyframes wave {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-50px);
}
100% {
transform: translateY(0);
}
}
</style>
</head>
<body>
<div class="wave-container">
<div class="wave"></div>
<div class="wave"></div>
<div class="wave"></div>
<div class="wave"></div>
<div class="wave"></div>
</div>
</body>
</html>
在这个示例中,使用了五个蓝色的 div 元素 .wave
来表示波浪效果。通过设置不同的 animation-delay
来创建时间差,从而形成连续的波浪效果。 CSS 动画 wave
定义了元素的缩放动画,使得波浪效果连续播放。
二、关键帧呼应
双盒弹跳联动。
可以注意到上述非常丝滑的模拟了两个盒子在不同阶段的弹跳效果。
三、关键帧顺接
四、利用 transform-origin 做拉伸
transform-origin: 48% 100% 从下往上扩展/拉伸;transform-origin: 50% 5% 从上往下扩展/拉伸。
transform-origin
属性用于指定 CSS 变换的原点。默认情况下,变换的原点为元素的中心点 (50% 50%)
。通过调整 transform-origin
的值,我们可以改变变换的起始位置,从而实现不同的效果。
-
transform-origin: 48% 100%;
:这个值将变换的原点设置为元素的底部中心。因此,当应用拉伸变换时,元素会从底部向上扩展。具体而言,变换会围绕元素底部边缘的水平中心点进行扩展。 -
transform-origin: 50% 5%;
:这个值将变换的原点设置为元素的顶部中心。因此,当应用拉伸变换时,元素会从顶部向下扩展。具体而言,变换会围绕元素顶部边缘的水平中心点进行扩展。
以下是具体的代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Stretch Animation</title>
<style>
.stretch-container {
display: flex;
margin-top: 50px;
width: 100%;
}
.stretch {
width: 50px;
height: 50px;
background-color: blue;
border-radius: 50%;
animation: stretch 1s linear infinite alternate;
}
.stretch:nth-child(1) {
transform-origin: 48% 100%;
}
.stretch:nth-child(2) {
transform-origin: 50% 5%;
}
@keyframes stretch {
0% {
transform: scaleY(1);
}
100% {
transform: scaleY(2);
}
}
</style>
</head>
<body>
<div class="stretch-container">
<div class="stretch"></div>
<div class="stretch"></div>
</div>
</body>
</html>
在这个示例中,有两个蓝色的 div 元素 .stretch
,通过不同的 transform-origin
值,分别实现了从底部向上拉伸和从顶部向下拉伸的效果。
五、大元素可拆分多个小元素联动
比如人物举着信封入场,可以信封和手做额外的附属动画,放大动作幅度。
图片来源:陈*真@腾讯
六、预留视觉缓冲
动画循环时可以设置 80% - 100% 关键帧之间不变。
预留视觉缓冲的目的是在动画循环的过程中,使得动画的最后一帧保持一段时间,以给用户提供视觉缓冲,使动画更加平滑和自然。在 CSS 中,可以通过设置关键帧动画的某些关键帧保持一段时间来实现预留视觉缓冲。
例如,在动画的 80% 到 100% 之间保持最后一帧的状态,可以让动画在结束阶段缓缓减速,给用户一个更平滑的动画效果。
以下是一个具体的示例,展示了如何在动画的 80% 到 100% 之间保持最后一帧的状态:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Animation with Visual Buffering</title>
<style>
.box {
width: 100px;
height: 100px;
background-color: blue;
position: relative;
animation: move 2s linear infinite;
}
@keyframes move {
0% {
transform: translateX(0);
}
80% {
transform: translateX(200px);
}
100% {
transform: translateX(200px);
}
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
在这个示例中,动画从 0% 到 80% 的阶段进行了水平移动,然后在 80% 到 100% 的阶段保持了最后一帧的状态,即元素位于水平方向上的最终位置。
这样做可以使得动画在结束阶段缓缓减速,给用户一个更平滑的动画体验。
七、随机感:动画周期设置
多个元素同时运动,可以设置不同 duration 和 delay。除⾮时间是各粒⼦时间的最⼩公倍数,否则不会回归到初始状态,从⽽产⽣随机感。
在多个元素同时运动时,如果它们具有不同的 duration
和 delay
,它们的动画周期不会是一个固定的整数倍关系,因此它们不会在同一时刻回归到初始状态,从而产生了一种随机感。
这是因为当动画周期不是一个固定的整数倍关系时,各个元素的动画在同一时刻处于不同的阶段,导致它们的动画效果看起来更加错落有致、自然多样。
以下是一个具体示例,展示了如何通过设置不同的 duration
和 delay
,使得多个元素同时运动,产生随机感的动画效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Random Motion</title>
<style>
.box {
width: 50px;
height: 50px;
background-color: blue;
position: absolute;
border-radius: 50%;
}
.box:nth-child(1) {
animation: move1 2s linear infinite;
top: 100px;
left: 100px;
}
.box:nth-child(2) {
animation: move2 3s linear infinite;
top: 200px;
left: 200px;
}
@keyframes move1 {
0% {
transform: translateX(0);
}
100% {
transform: translateX(200px);
}
}
@keyframes move2 {
0% {
transform: translateY(0);
}
100% {
transform: translateY(200px);
}
}
</style>
</head>
<body>
<div class="box"></div>
<div class="box"></div>
</body>
</html>
在这个示例中,有两个蓝色的圆形 .box
元素,它们分别通过不同的 animation
属性设置了不同的动画效果(move1
和 move2
),并且具有不同的起始位置和动画持续时间。
因此,它们的动画周期不是一个固定的整数倍关系,从而产生了一种随机感的动画效果。
八、抛物线:两个内外div实现x和y向量运动
主要就是利用两个内外div实现x向量运动和y向量运动,y向量运动引入贝塞尔曲线,即可实现适当曲线运动。
在上一篇我们在学习贝塞尔曲线时实现过。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Parabolic Motion</title>
<style>
.ball {
width: 50px;
height: 50px;
background-color: red;
position: absolute;
border-radius: 50%;
animation: horizontalMove 2s linear forwards, verticalMove 2s cubic-bezier(.74,.2,.95,.47) forwards;
}
@keyframes horizontalMove {
0% {
left: 0;
}
100% {
left: 200px;
}
}
@keyframes verticalMove {
0% {
top: 0;
}
100% {
top: 200px;
}
}
</style>
</head>
<body>
<div class="ball"></div>
</body>
</html>
我们是实现了一个 div 在 left 和 top 两个方向属性上的不同速度的变化来模拟抛物线。
但假如我们定义了如下:
@keyframes horizontalMove {
0% {
transform: translateX(0);
}
100% {
transform: translateY(200px);
}
}
@keyframes verticalMove {
0% {
transform: translateY(0);
}
100% {
transform: translateY(200px);
}
}
主要就是利用x向量运动和y向量运动,x向量匀速运动,y向量运动引入贝塞尔曲线,即可实现适当曲线运动。
这种方法可以应用于各种场景,比如游戏中的角色移动、用户界面中的动态效果、数据可视化中的图表动画等。通过调整贝塞尔曲线的控制点,可以实现不同形状的曲线运动,从而满足不同的需求和设计目的。
以下是一个更普适的示例,演示了如何利用两个 div 元素和贝塞尔曲线来实现适当的曲线运动:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bezier Curve Animation</title>
<style>
.outer {
position: relative;
width: 400px;
height: 400px;
border: 1px solid black;
overflow: hidden;
}
.inner {
position: absolute;
width: 50px;
height: 50px;
background-color: blue;
border-radius: 50%;
animation: moveX 2s linear infinite, moveY 2s cubic-bezier(.74,.2,.95,.47) infinite;
}
@keyframes moveX {
0% {
left: 0;
}
100% {
left: calc(100% - 50px);
}
}
@keyframes moveY {
0% {
top: 0;
}
100% {
top: calc(100% - 50px);
}
}
</style>
</head>
<body>
<div class="outer">
<div class="inner"></div>
</div>
</body>
</html>
在这个示例中,.outer
div 元素作为外部容器,限制活动范围,.inner
div 元素作为内部元素,利用两个不同的动画分别控制 x 向量和 y 向量的运动。在 y 向量的运动中,引入了贝塞尔曲线,使得动画呈现出适当的曲线运动效果。