小车旅行动画实现
效果展示
CSS 知识点
- 灵活使用 background 属性下的 repeating-linear-gradient 实现路面效果
- 灵活运用 animation 属性与 transform 实现小车和其他元素的动画效果
动画场景分析
从效果图可以看出需要实现此动画的话,需要position
属性控制元素部署到不同的层上从而形成堆叠效果,这样动画在执行的过程中会有比较好的运动差效果。具体的层次部署图如下:
整体页面结构
html
<div class="scene">
<div class="sun"></div>
<!-- 路面 -->
<div class="road"></div>
<!-- 小车 -->
<i class="fa-solid fa-van-shuttle"></i>
<!-- 云朵 -->
<i class="fa-solid fa-cloud" style="--i:1"></i>
<i class="fa-solid fa-cloud" style="--i:2"></i>
<i class="fa-solid fa-cloud" style="--i:3"></i>
<i class="fa-solid fa-cloud" style="--i:4"></i>
<i class="fa-solid fa-cloud" style="--i:5"></i>
<!-- 树木 -->
<i class="fa-solid fa-tree" style="--i:1"></i>
<i class="fa-solid fa-tree" style="--i:2"></i>
<i class="fa-solid fa-tree" style="--i:3"></i>
<i class="fa-solid fa-tree" style="--i:4"></i>
<i class="fa-solid fa-tree" style="--i:5"></i>
<i class="fa-solid fa-tree" style="--i:6"></i>
<i class="fa-solid fa-tree" style="--i:7"></i>
<!-- 大山 -->
<i class="fa-solid fa-mountain" style="--i:1"></i>
<i class="fa-solid fa-mountain" style="--i:2"></i>
<i class="fa-solid fa-mountain" style="--i:3"></i>
</div>
小车样式实现
小车实现起来比较简单,采用font-awesome
的字体库来实现,具体的样式如下:
css
.fa-van-shuttle {
position: absolute;
bottom: 30px;
left: 30px;
color: #fff;
font-size: 3.5em;
-webkit-text-stroke: 2px #000;
z-index: 10;
animation: animateVan 0.2s linear infinite;
}
/* 动画结合transform属性实现小车的上下运动效果 */
@keyframes animateVan {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(1px);
}
}
太阳样式实现
css
.sun {
position: absolute;
top: 40px;
right: 40px;
width: 40px;
height: 40px;
background: #fff;
border-radius: 50%;
/* 使用 box-shadow 属性实现多层阴影效果,达到太远散射效果*/
box-shadow: 0 0 40px orange, 0 0 60px orange, 0 0 80px orange, 0 0 100px
orange;
}
大山样式实现
css
.fa-mountain {
position: absolute;
bottom: 0;
font-size: 10em;
color: #8b3c23;
z-index: 1;
animation: animateClouds 15s linear infinite;
/* 每座大山都有动画延迟 */
animation-delay: calc(-3s * var(--i));
}
/* 使用 transform 属性实现大山移动动画,动画场景的容器为350px的宽度,所以动画起始是从350到-350之间重复运动 */
@keyframes animateClouds {
0% {
transform: translateX(350px);
}
100% {
transform: translateX(-350px);
}
}
公路样式实现
公路在实现的时候有点复杂,所以分布来说明
- 实现道路整体效果
css
.road {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 60px;
background: #333;
z-index: 3;
}
- 实现道路上方绿色色块(采用伪块来实现)
css
.road::before {
content: "";
position: absolute;
width: 100%;
height: 10px;
background: #0d9e0d;
}
- 使用 background 属性中的 repeating-linear-gradient 值实现道路的线条
css
.road::after {
content: "";
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100%;
height: 2px;
background: repeating-linear-gradient(
90deg,
transparent 0,
transparent 50%,
#fff 50%,
#fff 100%
);
background-size: 30px;
}
完成上述代码后效果如下:
此时的道路并不会运动,所以添加动画实现运动效果,具体代码如下:
css
@keyframes animateRoad {
0% {
background-position-x: 0;
}
100% {
/* 数值越小,运动速度 */
background-position-x: -30px;
}
}
树木样式实现
css
.fa-tree {
position: absolute;
bottom: 60px;
font-size: 2em;
color: #0d9e0d;
z-index: 3;
animation: animateClouds 7s linear infinite;
/* 动画采用大山一样的动画,只是动画延迟时间不一样 */
animation-delay: calc(-1s * var(--i));
}
云层样式实现
css
.fa-cloud {
position: absolute;
top: calc(15px * var(--i));
left: calc(15px * var(--i));
font-size: 2.5em;
color: #fff;
-webkit-text-stroke: 2px #000;
z-index: 2;
animation: animateClouds 3.5s linear infinite;
animation-delay: calc(-4s * var(--i));
}