Shatter (碎裂)

把任意内容像玻璃一样打碎成碎片飞散消失:零运行时依赖,Voronoi 碎片几何 + 仅合成器线程(transform/opacity)的动画,稳定 60fps;支持点击/指令/v-model 触发,尊重 reduced-motion。

为什么它能稳定 60fps

碎片几何由内置的 Voronoi 剖分生成(零运行时依赖)。每个碎片只被裁剪到自身包围盒大小并隔离绘制,所以一次性构建成本 ≈ 元素自身面积,而非 N 倍全尺寸图层;飞散阶段只动 transform 与 opacity——这两个属性在合成器线程上运行,不触发布局与重绘。运动是把真实的弹道轨迹(向外冲量 + 空气阻力 + 重力 t² 加速)采样进多段线性关键帧,因此自然连贯;clip-path 仅用于刻画玻璃边、保持静止。

打碎一个真实组件

它能包裹任意内容——这里是一张完整的卡片(封面图、评分、标签、简介、按钮)。点 打碎这张卡片,整张卡连同里面的图文一起碎成玻璃片飞散坠落;点「重新组合」, 同样的碎片会沿原路飞回、归位重新拼成卡片。触发用的是组件 ref 暴露的 shatter() / restore()

cover Galgame NEW

星空下的约定

Studio Moonlit · 2026

恋爱治愈校园

转学生在天文社遇见了她——一段关于星空、约定与离别的夏日物语,在蝉鸣声中悄然展开。

ComplexCard.vue

基础用法

trigger="click" 即可点击打碎;碎裂从点击点向外炸开, :auto-restore 让它在若干毫秒后自动复原。

🌸

点击打碎我

从点击点炸开 · 自动复原

Basic.vue

打碎图片

最常见的 ACGN 场景:点击打碎一张图片。每个碎片携带它对应的那一块图像切片飞散—— 直接克隆真实 DOM,无需 canvas 截图,也没有跨域 taint 问题。

kungalgame
ImageShatter.vue

v-model 触发

默认 trigger="manual"——用 v-model:shattered 声明式控制 (像「带玻璃碎裂的 v-if」)。复原时默认带「重新拼合」动画(reassemble), 设 :reassemble="false" 则瞬时复原。keep-space 在碎裂后保留原位占位,避免布局跳动。

v-model 控制

设 shattered = true 即碎裂,false 复原。

Model.vue

碎裂原点

origin 决定碎片向外飞散的中心:center(默认)、 toppointer(上次指针位置),或显式 { x, y } 像素坐标。

origincenter
origintop
originpointer
Origin.vue

碎片数量

pieces 控制碎片数(2–160)。数量越多构建越重,但飞散动画始终只在 合成器线程,帧率不受影响。

点击打碎 · 28 片
Pieces.vue

物理手感

gravity(重力,t² 加速下坠)、spread(飞散距离)、 rotation(最大自旋)组合出不同效果——轻盈飘散、加速坠落、猛烈炸裂。

轻盈飘散
重力坠落
猛烈炸裂
Physics.vue

属性

属性类型默认值说明
autoRestorenumber0Auto re-form this many ms after the break completes (0 = stay shattered). Default 0.
classNamestring""Extra classes for the wrapper.
disableAnimationbooleanfalseSkip the shard animation and hide instantly. Also forced under `prefers-reduced-motion`. Default false.
disabledbooleanfalseDisable shattering entirely — the content stays put. Default false.
durationnumber1100Fly-apart duration in ms. Default 1100.
easingstring"linear"Animation-level CSS easing. Default `linear` — the natural ballistic motion is baked into each shard's sampled keyframes, so override this only to time-warp the whole flight.
fadebooleantrueFade shards out as they fly (false = keep full opacity, e.g. flying off-screen). Default true.
gravitynumber1Downward gravity pull on the shards (0 = a pure radial burst). Default 1.
keepSpacebooleanfalseKeep the original's layout space after it shatters (`visibility:hidden`) instead of collapsing it (`display:none`). Default false.
originKunShatterOrigin"center"Where the break originates — shards fly outward from here. `center` (default), `top`, `pointer` (last pointer position over the content), or `{ x, y }` px.
piecesnumber24Target number of glass shards (Voronoi cells); clamped to 2–160. Default 24. Fewer is cheaper to build, but the fly-apart stays compositor-only regardless.
reassemblebooleantrueAnimate the re-form when restoring — a reverse "reassemble" where the same shards fly back in from where they scattered and settle into place. `false` snaps the content back instantly. Default true.
rotationnumber140Maximum random spin per shard, in degrees. Default 140.
seednumberDeterministic shard pattern: the same seed reproduces the same break (handy for visual tests). Omit for a fresh random shatter each time.
shatteredbooleanfalse
spreadnumber1How far the shards travel, as a multiplier. Default 1.
trigger"click" | "manual""manual"How the break is triggered. `manual` (default) = drive it via `v-model:shattered` or the exposed `shatter()` method; `click` = clicking the content shatters it, and the click point becomes the impact origin.
zIndexnumber9999z-index of the body-level shard overlay. Default 9999.