remove() и restore() — две отдельные операции. Библиотека проигрывает анимацию. Куда девается элемент и что это значит для приложения — решаете вы.
Удаление элемента
Перед отсоединением библиотека измеряет живой элемент. Визуальный эффект работает в изолированном слое, когда реального узла уже нет в layout.
const operation = effects.remove(element, {
retain: false,
layout: true,
});
const result = await operation.finished;
retain по умолчанию равен false: ссылка на DOM не сохраняется. Опция layout анимирует соседей в новые позиции.
Восстановление вставленного элемента
Сначала вставьте узел туда, где он должен оказаться, и только затем вызывайте restore().
container.append(element);
const operation = effects.restore(element);
await operation.finished;
Элемент должен быть подключён к документу и иметь ненулевой размер. Библиотека синхронно скрывает его, измеряет новую конечную позицию, делает снимок, проигрывает восстановление и показывает оригинал.
Скрытие сделано приостановленной Web Animation, а не инлайновым стилем, поэтому переживает смену классов и стилей во время эффекта. Из каскада CSS следует одно ограничение: авторское объявление с !important приоритетнее анимаций, поэтому правило вида .card { opacity: 1 !important } на цели восстановления оставит живой элемент видимым под слоем частиц. Помогает убрать !important с цели либо восстанавливать обёртку без этого объявления.
Анимация появления нового элемента
restore() можно использовать для анимации появления нового элемента. Сначала добавьте его в DOM, затем вызовите restore() — предварительно вызывать remove() не нужно.
const message = document.createElement('aside');
message.textContent = 'Создан только что';
notifications.append(message);
effects.restore(message, { preset: 'vapor' });
Объект операции
Оба метода синхронно возвращают объект операции:
const operation = effects.remove(element);
operation.operation; // 'remove'
operation.removalId; // RemovalId | null
operation.cancel();
const result = await operation.finished;
result.status; // 'completed' | 'cancelled' | 'skipped' | 'rejected'
После завершения объект операции не удерживает DOM-элемент.
Отмена останавливает только визуал
cancel() останавливает анимацию и звук, но не отменяет выбранное действие с контентом: удалённый элемент остаётся удалённым, а восстанавливаемый становится видимым.
Поэтому кнопка отмены или размонтирование представления посреди анимации не могут незаметно откатить уже принятое приложением решение.
Если элемент уже занят первой операцией, второй вызов не изменяет DOM и не создаёт идентификатор сохранения. Его промис finished ждёт завершения текущего владельца и только затем возвращает статус rejected, поэтому ожидание handle не обрывает активный жизненный цикл элемента.
Ошибка не блокирует контент
Если захват, аудио или пользовательский эффект завершились ошибкой, удаление всё равно отсоединит узел, а восстановление покажет его. Ошибка передаётся в onError, а при отсутствии доступного визуала результат получает статус skipped.
const effects = new Disintegrator({
preset: 'dust',
onError(error, context) {
console.error(context.operation, error);
},
});