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.6 KB · 74 lines html
Raw Blame History
1<!--2  ============================================================3  SVGarden — https://www.svgarden.dev4  Author : Simon-Pierre Boucher5  Contact: contact@spboucher.ai6  File   : snippets/backgrounds/dots-drift.html7  Desc   : Subtle drifting dot-grid pattern background8  ============================================================9-->10<!--svgarden11title: Drifting dots12slug: dots-drift13category: backgrounds14tags: [background, pattern, dots, ambient]15difficulty: intermediate16techniques: [svg-pattern, translate-property, seamless-tiling, layered-opacity]17how_it_works: >18  A <pattern> tile of one dot fills two oversized rects. Because a pattern is19  periodic, translating a rect by exactly one tile (28 units) returns it to a20  pixel-identical state, so the infinite drift never shows a seam — the rects21  are drawn larger than the viewport to hide the moving edges. The two layers22  drift in opposite diagonals at different speeds, which adds quiet depth23  without ever pulling focus from the content above.24customizable:25  - { var: "--sg-color",    label: "Dot color", type: color, default: "#7F77DD" }26  - { var: "--sg-size",     label: "Height",    type: range, min: 80, max: 260, default: 150, unit: px }27  - { var: "--sg-duration", label: "Speed",     type: range, min: 2, max: 20, step: 0.5, default: 8, unit: s }28created: 2026-08-1029-->30<div class="sg-dots-drift" style="--sg-color:#7F77DD; --sg-size:150px; --sg-duration:8s;">31  <svg viewBox="0 0 280 140" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false">32    <defs>33      <pattern id="sg-dots-drift-tile" width="28" height="28" patternUnits="userSpaceOnUse">34        <circle cx="4" cy="4" r="2.2" />35      </pattern>36    </defs>37    <rect class="sg-dots-drift-a" x="-28" y="-28" width="340" height="200" fill="url(#sg-dots-drift-tile)" />38    <rect class="sg-dots-drift-b" x="-28" y="-28" width="340" height="200" fill="url(#sg-dots-drift-tile)" />39  </svg>40</div>41<style>42  .sg-dots-drift {43    width: 100%;44    min-width: 240px;45    height: var(--sg-size);46    overflow: hidden;47    border-radius: 8px;48  }49  .sg-dots-drift svg {50    display: block;51    width: 100%;52    height: 100%;53  }54  .sg-dots-drift circle {55    fill: var(--sg-color);56  }57  .sg-dots-drift-a {58    opacity: 0.35;59    animation: sg-dots-drift-se var(--sg-duration) linear infinite;60  }61  .sg-dots-drift-b {62    opacity: 0.18;63    animation: sg-dots-drift-nw calc(var(--sg-duration) * 1.7) linear infinite;64  }65  @keyframes sg-dots-drift-se {66    from { translate: 0 0; }67    to   { translate: 28px 28px; }68  }69  @keyframes sg-dots-drift-nw {70    from { translate: 14px 14px; }71    to   { translate: -14px -14px; }72  }73</style>74