SPB Git

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%
3.8 KB · 99 lines html
Raw Blame History
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