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/filters/heat-shimmer.html7 Desc : Heat-haze shimmer rising over a flame8 ============================================================9-->10<!--svgarden11title: Heat shimmer12slug: heat-shimmer13category: filters14tags: [filter, heat, shimmer, flame]15difficulty: intermediate16techniques: [feTurbulence, feOffset-scrolling-noise, feDisplacementMap, gradient-mask]17how_it_works: >18 Heat haze is displacement that travels: feTurbulence generates a stretched19 noise field (stitchTiles keeps it seamless), a SMIL-animated feOffset scrolls20 that field upward, and feDisplacementMap warps the flame with whatever noise21 is currently passing through — so the wobble visibly rises like hot air.22 The trick that sells it is the second, unfiltered flame on top, masked by a23 vertical gradient: opaque at the base and transparent at the tip, it keeps24 the bottom rock-solid so the shimmer appears to grow with height, the way25 real convection does.26customizable:27 - { var: "--sg-color", label: "Flame", type: color, default: "#E8853C" }28 - { var: "--sg-size", label: "Size", type: range, min: 60, max: 220, default: 110, unit: px }29created: 2026-08-1030-->31<div class="sg-heat-shimmer" style="--sg-color:#E8853C; --sg-size:110px;">32 <svg viewBox="0 0 120 140" aria-hidden="true" focusable="false">33 <defs>34 <path id="sg-heat-shimmer-flame"35 d="M60 16 C 72 38, 92 52, 92 84 A32 32 0 0 1 28 84 C 28 52, 48 38, 60 16 Z" />36 <filter id="sg-heat-shimmer-f" x="-30%" y="-40%" width="160%" height="180%">37 <feTurbulence type="fractalNoise" baseFrequency="0.03 0.12" numOctaves="2"38 seed="3" stitchTiles="stitch" result="n" />39 <feOffset in="n" dx="0" dy="0" result="sn">40 <animate attributeName="dy" from="0" to="-50" dur="2.4s" repeatCount="indefinite" />41 </feOffset>42 <feDisplacementMap in="SourceGraphic" in2="sn" scale="9"43 xChannelSelector="R" yChannelSelector="G" />44 </filter>45 <linearGradient id="sg-heat-shimmer-grad" x1="0" y1="1" x2="0" y2="0">46 <stop offset="0.25" stop-color="white" />47 <stop offset="0.85" stop-color="black" />48 </linearGradient>49 <mask id="sg-heat-shimmer-solid">50 <rect x="0" y="0" width="120" height="140" fill="url(#sg-heat-shimmer-grad)" />51 </mask>52 </defs>53 <use class="sg-heat-shimmer-hazy" href="#sg-heat-shimmer-flame" filter="url(#sg-heat-shimmer-f)" />54 <use class="sg-heat-shimmer-base" href="#sg-heat-shimmer-flame" mask="url(#sg-heat-shimmer-solid)" />55 <path class="sg-heat-shimmer-core" d="M60 62 C 66 76, 76 82, 76 96 A16 16 0 0 1 44 96 C 44 82, 54 76, 60 62 Z" />56 </svg>57</div>58<style>59 .sg-heat-shimmer {60 width: var(--sg-size);61 }62 .sg-heat-shimmer svg {63 display: block;64 width: 100%;65 }66 .sg-heat-shimmer-hazy,67 .sg-heat-shimmer-base {68 fill: var(--sg-color);69 }70 .sg-heat-shimmer-core {71 fill: rgba(255, 255, 255, 0.5);72 }73</style>74