自定义效果由两段完整动画组成。Vanilla Disintegrate 提供几何位置、捕获、取消、清理以及音频接入协议;渲染方式和声音都由你选择。
定义两个阶段
import { defineEffect } from 'vanilla-disintegrate';
function createLayerClone(element: HTMLElement, layer: HTMLElement) {
const visual = element.cloneNode(true) as HTMLElement;
Object.assign(visual.style, {
height: '100%',
inset: '0',
margin: '0',
pointerEvents: 'none',
position: 'absolute',
width: '100%',
});
layer.append(visual);
return visual;
}
const pulse = defineEffect({
remove: {
needsSnapshot: false,
animate({ element, layer }) {
return createLayerClone(element, layer).animate(
[
{ opacity: 1, transform: 'scale(1)' },
{ opacity: 0, transform: 'scale(.6) rotate(8deg)' },
],
{ duration: 420, easing: 'cubic-bezier(.4, 0, 1, 1)' },
);
},
},
restore: {
needsSnapshot: false,
animate({ element, layer }) {
return createLayerClone(element, layer).animate(
[
{ opacity: 0, transform: 'scale(.6) rotate(-8deg)' },
{ opacity: 1, transform: 'scale(1) rotate(0)' },
],
{ duration: 520, easing: 'cubic-bezier(0, 0, .2, 1)' },
);
},
},
});
effects.remove(element, { effect: pulse });
effects.restore(insertedElement, { effect: pulse });
needsSnapshot: false 保证该阶段不会调用 capture 或 SnapDOM。
动画上下文
工厂会收到 operation、真实 element、最终 bounds、隔离 layer、snapshot、惰性 visual、AbortSignal、random()、reducedMotion 和 addCleanup(fn)。
恢复时,bounds 描述的是插入后的新位置,而不是删除前的位置。
返回值
工厂可返回 Web Animation、Promise、null,或带 finished、cancel()、dispose() 的控制器。该协议可用于 CSS/WAAPI、Canvas、SVG、WebGL 与第三方引擎。
const effects = new Disintegrator({
effects: { pulse },
effect: 'pulse',
});
直接传入效果对象与注册名称使用相同协议。
自定义声音
const effect = defineEffect({
remove: {
animate: removeAnimation,
sound: { src: '/sounds/remove.ogg', gain: 0.35 },
},
restore: {
animate: restoreAnimation,
sound: ({ signal }) => startMyAudioEngine(signal),
},
});
声音支持 URL、ArrayBuffer、AudioBuffer、参数对象或播放器工厂。音频错误不会终止视觉或 DOM 操作。