feat(snippets): grow backgrounds category (+5 next-level)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Showing 5 changed files with +502 and −0
added
snippets/backgrounds/aurora-veil.html
+100 −0
@@ -0,0 +1,100 @@ | ||
| 1 | +<!-- | |
| 2 | + ============================================================ | |
| 3 | + SVGarden — https://www.svgarden.dev | |
| 4 | + Author : Simon-Pierre Boucher | |
| 5 | + Contact: contact@spboucher.ai | |
| 6 | + File : snippets/backgrounds/aurora-veil.html | |
| 7 | + Desc : Northern-lights aurora ribbons drifting over a night sky | |
| 8 | + ============================================================ | |
| 9 | +--> | |
| 10 | +<!--svgarden | |
| 11 | +title: Aurora veil | |
| 12 | +slug: aurora-veil | |
| 13 | +category: backgrounds | |
| 14 | +tags: [background, aurora, blend-mode, blur] | |
| 15 | +difficulty: advanced | |
| 16 | +techniques: ["mix-blend-mode", "blur()", periodic-paths, translate-property, layered-opacity] | |
| 17 | +how_it_works: > | |
| 18 | + Each ribbon is one very wide stroked path whose curve repeats every 300 | |
| 19 | + units, so animating the modern translate property by exactly one period | |
| 20 | + loops with no visible seam. A heavy CSS blur() turns the hard strokes into | |
| 21 | + soft light, and mix-blend-mode: screen makes overlapping ribbons add their | |
| 22 | + light together the way real aurora curtains do against a dark sky. The | |
| 23 | + three layers drift at 1×, 1.6× and 2.3× the base duration, so the | |
| 24 | + composition slowly evolves and only realigns once every few minutes. | |
| 25 | + Where blend modes are unavailable the ribbons simply composite as | |
| 26 | + translucent color — dimmer, but never broken. | |
| 27 | +support: mix-blend-mode on SVG elements needs a modern browser; without it the ribbons fall back to plain translucency. | |
| 28 | +customizable: | |
| 29 | + - { var: "--sg-color", label: "Aurora color", type: color, default: "#52E6A7" } | |
| 30 | + - { var: "--sg-size", label: "Height", type: range, min: 120, max: 320, default: 200, unit: px } | |
| 31 | + - { var: "--sg-duration", label: "Drift speed", type: range, min: 6, max: 40, step: 1, default: 14, unit: s } | |
| 32 | +created: 2026-08-10 | |
| 33 | +--> | |
| 34 | +<div class="sg-aurora-veil" style="--sg-color:#52E6A7; --sg-size:200px; --sg-duration:14s;"> | |
| 35 | + <svg viewBox="0 0 600 200" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"> | |
| 36 | + <defs> | |
| 37 | + <linearGradient id="sg-aurora-veil-sky" x1="0" y1="0" x2="0" y2="1"> | |
| 38 | + <stop offset="0" stop-color="#071022" /> | |
| 39 | + <stop offset="1" stop-color="#161031" /> | |
| 40 | + </linearGradient> | |
| 41 | + </defs> | |
| 42 | + <rect class="sg-aurora-veil-bg" x="0" y="0" width="600" height="200" fill="url(#sg-aurora-veil-sky)" /> | |
| 43 | + <g class="sg-aurora-veil-stars"> | |
| 44 | + <circle cx="60" cy="38" r="1.1" /><circle cx="170" cy="22" r="0.9" /> | |
| 45 | + <circle cx="292" cy="46" r="1.2" /><circle cx="405" cy="18" r="0.8" /> | |
| 46 | + <circle cx="498" cy="52" r="1.1" /><circle cx="552" cy="26" r="0.9" /> | |
| 47 | + </g> | |
| 48 | + <path class="sg-aurora-veil-r1" d="M-20 84 c75 -30 225 30 300 0 c75 -30 225 30 300 0 c75 -30 225 30 300 0" /> | |
| 49 | + <path class="sg-aurora-veil-r2" d="M-20 112 c90 -22 210 24 300 0 c90 -22 210 24 300 0 c90 -22 210 24 300 0" /> | |
| 50 | + <path class="sg-aurora-veil-r3" d="M-20 62 c70 -18 230 20 300 0 c70 -18 230 20 300 0 c70 -18 230 20 300 0" /> | |
| 51 | + </svg> | |
| 52 | +</div> | |
| 53 | +<style> | |
| 54 | + .sg-aurora-veil { | |
| 55 | + width: 100%; | |
| 56 | + min-width: 260px; | |
| 57 | + height: var(--sg-size); | |
| 58 | + overflow: hidden; | |
| 59 | + border-radius: 8px; | |
| 60 | + } | |
| 61 | + .sg-aurora-veil svg { | |
| 62 | + display: block; | |
| 63 | + width: 100%; | |
| 64 | + height: 100%; | |
| 65 | + } | |
| 66 | + .sg-aurora-veil-stars circle { | |
| 67 | + fill: #cdd6f4; | |
| 68 | + opacity: 0.6; | |
| 69 | + } | |
| 70 | + .sg-aurora-veil path { | |
| 71 | + fill: none; | |
| 72 | + stroke-linecap: round; | |
| 73 | + mix-blend-mode: screen; | |
| 74 | + animation: sg-aurora-veil-drift var(--sg-duration) linear infinite; | |
| 75 | + } | |
| 76 | + .sg-aurora-veil-r1 { | |
| 77 | + stroke: var(--sg-color); | |
| 78 | + stroke-width: 38; | |
| 79 | + filter: blur(13px); | |
| 80 | + opacity: 0.75; | |
| 81 | + } | |
| 82 | + .sg-aurora-veil-r2 { | |
| 83 | + stroke: #7f77dd; | |
| 84 | + stroke-width: 30; | |
| 85 | + filter: blur(15px); | |
| 86 | + opacity: 0.6; | |
| 87 | + animation-duration: calc(var(--sg-duration) * 1.6); | |
| 88 | + } | |
| 89 | + .sg-aurora-veil-r3 { | |
| 90 | + stroke: #3ec7de; | |
| 91 | + stroke-width: 22; | |
| 92 | + filter: blur(11px); | |
| 93 | + opacity: 0.5; | |
| 94 | + animation-duration: calc(var(--sg-duration) * 2.3); | |
| 95 | + } | |
| 96 | + @keyframes sg-aurora-veil-drift { | |
| 97 | + from { translate: 0 0; } | |
| 98 | + to { translate: -300px 0; } | |
| 99 | + } | |
| 100 | +</style> | |
added
snippets/backgrounds/constellation-drift.html
+103 −0
@@ -0,0 +1,103 @@ | ||
| 1 | +<!-- | |
| 2 | + ============================================================ | |
| 3 | + SVGarden — https://www.svgarden.dev | |
| 4 | + Author : Simon-Pierre Boucher | |
| 5 | + Contact: contact@spboucher.ai | |
| 6 | + File : snippets/backgrounds/constellation-drift.html | |
| 7 | + Desc : Drifting star field with twinkling constellation lines | |
| 8 | + ============================================================ | |
| 9 | +--> | |
| 10 | +<!--svgarden | |
| 11 | +title: Constellation drift | |
| 12 | +slug: constellation-drift | |
| 13 | +category: backgrounds | |
| 14 | +tags: [background, stars, constellation, ambient] | |
| 15 | +difficulty: intermediate | |
| 16 | +techniques: [svg-use-tiling, translate-property, animation-delay, seamless-tiling] | |
| 17 | +how_it_works: > | |
| 18 | + The whole star field is drawn once as a 320-unit tile, then a <use> element | |
| 19 | + stamps a second copy exactly one tile-width to the right. Animating the | |
| 20 | + group's translate by that same 320 units means frame one and the last frame | |
| 21 | + are pixel-identical — the seamless-loop rule is: duplicate, offset by one | |
| 22 | + period, translate by one period. Twinkling is a single opacity keyframe | |
| 23 | + shared by every star; scattering the stars across three delay groups breaks | |
| 24 | + the synchronization so the sky shimmers instead of blinking. Styles applied | |
| 25 | + to the original tile automatically render in the <use> clone, so the | |
| 26 | + twinkle comes along for free. | |
| 27 | +customizable: | |
| 28 | + - { var: "--sg-color", label: "Star color", type: color, default: "#CFD8FF" } | |
| 29 | + - { var: "--sg-size", label: "Height", type: range, min: 100, max: 300, default: 170, unit: px } | |
| 30 | + - { var: "--sg-duration", label: "Drift speed", type: range, min: 10, max: 80, step: 1, default: 32, unit: s } | |
| 31 | +created: 2026-08-10 | |
| 32 | +--> | |
| 33 | +<div class="sg-constellation-drift" style="--sg-color:#CFD8FF; --sg-size:170px; --sg-duration:32s;"> | |
| 34 | + <svg viewBox="0 0 320 180" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"> | |
| 35 | + <defs> | |
| 36 | + <linearGradient id="sg-constellation-drift-sky" x1="0" y1="0" x2="0" y2="1"> | |
| 37 | + <stop offset="0" stop-color="#0a1228" /> | |
| 38 | + <stop offset="1" stop-color="#151b38" /> | |
| 39 | + </linearGradient> | |
| 40 | + </defs> | |
| 41 | + <rect x="0" y="0" width="320" height="180" fill="url(#sg-constellation-drift-sky)" /> | |
| 42 | + <g class="sg-constellation-drift-roll"> | |
| 43 | + <g id="sg-constellation-drift-tile"> | |
| 44 | + <polyline class="sg-constellation-drift-link" points="34,48 78,30 122,58 150,34" /> | |
| 45 | + <polyline class="sg-constellation-drift-link" points="190,120 232,96 268,128 298,102" /> | |
| 46 | + <polyline class="sg-constellation-drift-link" points="60,140 96,116 140,148" /> | |
| 47 | + <circle class="sg-constellation-drift-s1" cx="34" cy="48" r="1.8" /> | |
| 48 | + <circle class="sg-constellation-drift-s2" cx="78" cy="30" r="1.4" /> | |
| 49 | + <circle class="sg-constellation-drift-s3" cx="122" cy="58" r="1.7" /> | |
| 50 | + <circle class="sg-constellation-drift-s1" cx="150" cy="34" r="1.3" /> | |
| 51 | + <circle class="sg-constellation-drift-s2" cx="190" cy="120" r="1.6" /> | |
| 52 | + <circle class="sg-constellation-drift-s3" cx="232" cy="96" r="1.9" /> | |
| 53 | + <circle class="sg-constellation-drift-s1" cx="268" cy="128" r="1.4" /> | |
| 54 | + <circle class="sg-constellation-drift-s2" cx="298" cy="102" r="1.6" /> | |
| 55 | + <circle class="sg-constellation-drift-s3" cx="60" cy="140" r="1.5" /> | |
| 56 | + <circle class="sg-constellation-drift-s1" cx="96" cy="116" r="1.8" /> | |
| 57 | + <circle class="sg-constellation-drift-s2" cx="140" cy="148" r="1.3" /> | |
| 58 | + <circle class="sg-constellation-drift-s3" cx="205" cy="24" r="1.2" /> | |
| 59 | + <circle class="sg-constellation-drift-s1" cx="255" cy="52" r="1.0" /> | |
| 60 | + <circle class="sg-constellation-drift-s2" cx="20" cy="90" r="1.1" /> | |
| 61 | + <circle class="sg-constellation-drift-s3" cx="305" cy="160" r="1.2" /> | |
| 62 | + </g> | |
| 63 | + <use href="#sg-constellation-drift-tile" x="320" /> | |
| 64 | + </g> | |
| 65 | + </svg> | |
| 66 | +</div> | |
| 67 | +<style> | |
| 68 | + .sg-constellation-drift { | |
| 69 | + width: 100%; | |
| 70 | + min-width: 240px; | |
| 71 | + height: var(--sg-size); | |
| 72 | + overflow: hidden; | |
| 73 | + border-radius: 8px; | |
| 74 | + } | |
| 75 | + .sg-constellation-drift svg { | |
| 76 | + display: block; | |
| 77 | + width: 100%; | |
| 78 | + height: 100%; | |
| 79 | + } | |
| 80 | + .sg-constellation-drift-roll { | |
| 81 | + animation: sg-constellation-drift-move var(--sg-duration) linear infinite; | |
| 82 | + } | |
| 83 | + .sg-constellation-drift-link { | |
| 84 | + fill: none; | |
| 85 | + stroke: var(--sg-color); | |
| 86 | + stroke-width: 0.6; | |
| 87 | + opacity: 0.25; | |
| 88 | + } | |
| 89 | + .sg-constellation-drift circle { | |
| 90 | + fill: var(--sg-color); | |
| 91 | + animation: sg-constellation-drift-twinkle 3.8s ease-in-out infinite; | |
| 92 | + } | |
| 93 | + .sg-constellation-drift-s2 { animation-delay: -1.3s; } | |
| 94 | + .sg-constellation-drift-s3 { animation-delay: -2.6s; } | |
| 95 | + @keyframes sg-constellation-drift-move { | |
| 96 | + from { translate: 0 0; } | |
| 97 | + to { translate: -320px 0; } | |
| 98 | + } | |
| 99 | + @keyframes sg-constellation-drift-twinkle { | |
| 100 | + 0%, 100% { opacity: 1; } | |
| 101 | + 50% { opacity: 0.3; } | |
| 102 | + } | |
| 103 | +</style> | |
added
snippets/backgrounds/mesh-wave-grid.html
+93 −0
@@ -0,0 +1,93 @@ | ||
| 1 | +<!-- | |
| 2 | + ============================================================ | |
| 3 | + SVGarden — https://www.svgarden.dev | |
| 4 | + Author : Simon-Pierre Boucher | |
| 5 | + Contact: contact@spboucher.ai | |
| 6 | + File : snippets/backgrounds/mesh-wave-grid.html | |
| 7 | + Desc : Pseudo-3D wireframe wave grid rolling toward the viewer | |
| 8 | + ============================================================ | |
| 9 | +--> | |
| 10 | +<!--svgarden | |
| 11 | +title: Mesh wave grid | |
| 12 | +slug: mesh-wave-grid | |
| 13 | +category: backgrounds | |
| 14 | +tags: [background, wireframe, pseudo-3d, smil] | |
| 15 | +difficulty: advanced | |
| 16 | +techniques: [SMIL-path-morph, perspective-spacing, phase-offset-begin, layered-opacity] | |
| 17 | +how_it_works: > | |
| 18 | + There is no 3D here — the depth is drawn, not computed. Row spacing widens | |
| 19 | + from 14 units at the horizon to 26 near the viewer, stroke opacity climbs | |
| 20 | + from 0.25 to 0.9, and static rays fan out from a vanishing point; those | |
| 21 | + three perspective cues do all the work. Each row then morphs between the | |
| 22 | + same wave shape and its inverted twin via SMIL, and giving row n a begin | |
| 23 | + offset of −0.55n seconds turns identical animations into a phase gradient, | |
| 24 | + which reads as a swell rolling diagonally across the mesh. Same-structure | |
| 25 | + d strings (one M, two relative curves) keep every tween smooth. | |
| 26 | +customizable: | |
| 27 | + - { var: "--sg-color", label: "Grid color", type: color, default: "#7F77DD" } | |
| 28 | + - { var: "--sg-bg", label: "Sky color", type: color, default: "#0D0B1E" } | |
| 29 | + - { var: "--sg-size", label: "Height", type: range, min: 100, max: 280, default: 170, unit: px } | |
| 30 | +created: 2026-08-10 | |
| 31 | +--> | |
| 32 | +<div class="sg-mesh-wave-grid" style="--sg-color:#7F77DD; --sg-bg:#0D0B1E; --sg-size:170px;"> | |
| 33 | + <svg viewBox="0 0 400 210" preserveAspectRatio="none" aria-hidden="true" focusable="false"> | |
| 34 | + <defs> | |
| 35 | + <linearGradient id="sg-mesh-wave-grid-sky" x1="0" y1="0" x2="0" y2="1"> | |
| 36 | + <stop class="sg-mesh-wave-grid-skytop" offset="0" /> | |
| 37 | + <stop offset="1" stop-color="#05060d" /> | |
| 38 | + </linearGradient> | |
| 39 | + </defs> | |
| 40 | + <rect x="0" y="0" width="400" height="210" fill="url(#sg-mesh-wave-grid-sky)" /> | |
| 41 | + <g class="sg-mesh-wave-grid-rays"> | |
| 42 | + <line x1="200" y1="26" x2="-60" y2="210" /><line x1="200" y1="26" x2="30" y2="210" /> | |
| 43 | + <line x1="200" y1="26" x2="115" y2="210" /><line x1="200" y1="26" x2="200" y2="210" /> | |
| 44 | + <line x1="200" y1="26" x2="285" y2="210" /><line x1="200" y1="26" x2="370" y2="210" /> | |
| 45 | + <line x1="200" y1="26" x2="460" y2="210" /> | |
| 46 | + </g> | |
| 47 | + <g class="sg-mesh-wave-grid-rows"> | |
| 48 | + <path opacity="0.25"><animate attributeName="d" dur="5s" begin="0s" repeatCount="indefinite" | |
| 49 | + values="M0 40 c 66 -3 134 3 200 0 c 66 -3 134 3 200 0;M0 40 c 66 3 134 -3 200 0 c 66 3 134 -3 200 0;M0 40 c 66 -3 134 3 200 0 c 66 -3 134 3 200 0" /></path> | |
| 50 | + <path opacity="0.32"><animate attributeName="d" dur="5s" begin="-0.55s" repeatCount="indefinite" | |
| 51 | + values="M0 54 c 66 -4 134 4 200 0 c 66 -4 134 4 200 0;M0 54 c 66 4 134 -4 200 0 c 66 4 134 -4 200 0;M0 54 c 66 -4 134 4 200 0 c 66 -4 134 4 200 0" /></path> | |
| 52 | + <path opacity="0.4"><animate attributeName="d" dur="5s" begin="-1.1s" repeatCount="indefinite" | |
| 53 | + values="M0 70 c 66 -6 134 6 200 0 c 66 -6 134 6 200 0;M0 70 c 66 6 134 -6 200 0 c 66 6 134 -6 200 0;M0 70 c 66 -6 134 6 200 0 c 66 -6 134 6 200 0" /></path> | |
| 54 | + <path opacity="0.5"><animate attributeName="d" dur="5s" begin="-1.65s" repeatCount="indefinite" | |
| 55 | + values="M0 88 c 66 -7 134 7 200 0 c 66 -7 134 7 200 0;M0 88 c 66 7 134 -7 200 0 c 66 7 134 -7 200 0;M0 88 c 66 -7 134 7 200 0 c 66 -7 134 7 200 0" /></path> | |
| 56 | + <path opacity="0.6"><animate attributeName="d" dur="5s" begin="-2.2s" repeatCount="indefinite" | |
| 57 | + values="M0 108 c 66 -9 134 9 200 0 c 66 -9 134 9 200 0;M0 108 c 66 9 134 -9 200 0 c 66 9 134 -9 200 0;M0 108 c 66 -9 134 9 200 0 c 66 -9 134 9 200 0" /></path> | |
| 58 | + <path opacity="0.7"><animate attributeName="d" dur="5s" begin="-2.75s" repeatCount="indefinite" | |
| 59 | + values="M0 130 c 66 -10 134 10 200 0 c 66 -10 134 10 200 0;M0 130 c 66 10 134 -10 200 0 c 66 10 134 -10 200 0;M0 130 c 66 -10 134 10 200 0 c 66 -10 134 10 200 0" /></path> | |
| 60 | + <path opacity="0.8"><animate attributeName="d" dur="5s" begin="-3.3s" repeatCount="indefinite" | |
| 61 | + values="M0 154 c 66 -12 134 12 200 0 c 66 -12 134 12 200 0;M0 154 c 66 12 134 -12 200 0 c 66 12 134 -12 200 0;M0 154 c 66 -12 134 12 200 0 c 66 -12 134 12 200 0" /></path> | |
| 62 | + <path opacity="0.9"><animate attributeName="d" dur="5s" begin="-3.85s" repeatCount="indefinite" | |
| 63 | + values="M0 180 c 66 -13 134 13 200 0 c 66 -13 134 13 200 0;M0 180 c 66 13 134 -13 200 0 c 66 13 134 -13 200 0;M0 180 c 66 -13 134 13 200 0 c 66 -13 134 13 200 0" /></path> | |
| 64 | + </g> | |
| 65 | + </svg> | |
| 66 | +</div> | |
| 67 | +<style> | |
| 68 | + .sg-mesh-wave-grid { | |
| 69 | + width: 100%; | |
| 70 | + min-width: 240px; | |
| 71 | + height: var(--sg-size); | |
| 72 | + overflow: hidden; | |
| 73 | + border-radius: 8px; | |
| 74 | + } | |
| 75 | + .sg-mesh-wave-grid svg { | |
| 76 | + display: block; | |
| 77 | + width: 100%; | |
| 78 | + height: 100%; | |
| 79 | + } | |
| 80 | + .sg-mesh-wave-grid-skytop { | |
| 81 | + stop-color: var(--sg-bg); | |
| 82 | + } | |
| 83 | + .sg-mesh-wave-grid-rays line { | |
| 84 | + stroke: var(--sg-color); | |
| 85 | + stroke-width: 1; | |
| 86 | + opacity: 0.12; | |
| 87 | + } | |
| 88 | + .sg-mesh-wave-grid-rows path { | |
| 89 | + fill: none; | |
| 90 | + stroke: var(--sg-color); | |
| 91 | + stroke-width: 1.5; | |
| 92 | + } | |
| 93 | +</style> | |
added
snippets/backgrounds/rain-window.html
+112 −0
@@ -0,0 +1,112 @@ | ||
| 1 | +<!-- | |
| 2 | + ============================================================ | |
| 3 | + SVGarden — https://www.svgarden.dev | |
| 4 | + Author : Simon-Pierre Boucher | |
| 5 | + Contact: contact@spboucher.ai | |
| 6 | + File : snippets/backgrounds/rain-window.html | |
| 7 | + Desc : Rain streaks on a window with wet-glass refraction | |
| 8 | + ============================================================ | |
| 9 | +--> | |
| 10 | +<!--svgarden | |
| 11 | +title: Rain on a window | |
| 12 | +slug: rain-window | |
| 13 | +category: backgrounds | |
| 14 | +tags: [background, rain, turbulence, displacement] | |
| 15 | +difficulty: advanced | |
| 16 | +techniques: [feTurbulence, feDisplacementMap, animateMotion, staggered-delays] | |
| 17 | +how_it_works: > | |
| 18 | + The refraction is the trick worth stealing: the backdrop gradient is drawn | |
| 19 | + twice, and the top copy runs through feTurbulence noise feeding a | |
| 20 | + feDisplacementMap, which shoves its pixels around like light bending through | |
| 21 | + wet glass. A SMIL animate slowly mutates the noise's baseFrequency so the | |
| 22 | + distortion crawls instead of freezing. In front, eight streak lines share | |
| 23 | + one falling keyframe with scattered durations and negative delays, while | |
| 24 | + two heavier droplets wander down a wobbly animateMotion path — the slow | |
| 25 | + droplets against fast streaks give the scene its depth. | |
| 26 | +customizable: | |
| 27 | + - { var: "--sg-color", label: "Glass tint", type: color, default: "#31445A" } | |
| 28 | + - { var: "--sg-size", label: "Height", type: range, min: 100, max: 300, default: 180, unit: px } | |
| 29 | + - { var: "--sg-duration", label: "Rain speed", type: range, min: 0.8, max: 4, step: 0.1, default: 1.6, unit: s } | |
| 30 | +created: 2026-08-10 | |
| 31 | +--> | |
| 32 | +<div class="sg-rain-window" style="--sg-color:#31445A; --sg-size:180px; --sg-duration:1.6s;"> | |
| 33 | + <svg viewBox="0 0 320 180" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"> | |
| 34 | + <defs> | |
| 35 | + <linearGradient id="sg-rain-window-sky" x1="0" y1="0" x2="0" y2="1"> | |
| 36 | + <stop class="sg-rain-window-tint" offset="0" /> | |
| 37 | + <stop offset="1" stop-color="#0f1722" /> | |
| 38 | + </linearGradient> | |
| 39 | + <filter id="sg-rain-window-warp" x="-10%" y="-10%" width="120%" height="120%"> | |
| 40 | + <feTurbulence type="fractalNoise" baseFrequency="0.012 0.05" numOctaves="2" result="sg-noise"> | |
| 41 | + <animate attributeName="baseFrequency" dur="9s" repeatCount="indefinite" | |
| 42 | + values="0.012 0.05;0.016 0.06;0.012 0.05" /> | |
| 43 | + </feTurbulence> | |
| 44 | + <feDisplacementMap in="SourceGraphic" in2="sg-noise" scale="16" /> | |
| 45 | + </filter> | |
| 46 | + </defs> | |
| 47 | + <rect x="0" y="0" width="320" height="180" fill="url(#sg-rain-window-sky)" /> | |
| 48 | + <rect class="sg-rain-window-wet" x="-20" y="-20" width="360" height="220" fill="url(#sg-rain-window-sky)" /> | |
| 49 | + <g class="sg-rain-window-streaks"> | |
| 50 | + <line x1="30" y1="-30" x2="27" y2="-6" /> | |
| 51 | + <line x1="74" y1="-42" x2="71" y2="-14" /> | |
| 52 | + <line x1="118" y1="-26" x2="115" y2="-4" /> | |
| 53 | + <line x1="162" y1="-38" x2="159" y2="-10" /> | |
| 54 | + <line x1="206" y1="-30" x2="203" y2="-8" /> | |
| 55 | + <line x1="248" y1="-44" x2="245" y2="-16" /> | |
| 56 | + <line x1="284" y1="-28" x2="281" y2="-6" /> | |
| 57 | + <line x1="308" y1="-40" x2="305" y2="-14" /> | |
| 58 | + </g> | |
| 59 | + <circle class="sg-rain-window-drop1" cx="96" cy="0" r="2.6"> | |
| 60 | + <animateMotion dur="8s" begin="-2s" repeatCount="indefinite" | |
| 61 | + path="M0 -10 q 4 30 -3 58 q -5 26 2 52 q 5 26 -2 50 q -4 20 1 44" /> | |
| 62 | + </circle> | |
| 63 | + <circle class="sg-rain-window-drop2" cx="228" cy="0" r="2.1"> | |
| 64 | + <animateMotion dur="11s" begin="-6s" repeatCount="indefinite" | |
| 65 | + path="M0 -10 q -4 34 3 62 q 5 28 -3 54 q -4 24 3 48 q 3 18 -2 40" /> | |
| 66 | + </circle> | |
| 67 | + </svg> | |
| 68 | +</div> | |
| 69 | +<style> | |
| 70 | + .sg-rain-window { | |
| 71 | + width: 100%; | |
| 72 | + min-width: 240px; | |
| 73 | + height: var(--sg-size); | |
| 74 | + overflow: hidden; | |
| 75 | + border-radius: 8px; | |
| 76 | + } | |
| 77 | + .sg-rain-window svg { | |
| 78 | + display: block; | |
| 79 | + width: 100%; | |
| 80 | + height: 100%; | |
| 81 | + } | |
| 82 | + .sg-rain-window-tint { | |
| 83 | + stop-color: var(--sg-color); | |
| 84 | + } | |
| 85 | + .sg-rain-window-wet { | |
| 86 | + filter: url(#sg-rain-window-warp); | |
| 87 | + opacity: 0.75; | |
| 88 | + } | |
| 89 | + .sg-rain-window-streaks line { | |
| 90 | + stroke: #dbe6f3; | |
| 91 | + stroke-width: 1.4; | |
| 92 | + stroke-linecap: round; | |
| 93 | + opacity: 0.32; | |
| 94 | + animation: sg-rain-window-fall var(--sg-duration) linear infinite; | |
| 95 | + } | |
| 96 | + .sg-rain-window-streaks line:nth-of-type(2) { animation-duration: calc(var(--sg-duration) * 0.8); animation-delay: calc(var(--sg-duration) * -0.4); } | |
| 97 | + .sg-rain-window-streaks line:nth-of-type(3) { animation-duration: calc(var(--sg-duration) * 1.25); animation-delay: calc(var(--sg-duration) * -0.9); } | |
| 98 | + .sg-rain-window-streaks line:nth-of-type(4) { animation-duration: calc(var(--sg-duration) * 0.7); animation-delay: calc(var(--sg-duration) * -0.2); } | |
| 99 | + .sg-rain-window-streaks line:nth-of-type(5) { animation-duration: calc(var(--sg-duration) * 1.1); animation-delay: calc(var(--sg-duration) * -0.7); } | |
| 100 | + .sg-rain-window-streaks line:nth-of-type(6) { animation-duration: calc(var(--sg-duration) * 0.85); animation-delay: calc(var(--sg-duration) * -0.55); } | |
| 101 | + .sg-rain-window-streaks line:nth-of-type(7) { animation-duration: calc(var(--sg-duration) * 1.3); animation-delay: calc(var(--sg-duration) * -0.3); } | |
| 102 | + .sg-rain-window-streaks line:nth-of-type(8) { animation-duration: calc(var(--sg-duration) * 0.75); animation-delay: calc(var(--sg-duration) * -0.65); } | |
| 103 | + .sg-rain-window-drop1, | |
| 104 | + .sg-rain-window-drop2 { | |
| 105 | + fill: #e7eef8; | |
| 106 | + opacity: 0.5; | |
| 107 | + } | |
| 108 | + @keyframes sg-rain-window-fall { | |
| 109 | + from { transform: translateY(0); } | |
| 110 | + to { transform: translateY(230px); } | |
| 111 | + } | |
| 112 | +</style> | |
added
snippets/backgrounds/topo-lines-morph.html
+94 −0
@@ -0,0 +1,94 @@ | ||
| 1 | +<!-- | |
| 2 | + ============================================================ | |
| 3 | + SVGarden — https://www.svgarden.dev | |
| 4 | + Author : Simon-Pierre Boucher | |
| 5 | + Contact: contact@spboucher.ai | |
| 6 | + File : snippets/backgrounds/topo-lines-morph.html | |
| 7 | + Desc : Topographic contour lines slowly morphing, map-style | |
| 8 | + ============================================================ | |
| 9 | +--> | |
| 10 | +<!--svgarden | |
| 11 | +title: Topo lines morph | |
| 12 | +slug: topo-lines-morph | |
| 13 | +category: backgrounds | |
| 14 | +tags: [background, topographic, morph, smil] | |
| 15 | +difficulty: advanced | |
| 16 | +techniques: [SMIL-path-morph, matched-path-structure, staggered-durations, layered-opacity] | |
| 17 | +how_it_works: > | |
| 18 | + Five nested contour rings each morph between two variants of themselves with | |
| 19 | + a SMIL animate on the d attribute — and as with every path morph, the two | |
| 20 | + variants must share the exact same command skeleton (here one M plus four | |
| 21 | + cubics) or the browser snaps instead of tweening. The meditative quality | |
| 22 | + comes from the timing design: every ring gets a different duration and a | |
| 23 | + negative begin offset, so no two contours ever breathe in phase, exactly | |
| 24 | + like elevation lines redrawn between survey years. Opacity falls off toward | |
| 25 | + the outer rings to fake the fading detail of a real map. | |
| 26 | +customizable: | |
| 27 | + - { var: "--sg-color", label: "Contour color", type: color, default: "#7F77DD" } | |
| 28 | + - { var: "--sg-bg", label: "Map background", type: color, default: "#101623" } | |
| 29 | + - { var: "--sg-size", label: "Height", type: range, min: 100, max: 300, default: 180, unit: px } | |
| 30 | +created: 2026-08-10 | |
| 31 | +--> | |
| 32 | +<div class="sg-topo-lines-morph" style="--sg-color:#7F77DD; --sg-bg:#101623; --sg-size:180px;"> | |
| 33 | + <svg viewBox="0 0 240 160" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"> | |
| 34 | + <rect class="sg-topo-lines-morph-paper" x="0" y="0" width="240" height="160" /> | |
| 35 | + <g class="sg-topo-lines-morph-rings"> | |
| 36 | + <path opacity="0.95"> | |
| 37 | + <animate attributeName="d" dur="14s" begin="-2s" repeatCount="indefinite" | |
| 38 | + values="M130 78 C130 84.6 124.6 90 118 90 C111.4 90 106 84.6 106 78 C106 71.4 111.4 66 118 66 C124.6 66 130 71.4 130 78 Z; | |
| 39 | + M133 77 C132 84 125 92 117 91 C110 90 104 84 105 77 C106 70 112 65 119 66 C126 67 134 70 133 77 Z; | |
| 40 | + M130 78 C130 84.6 124.6 90 118 90 C111.4 90 106 84.6 106 78 C106 71.4 111.4 66 118 66 C124.6 66 130 71.4 130 78 Z" /> | |
| 41 | + </path> | |
| 42 | + <path opacity="0.8"> | |
| 43 | + <animate attributeName="d" dur="18s" begin="-5s" repeatCount="indefinite" | |
| 44 | + values="M144 78 C144 92.4 132.4 104 118 104 C103.6 104 92 92.4 92 78 C92 63.6 103.6 52 118 52 C132.4 52 144 63.6 144 78 Z; | |
| 45 | + M149 75 C147 90 134 108 116 106 C100 104 88 92 90 75 C92 60 104 49 120 51 C136 53 151 60 149 75 Z; | |
| 46 | + M144 78 C144 92.4 132.4 104 118 104 C103.6 104 92 92.4 92 78 C92 63.6 103.6 52 118 52 C132.4 52 144 63.6 144 78 Z" /> | |
| 47 | + </path> | |
| 48 | + <path opacity="0.65"> | |
| 49 | + <animate attributeName="d" dur="22s" begin="-8s" repeatCount="indefinite" | |
| 50 | + values="M158 78 C158 100 140 118 118 118 C96 118 78 100 78 78 C78 56 96 38 118 38 C140 38 158 56 158 78 Z; | |
| 51 | + M164 74 C162 96 142 122 116 119 C92 116 72 98 75 74 C78 52 96 35 121 38 C144 41 166 52 164 74 Z; | |
| 52 | + M158 78 C158 100 140 118 118 118 C96 118 78 100 78 78 C78 56 96 38 118 38 C140 38 158 56 158 78 Z" /> | |
| 53 | + </path> | |
| 54 | + <path opacity="0.5"> | |
| 55 | + <animate attributeName="d" dur="26s" begin="-11s" repeatCount="indefinite" | |
| 56 | + values="M172 78 C172 107.8 147.8 132 118 132 C88.2 132 64 107.8 64 78 C64 48.2 88.2 24 118 24 C147.8 24 172 48.2 172 78 Z; | |
| 57 | + M179 73 C176 102 152 136 115 132 C82 128 58 106 61 73 C64 44 88 21 122 25 C152 29 182 44 179 73 Z; | |
| 58 | + M172 78 C172 107.8 147.8 132 118 132 C88.2 132 64 107.8 64 78 C64 48.2 88.2 24 118 24 C147.8 24 172 48.2 172 78 Z" /> | |
| 59 | + </path> | |
| 60 | + <path opacity="0.35"> | |
| 61 | + <animate attributeName="d" dur="30s" begin="-14s" repeatCount="indefinite" | |
| 62 | + values="M186 78 C186 115.5 155.5 146 118 146 C80.5 146 50 115.5 50 78 C50 40.5 80.5 10 118 10 C155.5 10 186 40.5 186 78 Z; | |
| 63 | + M193 72 C189 108 158 150 114 145 C76 141 44 112 48 72 C52 36 82 8 124 12 C158 15 197 36 193 72 Z; | |
| 64 | + M186 78 C186 115.5 155.5 146 118 146 C80.5 146 50 115.5 50 78 C50 40.5 80.5 10 118 10 C155.5 10 186 40.5 186 78 Z" /> | |
| 65 | + </path> | |
| 66 | + </g> | |
| 67 | + <circle class="sg-topo-lines-morph-peak" cx="118" cy="78" r="2" /> | |
| 68 | + </svg> | |
| 69 | +</div> | |
| 70 | +<style> | |
| 71 | + .sg-topo-lines-morph { | |
| 72 | + width: 100%; | |
| 73 | + min-width: 240px; | |
| 74 | + height: var(--sg-size); | |
| 75 | + overflow: hidden; | |
| 76 | + border-radius: 8px; | |
| 77 | + } | |
| 78 | + .sg-topo-lines-morph svg { | |
| 79 | + display: block; | |
| 80 | + width: 100%; | |
| 81 | + height: 100%; | |
| 82 | + } | |
| 83 | + .sg-topo-lines-morph-paper { | |
| 84 | + fill: var(--sg-bg); | |
| 85 | + } | |
| 86 | + .sg-topo-lines-morph-rings path { | |
| 87 | + fill: none; | |
| 88 | + stroke: var(--sg-color); | |
| 89 | + stroke-width: 1.6; | |
| 90 | + } | |
| 91 | + .sg-topo-lines-morph-peak { | |
| 92 | + fill: var(--sg-color); | |
| 93 | + } | |
| 94 | +</style> | |
| 95 | ||