spb/svgarden Public
SVGarden — searchable bank of 74 self-contained SVG+CSS animation snippets (svgarden.dev)
HTML 79.2%
Astro 10.3%
JavaScript 6%
CSS 3.7%
Shell 0.8%
1<!--2 ============================================================3 SVGarden — https://www.svgarden.dev4 Author : Simon-Pierre Boucher5 Contact: contact@spboucher.ai6 File : snippets/motion-path/train-track.html7 Desc : Toy train following its track, wheels spinning, car in tow8 ============================================================9-->10<!--svgarden11title: Train on track12slug: train-track13category: motion-path14tags: [motion, smil, train, mpath]15difficulty: intermediate16techniques: [animateMotion, mpath, begin-offset, transform-box]17how_it_works: >18 One <path> is the single source of truth: it is drawn twice as artwork19 (dashed sleepers under a solid rail) and referenced twice via <mpath> as the20 motion route, so the train can never leave its own track. The engine and the21 car run identical animateMotion timings, but the car starts with a negative22 begin offset, keeping it a fixed phase behind — that's how you couple23 carriages without maths. rotate="auto" turns both into the curves, while the24 wheels spin on their own axes thanks to transform-box: fill-box, which makes25 each wheel rotate around its own center instead of the SVG origin.26customizable:27 - { var: "--sg-color", label: "Train", type: color, default: "#7F77DD" }28 - { var: "--sg-car", label: "Car", type: color, default: "#EFBB33" }29 - { var: "--sg-size", label: "Size", type: range, min: 160, max: 440, default: 260, unit: px }30created: 2026-08-1031-->32<div class="sg-train-track" style="--sg-color:#7F77DD; --sg-car:#EFBB33; --sg-size:260px;">33 <svg viewBox="0 0 200 130" aria-hidden="true" focusable="false">34 <path id="sg-train-track-rail" class="sg-train-track-sleepers"35 d="M 45 25 H 155 A 28 28 0 0 1 183 53 V 77 A 28 28 0 0 1 155 105 H 45 A 28 28 0 0 1 17 77 V 53 A 28 28 0 0 1 45 25 Z" />36 <use href="#sg-train-track-rail" class="sg-train-track-rails" />37 <g class="sg-train-track-car">38 <rect x="-8" y="-8" width="16" height="6.5" rx="1.5" />39 <g class="sg-train-track-wheel"><circle cx="-4" cy="0" r="2.4" /><path d="M-4 -2.4 V2.4 M-6.4 0 H-1.6" /></g>40 <g class="sg-train-track-wheel"><circle cx="4" cy="0" r="2.4" /><path d="M4 -2.4 V2.4 M1.6 0 H6.4" /></g>41 <animateMotion dur="10s" begin="-9.75s" repeatCount="indefinite" rotate="auto">42 <mpath href="#sg-train-track-rail" />43 </animateMotion>44 </g>45 <g class="sg-train-track-engine">46 <rect x="-9" y="-8" width="13" height="7" rx="1.5" />47 <rect x="3" y="-11" width="7" height="10" rx="1.5" />48 <rect x="-7" y="-11.5" width="3" height="4" rx="1" />49 <g class="sg-train-track-wheel"><circle cx="-5" cy="0" r="2.4" /><path d="M-5 -2.4 V2.4 M-7.4 0 H-2.6" /></g>50 <g class="sg-train-track-wheel"><circle cx="5" cy="0" r="2.4" /><path d="M5 -2.4 V2.4 M2.6 0 H7.4" /></g>51 <animateMotion dur="10s" repeatCount="indefinite" rotate="auto">52 <mpath href="#sg-train-track-rail" />53 </animateMotion>54 </g>55 </svg>56</div>57<style>58 .sg-train-track {59 width: var(--sg-size);60 }61 .sg-train-track svg {62 display: block;63 width: 100%;64 }65 .sg-train-track-sleepers {66 fill: none;67 stroke: rgba(128, 128, 128, 0.35);68 stroke-width: 7;69 stroke-dasharray: 1.6 5;70 }71 .sg-train-track-rails {72 fill: none;73 stroke: rgba(128, 128, 128, 0.55);74 stroke-width: 1.6;75 stroke-dasharray: none;76 }77 .sg-train-track-engine rect {78 fill: var(--sg-color);79 }80 .sg-train-track-car rect {81 fill: var(--sg-car);82 }83 .sg-train-track-wheel circle {84 fill: rgba(60, 60, 60, 0.85);85 }86 .sg-train-track-wheel path {87 stroke: rgba(200, 200, 200, 0.9);88 stroke-width: 0.7;89 }90 .sg-train-track-wheel {91 transform-box: fill-box;92 transform-origin: center;93 animation: sg-train-track-spin 0.9s linear infinite;94 }95 @keyframes sg-train-track-spin {96 to { transform: rotate(360deg); }97 }98</style>99