前言
最近在整理CSS动画相关的代码时,发现了一个特别有趣的小项目------两个小球的亲亲动画。这个看似简单的动画其实涉及了CSS动画的很多核心概念:border-radius
、animation
、定位布局等。今天就来详细解析一下这个萌萌的动画是如何实现的。
先来看看最终效果:两个可爱的小球,左边的球会先蹭蹭右边的球,然后右边的球会主动亲一下左边的球,最后还会冒出一个小爱心。整个动画循环播放,非常治愈。
HTML结构设计
首先,我们需要设计HTML结构。这里使用了emmet语法来快速生成代码:
html
<div class="container">
<div id="l-ball" class="ball">
<div class="face face-l">
<div class="eye eye-l"></div>
<div class="eye eye-r"></div>
<div class="mouth"></div>
</div>
</div>
<div id="r-ball" class="ball">
<div class="face face-r">
<div class="eye eye-l eye-r-p"></div>
<div class="eye eye-r eye-r-p"></div>
<div class="mouth"></div>
</div>
</div>
<div class="heart"></div>
</div>
结构解析:
.container
:页面居中的容器#l-ball
、#r-ball
:左右两个小球(id唯一标识).ball
:球的通用样式(class可复用).face
:小球的脸部区域.eye
:眼睛(每个球有两只眼睛).mouth
:嘴巴.heart
:爱心特效
这里体现了面向对象的CSS思想,通过多类名实现样式的复用和多态。
CSS基础样式
页面布局与居中
css
body {
background-color: #pink;
margin: 0;
}
.container {
position: absolute;
top: 50%;
left: 50%;
width: 238px;
transform: translate(-50%, -50%);
}
这里使用了经典的水平垂直居中 方案:position: absolute
+ transform: translate(-50%, -50%)
。
小球基础样式
css
.ball {
width: 100px;
height: 100px;
border: 8px solid #110202e7;
border-radius: 50%;
display: inline-block;
background-color: #fff;
vertical-align: top;
position: relative;
}
关键技术点:
border-radius: 50%
:将方形变成圆形display: inline-block
:行内块级元素,可以设置宽高且在一行显示position: relative
:相对定位,为子元素提供定位参考
脸部特征设计
css
.face {
width: 70px;
height: 30px;
position: absolute;
right: 0;
top: 30px;
border-top-right-radius: 15px;
}
.eye {
width: 15px;
height: 14px;
border-radius: 50%;
border-bottom: 5px solid #020000;
position: absolute;
}
.mouth {
width: 30px;
height: 14px;
border-radius: 50%;
border-bottom: 5px solid #020000;
position: absolute;
bottom: -5px;
left: 0;
right: 0;
margin: auto;
}
这里使用了绝对定位 (position: absolute
),子元素会相对于最近的position
不为static
的父元素进行定位。
动画世界的精彩
左球的蹭蹭动画
css
#l-ball {
animation: nuzzleLeft 4s ease-in-out infinite;
z-index: 2;
}
@keyframes nuzzleLeft {
0%, 100% { transform: translateX(0) rotate(0deg); }
/* 第一次蹭 */
10% { transform: translateX(20px) rotate(-5deg); }
15% { transform: translateX(20px) rotate(5deg); }
20% { transform: translateX(20px) rotate(-5deg); }
25% { transform: translateX(0) rotate(0deg); }
/* 第二次蹭 */
35% { transform: translateX(20px) rotate(-5deg); }
40% { transform: translateX(20px) rotate(5deg); }
45% { transform: translateX(20px) rotate(-5deg); }
50% { transform: translateX(0) rotate(0deg); }
/* 保持静止,等右球亲它 */
55%, 80% { transform: translateX(0) rotate(0deg); }
}
右球的亲亲动画
css
#r-ball {
animation: kissRight 4s ease-in-out infinite;
z-index: 1;
}
@keyframes kissRight {
/* 初始静止,等左球蹭完 */
0%, 55% { transform: translateX(0) rotate(0deg); }
/* 向左亲 */
65% { transform: translateX(-30px) rotate(5deg); }
70% { transform: translateX(-30px) scale(0.9) rotate(5deg); }
75% { transform: translateX(-30px) rotate(5deg); }
/* 回到初始位置 */
80%, 100% { transform: translateX(0) rotate(0deg); }
}
爱心特效
css
.heart {
position: absolute;
top: 10px;
left: 50%;
transform: translateX(-50%);
width: 30px;
height: 30px;
background-color: #ff3366;
animation: heartBeat 4s ease-in-out infinite;
opacity: 0;
clip-path: path('M15,8 C15,8 14,3 9,3 C4,3 3,8 3,8 C3,8 3,13 15,20 C27,13 27,8 27,8 C27,8 26,3 21,3 C16,3 15,8 15,8 Z');
z-index: 10;
}
@keyframes heartBeat {
0%, 64%, 100% { transform: translateX(-50%) scale(0); opacity: 0; }
70% { transform: translateX(-50%) scale(1.2); opacity: 1; }
73% { transform: translateX(-50%) scale(1); opacity: 1; }
76% { transform: translateX(-50%) scale(1.1); opacity: 1; }
80% { transform: translateX(-50%) scale(0); opacity: 0; }
}
这里使用了clip-path
来绘制爱心形状,搭配缩放动画实现心跳效果。
细节优化:嘴巴表情动画
为了让动画更加生动,我们还给小球的嘴巴添加了表情变化:
css
@keyframes leftMouth {
0%, 100% { width: 30px; border-bottom-width: 5px; }
/* 蹭的时候嘴巴微微变化 */
10%, 20%, 35%, 45% { width: 25px; border-bottom-width: 6px; }
15%, 40% { width: 28px; border-bottom-width: 5px; }
/* 被亲的时候嘴巴变化 */
65%, 75% { width: 15px; border-bottom-width: 7px; }
}
@keyframes rightMouth {
0%, 60%, 100% { width: 30px; border-bottom-width: 5px; }
/* 亲的时候嘴巴变化 */
65%, 75% { width: 15px; border-bottom-width: 7px; }
}
核心知识点总结
1. Display属性的妙用
div
默认是block
(块级),独占一行span
、i
、a
等是inline
(行内),不能设置宽高inline-block
(行内块级):既能设置宽高,又能在一行显示
2. 定位系统
position: relative
:相对定位,子元素相对它定位,同时相对于自身位置定位position: absolute
:绝对定位,会找到离它最近的position
不为static
的父元素进行定位,直到body为止
3. 面向对象的CSS
通过多类名实现样式的复用和多态,比如.ball
类可以被多个元素使用,而#l-ball
和#r-ball
的id则用于区分不同的动画效果。
实际应用场景
这个动画虽然看起来简单,但包含了很多实用的技术:
- 加载动画:可以改造成各种加载提示
- 交互反馈:点赞、收藏等操作的动画效果
- 情感化设计:增加产品的趣味性和用户粘性
- 节日主题:情人节、七夕等节日氛围营造
结语
通过这个小球亲亲动画,我们学习了CSS动画的核心概念:关键帧动画、定位布局、样式复用等。虽然是一个简单的动画,但其中蕴含的CSS技巧却很实用。
CSS动画的魅力就在于此------用简单的代码创造出生动有趣的效果。在实际项目中,这些技巧可以大大提升用户体验,让冰冷的界面变得温暖有趣。