Swarm Text text
Text dissolves into swarm particles that scatter when your mouse approaches and reassemble when it leaves.
Tech Keywords
| Name | Description |
|---|---|
| Pointer Events | Detects pointer movement, clicks, hovers, and more, providing coordinates and target information |
| Canvas Shader | Written in GLSL and executed directly on the GPU, faster than the Canvas 2D API but harder to master |
| Canvas getImageData | Reads pixel data from a specified canvas region |
| Noise | Produces more natural randomness than Math.random, commonly used for terrain, clouds, and textures |
| Curl Noise | Divergence-free vector field based on noise, producing naturally flowing particle motion |
| Vector Math | Math operations for direction, acceleration, velocity, and more |
| Particle System | Spawns large numbers of small objects, commonly used to simulate smoke, fire, rain, and snow |
| Physics Simulation | Simulates 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;
/** 粒子取樣間距(px),越小粒子越密。@default 0.1 */
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;
}