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%
2.8 KB · 79 lines html
Raw Blame History
1<!--2  ============================================================3  SVGarden — https://www.svgarden.dev4  Author : Simon-Pierre Boucher5  Contact: contact@spboucher.ai6  File   : snippets/morph/play-pause-morph.html7  Desc   : Play ⇄ pause icon morph on click8  ============================================================9-->10<!--svgarden11title: Play ⇄ pause morph12slug: play-pause-morph13category: morph14tags: [morph, play, pause, button, js]15difficulty: advanced16techniques: [css-d-property, matched-path-structure, transition, aria-pressed]17how_it_works: >18  The play triangle is secretly two quadrilaterals sharing an edge, because the19  pause icon is two quadrilaterals too — matching point counts is what lets the20  shapes tween. The script only flips aria-pressed and writes each path's new21  d into style.d; the CSS transition on the d property does the actual morph.22  Browsers without CSS d support (older Safari) still swap icons instantly via23  the attribute fallback, so the button never breaks.24customizable:25  - { var: "--sg-color", label: "Color", type: color, default: "#7F77DD" }26  - { var: "--sg-size",  label: "Size",  type: range, min: 32, max: 140, default: 64, unit: px }27created: 2026-08-1028-->29<button class="sg-play-pause-morph" type="button" aria-pressed="false" aria-label="Play" style="--sg-color:#7F77DD; --sg-size:64px;">30  <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">31    <path d="M8 5 L13 7.1 L13 16.9 L8 19 Z" />32    <path d="M13 7.1 L18 9.2 L18 14.8 L13 16.9 Z" />33  </svg>34</button>35<script>36  document.querySelectorAll('.sg-play-pause-morph:not([data-sg-init])').forEach(function (btn) {37    btn.setAttribute('data-sg-init', '');38    var shapes = {39      play:  ['M8 5 L13 7.1 L13 16.9 L8 19 Z', 'M13 7.1 L18 9.2 L18 14.8 L13 16.9 Z'],40      pause: ['M7 5 L11 5 L11 19 L7 19 Z', 'M14.5 5 L18.5 5 L18.5 19 L14.5 19 Z']41    };42    btn.addEventListener('click', function () {43      var playing = btn.getAttribute('aria-pressed') !== 'true';44      btn.setAttribute('aria-pressed', playing);45      btn.setAttribute('aria-label', playing ? 'Pause' : 'Play');46      btn.querySelectorAll('path').forEach(function (p, i) {47        var d = shapes[playing ? 'pause' : 'play'][i];48        p.setAttribute('d', d);49        p.style.d = 'path("' + d + '")';50      });51    });52  });53</script>54<style>55  .sg-play-pause-morph {56    appearance: none;57    border: 2px solid var(--sg-color);58    border-radius: 50%;59    background: transparent;60    cursor: pointer;61    width: var(--sg-size);62    height: var(--sg-size);63    display: inline-grid;64    place-items: center;65    transition: background 0.2s ease;66  }67  .sg-play-pause-morph:hover {68    background: rgba(127, 119, 221, 0.12);69  }70  .sg-play-pause-morph svg {71    width: 62%;72    height: 62%;73  }74  .sg-play-pause-morph path {75    fill: var(--sg-color);76    transition: d 0.35s ease;77  }78</style>79