Particle Text <mv-particle-text>
由数千个 canvas 粒子绘制的文本,粒子从元素自身的字体中采样:它们从左到右扫入就位,躲开指针后再弹回,点击时四散炸开,文本变化时流向新的单词,并按它们穿过的渐变着色。
| 分类 | 动画文字 |
|---|---|
| 类型 | Web Component(<mv-particle-text>) |
| 状态 | 稳定版 |
| Keywords | safe-rewrite, particles, canvas, text, morph, interactive, hero, repel |
When to use
- A hero title should be drawn by particles that assemble, flee the cursor and explode on click
- A short word should morph into another with particles flowing into place
Avoid when
- Low-end mobile or several instances per page; thousands of canvas particles are costly
- Long text or paragraphs; the canvas is built for a short word or title and shrinks overflowing text
- A changing number should be drawn in particles → use Particle Counter instead
安装
node scripts/add.mjs particle-text --out ./src/marvelous使用 Marvelous UI MCP 服务器的 AI 智能体:install_components({ slugs: ["particle-text"], target_dir: "<absolute path>/src/marvelous", framework: "react" })。
复制的文件(含依赖):tokens/tokens.css, core/base.css, core/canvas.js, core/dom.js, core/element.js, core/motion.js, core/observe.js, components/particle-text/particle-text.js, components/particle-text/particle-text.css。
用法
标准标记,可在此基础上通过属性、data-* 和 CSS 变量进行定制:
<div style="display:grid;gap:.5rem;width:100%;justify-items:center">
<mv-particle-text id="mv-particle-text-demo" colors="var(--mv-accent), oklch(0.72 0.14 225), oklch(0.75 0.16 345)">Hello</mv-particle-text>
<div style="display:flex;gap:.5rem;flex-wrap:wrap;justify-content:center">
<button class="mv-button" data-size="sm" data-variant="outline" data-word="Hello">Hello</button>
<button class="mv-button" data-size="sm" data-variant="outline" data-word="Marvelous">Marvelous</button>
<button class="mv-button" data-size="sm" data-variant="outline" data-word="Thanks!">Thanks!</button>
<button class="mv-button" data-size="sm" data-variant="ghost" id="mv-particle-text-demo-burst">Burst</button>
</div>
<p style="margin:.25rem 0 0;font-size:.8rem;color:var(--mv-fg-subtle)">Hover the letters to scatter them, click to make them explode.</p>
<mv-particle-text text="2026" style="font-size:3.5rem;max-width:320px;margin-top:.5rem" radius="50"></mv-particle-text>
</div>
<script type="module">
const pt = document.getElementById("mv-particle-text-demo");
for (const b of document.querySelectorAll("[data-word]")) b.addEventListener("click", () => { pt.text = b.dataset.word; });
document.getElementById("mv-particle-text-demo-burst").addEventListener("click", () => pt.burst());
</script>API
Attributes
| Name | 类型 | Default | Description |
|---|---|---|---|
text | string | Text (otherwise the element content). Changing it triggers a morph. | |
colors | list of CSS colors | var(--mv-particle-text-color) | One color, or several for a left-to-right gradient laid over the text; particles take the color of where they are (tokens accepted, they follow the theme). |
trigger | view | hover | load | manual | view | When the particles assemble (manual: call assemble()). |
gap | number | auto (2-8) | Sampling step in px (smaller = more particles, capped at 7,000; auto keeps the count under the cap). |
size | number | gap × 0.86 | Particle side length (px). |
radius | number | 90 | Cursor influence radius (px). |
strength | number | 1 | Repulsion strength. |
Methods
| Name | Description |
|---|---|
assemble() | Assembles the particles into text. |
burst(x?, y?) | Explodes the particles from a point (local coordinates, center by default). |
Events
| Name | Description |
|---|---|
mv-settle | All particles are back in place (the loop stops). |
CSS variables
| Name | Default | Description |
|---|---|---|
--mv-particle-text-color | var(--mv-fg) | Default color. |
Accessibility
The text stays available as visually hidden text for screen readers; the canvas is aria-hidden. Font family, weight and size come from the element's CSS (the text shrinks if it overflows). Reduced motion: text is assembled immediately, with no repulsion or explosion. Forced colors: particles use the system text color. The loop pauses off-screen and stops when idle.