手把手教你实现一个前进的小火车

440 阅读5分钟

前言

这次带大家来实现一个生动的正在前进的火车效果,纯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 的样式及动画效果。关于这里的动画效果,车轮从 旋转到 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 实现,代码简单易懂。另外,感兴趣的小伙伴们还可以在现有基础上发散思维,比如增加点其他效果,或者更改颜色等等。关于该效果如果大家有更好的想法欢迎在评论区分享,互相学习。最后,完整代码在码上掘金里可以查看,如果有什么问题大家在评论区里讨论~