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.7 KB · 96 lines html
Raw Blame History
1<!--2  ============================================================3  SVGarden — https://www.svgarden.dev4  Author : Simon-Pierre Boucher5  Contact: contact@spboucher.ai6  File   : snippets/buttons/btn-goo-blob.html7  Desc   : Gooey blob splash bursting from behind the button on hover8  ============================================================9-->10<!--svgarden11title: Goo blob button12slug: btn-goo-blob13category: buttons14tags: [button, goo, filter, hover]15difficulty: advanced16techniques: [feGaussianBlur, feColorMatrix, goo-filter, transform-stagger]17how_it_works: >18  The gooey look is a two-step SVG filter: feGaussianBlur smears the pill and19  its satellite circles into one soft cloud, then feColorMatrix multiplies the20  alpha channel by 19 and subtracts 9, which slams soft edges back to hard ones21  — but only where blurred shapes overlap enough, so nearby shapes appear to22  fuse like liquid. On hover the satellites simply translate outward; every23  merge and pinch-off you see is the matrix doing the work. The label lives in24  plain HTML above the filtered SVG, because running text through a goo filter25  turns it to mush.26customizable:27  - { var: "--sg-color",    label: "Goo color", type: color, default: "#7F77DD" }28  - { var: "--sg-size",     label: "Width",     type: range, min: 120, max: 240, default: 160, unit: px }29  - { var: "--sg-duration", label: "Speed",     type: range, min: 0.2, max: 1.5, step: 0.05, default: 0.5, unit: s }30created: 2026-08-1031-->32<button class="sg-btn-goo-blob" type="button" style="--sg-color:#7F77DD; --sg-size:160px; --sg-duration:0.5s;">33  <svg viewBox="0 0 160 80" aria-hidden="true" focusable="false">34    <defs>35      <filter id="sg-btn-goo-blob-goo" x="-30%" y="-60%" width="160%" height="220%">36        <feGaussianBlur in="SourceGraphic" stdDeviation="8" result="sg-btn-goo-blob-blur" />37        <feColorMatrix in="sg-btn-goo-blob-blur" mode="matrix"38          values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 19 -9" />39      </filter>40    </defs>41    <g class="sg-btn-goo-blob-goop">42      <rect x="20" y="24" width="120" height="32" rx="16" />43      <circle class="sg-btn-goo-blob-b1" cx="80" cy="40" r="9" />44      <circle class="sg-btn-goo-blob-b2" cx="80" cy="40" r="7" />45      <circle class="sg-btn-goo-blob-b3" cx="80" cy="40" r="8" />46      <circle class="sg-btn-goo-blob-b4" cx="80" cy="40" r="6" />47    </g>48  </svg>49  <span class="sg-btn-goo-blob-label">Hover the goo</span>50</button>51<style>52  .sg-btn-goo-blob {53    position: relative;54    appearance: none;55    border: 0;56    background: transparent;57    padding: 0;58    width: var(--sg-size);59    aspect-ratio: 2 / 1;60    cursor: pointer;61    font: inherit;62  }63  .sg-btn-goo-blob svg {64    position: absolute;65    inset: 0;66    width: 100%;67    height: 100%;68    overflow: visible;69  }70  .sg-btn-goo-blob-goop {71    fill: var(--sg-color);72    filter: url(#sg-btn-goo-blob-goo);73  }74  .sg-btn-goo-blob circle {75    transition: transform var(--sg-duration) cubic-bezier(0.3, 1.6, 0.5, 1);76  }77  .sg-btn-goo-blob-label {78    position: absolute;79    inset: 0;80    display: grid;81    place-items: center;82    color: #ffffff;83    font-weight: 600;84    font-size: calc(var(--sg-size) / 11);85    pointer-events: none;86  }87  .sg-btn-goo-blob:hover .sg-btn-goo-blob-b1,88  .sg-btn-goo-blob:focus-visible .sg-btn-goo-blob-b1 { transform: translate(-62px, -18px); }89  .sg-btn-goo-blob:hover .sg-btn-goo-blob-b2,90  .sg-btn-goo-blob:focus-visible .sg-btn-goo-blob-b2 { transform: translate(58px, -22px); }91  .sg-btn-goo-blob:hover .sg-btn-goo-blob-b3,92  .sg-btn-goo-blob:focus-visible .sg-btn-goo-blob-b3 { transform: translate(-48px, 20px); }93  .sg-btn-goo-blob:hover .sg-btn-goo-blob-b4,94  .sg-btn-goo-blob:focus-visible .sg-btn-goo-blob-b4 { transform: translate(52px, 24px); }95</style>96