前言
这次带大家来实现一个生动的正在前进的火车效果,纯CSS实现,通过动画来展现出一个前进的小火车,话不多说,我们直接进入主题
效果预览
小火车最终实现的效果如下所示。
HTML部分
首先我们看到HTML部分,这是整个效果的基建,相关代码如下。
<div class="loader">
<div class="station-lights">
<div class="light"></div>
<div class="light"></div>
<div class="light"></div>
<div class="light"></div>
<div class="light"></div>
</div>
<div class="metro-train">
<div class="window"></div>
<div class="window"></div>
<div class="window"></div>
<div class="window"></div>
<div class="window"></div>
<div class="window"></div>
<div class="wheels">
<div class="wheel"></div>
<div class="wheel"></div>
<div class="wheel"></div>
<div class="wheel"></div>
</div>
</div>
<div class="track"></div>
<div class="platform"></div>
</div>
这里定义了一个小火车进站动画的结构,包含站台灯光、列车车厢、车轮、轨道和站台等元素。
最外层 .loader 是动画容器。内部包含站台灯光 .station-lights、列车 .metro-train、轨道 .track 和站台 .platform。通过CSS实现闪烁或渐变动画,营造灯光效果
车厢窗户有6个 .window 元素,代表列车每节车厢的窗户,为矩形并添加反光效果。车轮组有4个 .wheel 元素,通过CSS动画实现旋转,模拟列车行驶。轨道.track为两条平行线,表示列车行驶的轨道。站台.platform是一个长条形元素,模拟乘客候车的站台。
CSS部分
紧接着我们看到CSS部分,首先是metro-train类的样式,相关代码如下。
.metro-train {
width: 14em;
height: 4em;
background: linear-gradient(to right, #2c3e50, #4ca1af);
border-radius: 0.8em;
position: relative;
left: 1em;
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
animation: train-move 2s infinite ease-in-out;
}
@keyframes train-move {
0%, 100% {
transform: translateX(0);
}
50% {
transform: translateX(0.5em);
}
}
.metro-train::before {
content: '';
position: absolute;
width: 90%;
height: 1.5em;
background: rgba(255,255,255,0.2);
border-radius: 0.4em;
top: 0.5em;
left: 5%;
}
.metro-train::after {
content: '';
position: absolute;
width: 100%;
height: 0.8em;
background: rgba(0,0,0,0.2);
border-radius: 0 0 0.8em 0.8em;
bottom: 0;
}
这里定义了一个 .metro-train 的样式和动画效果,通过渐变背景、伪元素和关键帧动画模拟列车的外观和轻微晃动效果。
从左到右的线性渐变,从深蓝(#2c3e50)过渡到蓝绿色(#4ca1af),模拟金属车身的反光,添加底部阴影,增强立体感。并且应用一个train-move 动画(2秒循环)。该动画的效果是列车在初始位置(0%)和结束位置(100%)静止,在动画中点(50%)向右平移 0.5em,形成左右摇摆的晃动感。接着用伪元素来装饰列车,模拟车顶的反光条,并且增强底部的阴影效果。
然后是window的样式,相关代码如下。
.window {
position: absolute;
width: 1.2em;
height: 1em;
background: rgba(200,230,255,0.8);
border-radius: 0.2em;
top: 1em;
}
.window:nth-child(1) { left: 1.5em; }
.window:nth-child(2) { left: 3.5em; }
.window:nth-child(3) { left: 5.5em; }
.window:nth-child(4) { left: 7.5em; }
.window:nth-child(5) { left: 9.5em; }
.window:nth-child(6) { left: 11.5em; }
.wheels {
position: absolute;
width: 100%;
height: 1.5em;
bottom: -0.8em;
display: flex;
justify-content: space-around;
}
.wheel {
width: 1.5em;
height: 1.5em;
background: radial-gradient(circle, #333 30%, #555 100%);
border-radius: 50%;
border: 0.2em solid #777;
animation: wheel-spin 1s infinite linear;
}
@keyframes wheel-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
这里定义了地铁列车的车窗(.window)和车轮(.wheel) 的样式及动画效果。关于这里的动画效果,车轮从 0° 旋转到 360°,形成连续滚动效果,关键帧使车轮无限旋转(1秒/圈),模拟行驶效果。
整体效果就是列车车身(.metro-train)上有6个等距排列的浅蓝色车窗,底部有4个旋转的金属质感车轮。车轮持续旋转(wheel-spin),列车轻微左右晃动(train-move),共同模拟行驶中的地铁。
接下来我们就定义了 track 的样式,相关代码如下。
.track {
width: 16em;
height: 0.3em;
background: #777;
position: absolute;
bottom: 0;
border-radius: 0.3em;
overflow: hidden;
}
.track::before {
content: '';
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(90deg,
transparent 0%,
rgba(255,255,255,0.8) 50%,
transparent 100%);
animation: track-light 1.5s infinite linear;
}
@keyframes track-light {
from { transform: translateX(-100%); }
to { transform: translateX(100%); }
}
.station-lights {
position: absolute;
width: 100%;
height: 2em;
top: -2.5em;
display: flex;
justify-content: space-between;
}
这里定义了轨道(.track)和站台灯光(.station-lights) 的样式及动画效果,整体效果 就是灰色轨道位于底部,上方悬空一排站台灯光。轨道上白色光带持续左右扫过,模拟列车灯光或环境光反射。
这里使用了一个光带动画,光带从轨道左端扫到右端,模拟列车灯光照射轨道的动态效果,关键帧使光带从左到右无限循环移动,增强动态感。
@keyframes light-blink {
0%, 100% { opacity: 0; transform: scale(0.5); }
50% { opacity: 1; transform: scale(1.2); background: #ff6b81; }
}
开始和结束(0%, 100%)的时候灯光完全透明(opacity: 0)且缩小(scale(0.5)),模拟熄灭状态。 中间点(50%)的时候灯光完全显示(opacity: 1),放大(scale(1.2))并变为亮粉色(#ff6b81),模拟高亮状态。最终这个动画效果就是灯光周期性闪烁,伴随缩放和颜色变化,营造动态氛围(如警报灯或装饰灯)。
总结
以上就是整个效果的实现过程了,纯 CSS 实现,代码简单易懂。另外,感兴趣的小伙伴们还可以在现有基础上发散思维,比如增加点其他效果,或者更改颜色等等。关于该效果如果大家有更好的想法欢迎在评论区分享,互相学习。最后,完整代码在码上掘金里可以查看,如果有什么问题大家在评论区里讨论~