Skip to content

Every little fish swimming around is a visitor on this page right now, and one of them is you ( ´ ▽ ` )ノ If they get in the way of reading, feel free to turn them off.

Swarm Text text

Text dissolves into swarm particles that scatter when your mouse approaches and reassemble when it leaves.

Tech Keywords

NameDescription
Pointer EventsDetects pointer movement, clicks, hovers, and more, providing coordinates and target information
Canvas ShaderWritten in GLSL and executed directly on the GPU, faster than the Canvas 2D API but harder to master
Canvas getImageDataReads pixel data from a specified canvas region
NoiseProduces more natural randomness than Math.random, commonly used for terrain, clouds, and textures
Curl NoiseDivergence-free vector field based on noise, producing naturally flowing particle motion
Vector MathMath operations for direction, acceleration, velocity, and more
Particle SystemSpawns large numbers of small objects, commonly used to simulate smoke, fire, rain, and snow
Physics SimulationSimulates real-world physics such as gravity, collisions, and velocity

Usage Examples

Basic Usage

Text is rendered as swarm particles. When the mouse approaches, particles scatter. When the mouse leaves, they gradually reassemble.

Check out the source code
vue
<template>
  <div class="w-full example-wrap">
    <text-swarm :text="t('text')" class="h-[50vh]" />
  </div>
</template>

<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import TextSwarm from '../text-swarm.vue'

const { t } = useI18n()
</script>

How it Works

Text is drawn on an offscreen Canvas and pixel data is sampled to generate particle positions.

Physics simulation runs on the GPU via WebGL2 shaders, using ping-pong float textures for particle state and a pre-computed curl noise texture for airflow turbulence.

When the mouse approaches, radial push and wind forces scatter the particles. When it leaves, particles drift back to their origin in a cohesive swarm-like motion.

Source Code

API

Props

interface Props {
  /** 要顯示的文字 */
  text: string;

  /** 文字大小(px)。@default 80 */
  fontSize?: number;

  /** 字型。@default 'sans-serif' */
  fontFamily?: string;

  /** 字重。@default 'normal' */
  fontWeight?: string;

  /** 粒子大小(px)。@default 0.1 */
  particleSize?: number;

  /** 粒子顏色。@default 'currentColor' */
  particleColor?: string;

  /**
   * 粒子取樣間距,單位為裝置像素,越小粒子越密。
   *
   * 以裝置像素計算才能在高解析度螢幕上正確超取樣文字,還原度不隨 DPR 改變。
   *
   * @default 0.5
   */
  particleGap?: number;

  /** 滑鼠散開影響半徑(px)。@default 40 */
  scatterRadius?: number;

  /** 散開力道。@default 40 */
  scatterForce?: number;

  /** 回歸速度,0~1 之間,越大回歸越快。@default 0.1 */
  returnSpeed?: number;

  /** 摩擦力,0~1 之間,越大慣性越強。@default 0.92 */
  friction?: number;
}

v0.89.3