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.4 KB · 89 lines html
Raw Blame History
1<!--2  ============================================================3  SVGarden — https://www.svgarden.dev4  Author : Simon-Pierre Boucher5  Contact: contact@spboucher.ai6  File   : snippets/text-fx/text-liquid-fill.html7  Desc   : Letterforms fill with rising liquid topped by a moving wave8  ============================================================9-->10<!--svgarden11title: Liquid-fill text12slug: text-liquid-fill13category: text-fx14tags: [text, clip-path, liquid, wave]15difficulty: advanced16techniques: [clipPath-from-text, periodic-wave-path, nested-transform-layers, translate-property]17how_it_works: >18  A <clipPath> built from bold <text> confines everything drawn inside it to the19  letterforms, so the "liquid" only exists where the glyphs are. The liquid is a20  single path whose top edge is a periodic quadratic wave (q + t commands repeat21  every 130 units) extending far past the visible area and closing into a deep22  solid below. Two animations are deliberately split across nested groups so23  their transforms don't fight: the outer group rises with translateY to raise24  the water level, while the inner path slides horizontally by exactly one wave25  period, which makes the surface roll seamlessly. A faint stroked copy of the26  text on top shows the unfilled portion on any background.27customizable:28  - { var: "--sg-color",    label: "Liquid color", type: color, default: "#3F8FDF" }29  - { var: "--sg-size",     label: "Width",        type: range, min: 140, max: 420, default: 260, unit: px }30  - { var: "--sg-duration", label: "Fill time",    type: range, min: 2, max: 10, step: 0.5, default: 5, unit: s }31created: 2026-08-1032-->33<div class="sg-text-liquid-fill" style="--sg-color:#3F8FDF; --sg-size:260px; --sg-duration:5s;">34  <svg viewBox="0 0 260 90" role="img" aria-label="FLOW">35    <title>FLOW</title>36    <defs>37      <clipPath id="sg-text-liquid-fill-clip">38        <text class="sg-text-liquid-fill-txt" x="130" y="72">FLOW</text>39      </clipPath>40    </defs>41    <text class="sg-text-liquid-fill-txt sg-text-liquid-fill-ghost" x="130" y="72">FLOW</text>42    <g clip-path="url(#sg-text-liquid-fill-clip)">43      <g class="sg-text-liquid-fill-rise">44        <path class="sg-text-liquid-fill-wave"45          d="M-260 8 q32 -14 65 0 t65 0 t65 0 t65 0 t65 0 t65 0 t65 0 t65 0 V120 H-260 Z" />46      </g>47    </g>48  </svg>49</div>50<style>51  .sg-text-liquid-fill {52    width: var(--sg-size);53  }54  .sg-text-liquid-fill svg {55    display: block;56    width: 100%;57  }58  .sg-text-liquid-fill-txt {59    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;60    font-size: 64px;61    font-weight: 800;62    letter-spacing: 2px;63    text-anchor: middle;64  }65  .sg-text-liquid-fill-ghost {66    fill: none;67    stroke: var(--sg-color);68    stroke-width: 1.5;69    opacity: 0.35;70  }71  .sg-text-liquid-fill-rise {72    animation: sg-text-liquid-fill-up var(--sg-duration) ease-in-out infinite;73  }74  .sg-text-liquid-fill-wave {75    fill: var(--sg-color);76    animation: sg-text-liquid-fill-roll calc(var(--sg-duration) / 3) linear infinite;77  }78  @keyframes sg-text-liquid-fill-up {79    0%        { transform: translateY(62px); opacity: 1; }80    60%       { transform: translateY(6px); }81    82%       { transform: translateY(6px); opacity: 1; }82    94%       { transform: translateY(6px); opacity: 0; }83    100%      { transform: translateY(62px); opacity: 0; }84  }85  @keyframes sg-text-liquid-fill-roll {86    to { translate: 130px 0; }87  }88</style>89