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%
1<!--2 ============================================================3 SVGarden — https://www.svgarden.dev4 Author : Simon-Pierre Boucher5 Contact: contact@spboucher.ai6 File : snippets/backgrounds/rain-window.html7 Desc : Rain streaks on a window with wet-glass refraction8 ============================================================9-->10<!--svgarden11title: Rain on a window12slug: rain-window13category: backgrounds14tags: [background, rain, turbulence, displacement]15difficulty: advanced16techniques: [feTurbulence, feDisplacementMap, animateMotion, staggered-delays]17how_it_works: >18 The refraction is the trick worth stealing: the backdrop gradient is drawn19 twice, and the top copy runs through feTurbulence noise feeding a20 feDisplacementMap, which shoves its pixels around like light bending through21 wet glass. A SMIL animate slowly mutates the noise's baseFrequency so the22 distortion crawls instead of freezing. In front, eight streak lines share23 one falling keyframe with scattered durations and negative delays, while24 two heavier droplets wander down a wobbly animateMotion path — the slow25 droplets against fast streaks give the scene its depth.26customizable: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 }30created: 2026-08-1031-->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>113