Skip to content

Hi Hue bg

Hi-hue (hî-hue) is a Taiwanese word for the flower-like ripples that bloom on the still water's surface when fish swim below.

Like Jit Hue, it comes from 《日花閃爍:台語的美麗詞彙&一百首詩》 (Shimmering Jit-Hue: Beautiful Taiwanese Words & One Hundred Poems).

Watching fish glide beneath the water while hi-hue blooms above feels like reading a poem that never ends.

Usage Examples

Basic Usage

Click anywhere to bloom a hi-hue; a few small fish surface within the area, swim around briefly, then dive back into the depths.

台語裡獨有的漂亮詞彙 魚花 hî-hue 水裡魚群游動,在靜止的水面上
泛出如花一般的漣漪,
台語將此波紋稱為「魚花」。
《魚花》 午後的池塘睡得很沉
連雲都繞著走
魚兒在水面綻開
一朵朵 看一眼便忘的花
池塘記不住
雲也記不住
只有蹲在岸邊的我
記了一整個下午
The afternoon pond sleeps deep,
even the clouds detour around it.

On the water, fish bloom —
flower after flower, forgotten at a glance.

The pond does not remember,
nor do the clouds.
Only I, crouched on the bank,
remembered the whole afternoon.
View example source code
vue
<template>
  <div class="w-full flex flex-col gap-4">
    <bg-hi-hue class="w-full cursor-pointer border rounded-xl">
      <div class="font-wenkai h-full flex flex-col items-center justify-center gap-12 p-8 md:p-14">
        <!-- 名詞解釋 -->
        <div class="flex flex-col items-center gap-6 text-center">
          <span class="text-xs tracking-[0.5em] opacity-60">
            台語裡獨有的漂亮詞彙
          </span>

          <span class="flex items-baseline gap-4">
            <span class="text-6xl md:text-7xl tracking-[0.15em]">
              魚花
            </span>
            <span class="text-xl md:text-2xl italic tracking-wider text-cyan-700/60 dark:text-cyan-300/70">
              hî-hue
            </span>
          </span>

          <span class="block max-w-md text-base tracking-wider leading-loose">
            水裡魚群游動,在靜止的水面上
            <br>
            泛出如花一般的漣漪,
            <br>
            台語將此波紋稱為「魚花」。
          </span>
        </div>

        <span class="block h-px w-16 bg-gray-300 dark:bg-slate-700" />

        <!-- 新詩 -->
        <div class="flex flex-col items-center gap-7 text-center">
          <span class=" tracking-[0.4em]">
            《魚花》
          </span>

          <span class="block tracking-[0.15em] leading-[2.4]">
            午後的池塘睡得很沉
            <br>
            連雲都繞著走
          </span>

          <span class="block tracking-[0.15em] leading-[2.4]">
            魚兒在水面綻開
            <br>
            一朵朵 看一眼便忘的花
          </span>

          <span class="block tracking-[0.15em] leading-[2.4]">
            池塘記不住
            <br>
            雲也記不住
            <br>
            只有蹲在岸邊的我
            <br>
            記了一整個下午
          </span>

          <!-- 英譯 -->
          <span class="block max-w-md text-sm italic leading-relaxed opacity-60">
            The afternoon pond sleeps deep,
            <br>
            even the clouds detour around it.
            <br><br>
            On the water, fish bloom —
            <br>
            flower after flower, forgotten at a glance.
            <br><br>
            The pond does not remember,
            <br>
            nor do the clouds.
            <br>
            Only I, crouched on the bank,
            <br>
            remembered the whole afternoon.
          </span>
        </div>
      </div>
    </bg-hi-hue>
  </div>
</template>

<script setup lang="ts">
import BgHiHue from '../bg-hi-hue.vue'
</script>

How It Works

Fish Life Cycle

Each click spawns several small fish near the click position. Every fish goes through three phases:

  • Emerging: rises from the depths to the surface. Opacity fades in from 0 to maximum while size scales up in sync.
  • Swimming: drifts along the surface, randomly changing direction to produce a natural exploring trail.
  • Diving: opacity and size shrink together as the fish sinks back into the depths, then leaves the canvas.

The full life cycle lasts about 4 to 7 seconds. A single depth parameter drives both opacity and scale, simulating the visual difference between a fish near the surface and one deep below.

Serpentine Motion

Each fish body is made up of several segments. Every segment follows the one in front and adds a sine-wave offset to mimic real swimming posture. Tail wag amplitude grows with segment index, so the tip oscillates the most. Each segment's position and orientation traces out a spindle-shaped outline, with a swallow-tail fin trailing behind to give the natural fish silhouette.

Ripple Visuals

The ripple from each click uses two techniques in tandem:

  • SVG feDisplacementMap: a dynamic displacement map warps whatever sits behind the ripple, producing a strong refractive feel against textured backgrounds (cards, text, etc.).
  • Canvas light/shadow rings: on a separate overlay, radial gradient rings (inner shadow, outer highlight) are drawn so the ripple stays visible even on a plain solid background.

Together they cover both cases: the ripple holds up whether the backdrop is empty or full of content.

Source Code

API

Props

interface Props {
  /** feDisplacementMap scale。@default 10 */
  displacementIntensity?: number;
  /** 點擊扭曲半徑(px),0 表示自動擴散至最遠角落。@default 0 */
  distortionRadius?: number;
  /** 水波衰減時間(秒)。@default 3 */
  distortionDecay?: number;
  /** 每次點擊生成的魚數量。@default 3 */
  count?: number;
  /** 魚的尺寸倍率。@default 1 */
  sizeScale?: number;
}

Slots

interface Slots {
  default?: () => unknown;
}

v0.65.0