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%
4.3 KB · 112 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/orbit-planets.html7  Desc   : Mini solar system — planets on elliptical CSS offset-path orbits8  ============================================================9-->10<!--svgarden11title: Orbiting planets12slug: orbit-planets13category: motion-path14tags: [motion, orbit, planets, offset-path]15difficulty: advanced16techniques: [offset-path, offset-distance, "@supports", nested-transforms]17how_it_works: >18  Each planet is pinned to an invisible ellipse with offset-path: path('…') and19  flown around it by animating a single property, offset-distance, from 0% to20  100% — the browser handles all the trigonometry. The three orbits share one21  keyframe block and differ only in animation-duration, so their alignments22  drift like a real system. The moon is a nested transform: a carrier group23  rotating about its local origin, which offset-path has already parked on the24  planet. Everything sits inside an @supports guard, so browsers without25  offset-path simply show the planets resting on their rails.26support: >27  CSS offset-path on SVG children needs Chrome 116+, Safari 16+ or Firefox 122+.28  Unsupported browsers show a static system (planets resting on their orbit29  rails); the moon keeps spinning either way.30customizable:31  - { var: "--sg-sun",      label: "Sun",     type: color, default: "#EFBB33" }32  - { var: "--sg-color",    label: "Planets", type: color, default: "#7F77DD" }33  - { var: "--sg-size",     label: "Size",    type: range, min: 140, max: 420, default: 240, unit: px }34  - { var: "--sg-duration", label: "Year",    type: range, min: 2, max: 14, step: 0.5, default: 6, unit: s }35created: 2026-08-1036-->37<div class="sg-orbit-planets" style="--sg-sun:#EFBB33; --sg-color:#7F77DD; --sg-size:240px; --sg-duration:6s;">38  <svg viewBox="0 0 200 140" aria-hidden="true" focusable="false">39    <ellipse class="sg-orbit-planets-rail" cx="100" cy="70" rx="38" ry="20" />40    <ellipse class="sg-orbit-planets-rail" cx="100" cy="70" rx="64" ry="36" />41    <ellipse class="sg-orbit-planets-rail" cx="100" cy="70" rx="88" ry="52" />42    <circle class="sg-orbit-planets-sun" cx="100" cy="70" r="9" />43    <circle class="sg-orbit-planets-p sg-orbit-planets-p1" r="3.4" />44    <g class="sg-orbit-planets-p sg-orbit-planets-p2">45      <circle class="sg-orbit-planets-body" r="4.6" />46      <g class="sg-orbit-planets-moon-orbit">47        <circle class="sg-orbit-planets-moon" cx="8.5" cy="0" r="1.6" />48      </g>49    </g>50    <circle class="sg-orbit-planets-p sg-orbit-planets-p3" r="2.6" />51  </svg>52</div>53<style>54  .sg-orbit-planets {55    width: var(--sg-size);56  }57  .sg-orbit-planets svg {58    display: block;59    width: 100%;60  }61  .sg-orbit-planets-rail {62    fill: none;63    stroke: rgba(128, 128, 128, 0.35);64    stroke-width: 1;65    stroke-dasharray: 2 3;66  }67  .sg-orbit-planets-sun {68    fill: var(--sg-sun);69  }70  .sg-orbit-planets-p,71  .sg-orbit-planets-body {72    fill: var(--sg-color);73  }74  .sg-orbit-planets-p1 { opacity: 0.9;  transform: translate(62px, 70px); }75  .sg-orbit-planets-p2 { transform: translate(164px, 70px); }76  .sg-orbit-planets-p3 { opacity: 0.55; transform: translate(100px, 122px); }77  .sg-orbit-planets-moon {78    fill: var(--sg-color);79    opacity: 0.7;80  }81  .sg-orbit-planets-moon-orbit {82    transform-origin: 0 0;83    animation: sg-orbit-planets-spin 2.2s linear infinite;84  }85  @supports (offset-path: path('M0 0 L1 1')) {86    .sg-orbit-planets-p {87      transform: none;88      offset-rotate: 0deg;89      animation: sg-orbit-planets-fly var(--sg-duration) linear infinite;90    }91    .sg-orbit-planets-p1 {92      offset-path: path('M62 70 a38 20 0 1 1 76 0 a38 20 0 1 1 -76 0');93    }94    .sg-orbit-planets-p2 {95      offset-path: path('M36 70 a64 36 0 1 1 128 0 a64 36 0 1 1 -128 0');96      animation-duration: calc(var(--sg-duration) * 1.9);97      animation-delay: calc(var(--sg-duration) * -0.7);98    }99    .sg-orbit-planets-p3 {100      offset-path: path('M12 70 a88 52 0 1 1 176 0 a88 52 0 1 1 -176 0');101      animation-duration: calc(var(--sg-duration) * 3.1);102      animation-delay: calc(var(--sg-duration) * -1.4);103    }104  }105  @keyframes sg-orbit-planets-fly {106    to { offset-distance: 100%; }107  }108  @keyframes sg-orbit-planets-spin {109    to { transform: rotate(360deg); }110  }111</style>112