如何用CSS实现平交道(Level Crossing)多状态动态切换?当前仅能全显/全隐
用CSS实现平交道动态状态切换的问题
需求说明
希望用CSS实现平交道的三种动态状态:
- ST-00:默认状态(对应第一张图)
- ST-01:对应第二张图
- ST-02:对应第三张图
当前使用的SVG代码:
<g transform="translate(50 150) scale(1.2 1)" class="Box-ST00" stroke="none" fill="none"> <rect width="150" height="10"/> </g> <g transform="translate(90 30) scale(1.2 1) rotate(90)" class="Box-ST00" stroke="none" fill="none"> <rect width="150" height="10" transform="scale(1.2 1) rotate(-50)" /> </g>
当前CSS代码:
/* Box STATE00 - None */ .Box-ST00 { stroke: black; fill: black; stroke-width: var(--boxes_stroke_width_small) } /* Box STATE01 - White */ .Box-ST01 { stroke: white; fill: white ; stroke-width: var(--boxes_stroke_width_small) }
目前问题:仅能实现完全填充或完全不显示的效果,无法实现中间状态(ST-02)或细腻的动态切换。
解决思路
1. 拆分视觉元素,分层控制状态
平交道的动态效果(比如栏杆起落、警示变化)靠单一矩形无法实现,建议把元素拆成固定底座、可转动栏杆、警示组件等独立SVG元素,给每个元素绑定状态类:
<!-- 固定底座 --> <g class="crossing-base"> <rect x="20" y="140" width="200" height="10" fill="#666"/> </g> <!-- 可转动的栏杆 --> <g class="crossing-bar ST-00" transform="translate(20 145)"> <rect width="150" height="10" fill="#c00"/> </g>
通过CSS的transform(旋转、平移)和opacity控制不同状态:
.crossing-bar { transform-origin: left center; /* 以栏杆左端为旋转中心 */ transition: transform 0.6s ease; /* 平滑过渡动画 */ } /* ST-00:栏杆抬起 */ .crossing-bar.ST-00 { transform: rotate(0deg); } /* ST-01:栏杆下落至中间位置 */ .crossing-bar.ST-01 { transform: rotate(45deg); } /* ST-02:栏杆完全落下 */ .crossing-bar.ST-02 { transform: rotate(90deg); }
2. 用clip-path实现部分显示效果
如果需要的是“部分填充/隐藏”的状态,比如栏杆逐步显示,可以用CSSclip-path裁剪元素:
/* ST-00:完全显示 */ .Box-ST00 { clip-path: inset(0 0 0 0); fill: black; } /* ST-01:显示一半宽度 */ .Box-ST01 { clip-path: inset(0 50% 0 0); fill: white; } /* ST-02:完全隐藏 */ .Box-ST02 { clip-path: inset(0 100% 0 0); }
3. 多元素叠加实现混合状态
如果ST-02需要黑白相间的栏杆效果,可以叠加两个矩形,分别控制显示:
<g class="crossing-bar ST-00"> <rect class="bar-black" width="150" height="10" fill="black"/> <rect class="bar-white" width="75" height="10" fill="white" x="75"/> </g>
通过CSS调整宽度或透明度实现状态切换:
.crossing-bar.ST-02 .bar-white { width: 150; opacity: 0.5; }
4. 用JS触发状态切换
通过JavaScript切换元素的类名,就能触发CSS定义的状态变化:
// 示例:从ST-00切换到ST-02 const bar = document.querySelector('.crossing-bar'); bar.classList.remove('ST-00'); bar.classList.add('ST-02');
内容的提问来源于stack exchange,提问作者CLetter
相关产品推荐
相关产品推荐

