Vanilla Disintegratev1.0.0
RU
На этой странице

Пользовательский эффект — это пара полноценных анимаций. Vanilla Disintegrate предоставляет геометрию, снимок, отмену, cleanup и контракт для подключения аудио; способ рендеринга и звук выбираете вы.

Определить обе фазы

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(). Контроллер также может передать свой визуальный element, duration и layoutDelay.

Этого достаточно для CSS/WAAPI, Canvas-цикла, SVG, WebGL и сторонних движков. dispose() вызывается при любом результате и должен освобождать ресурсы рендерера.

Именованный эффект

const effects = new Disintegrator({
  effects: { pulse },
  effect: 'pulse',
});

effects.remove(element);

Прямые объекты и зарегистрированные имена используют тот же контракт, что и четыре встроенных эффекта.

Свой звук

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-операцию.

Редактировать страницу на GitHub