Документация/API

Анимации

Опции и хуки анимаций — сортировка, бросок и изменения, сделанные не драгом.

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

Страница переведена ИИ и может содержать неточности. Читать английский оригинал

animation провайдера (перемещения раскладки при сортировке), dropAnimation (приземление оверлея) и animateChanges (изменения данных, сделанные не драгом) принимают false, опции или вашу собственную функцию — для GSAP или motion. Списки и деревья могут переопределять animation и animateChanges; перетаскиваемые элементы, сортируемые элементы и списки могут задавать собственную dropAnimation, а цели — overDropAnimation. См. анимации.

<DnDProvider :animation="{ duration: 180, easing: 'ease-out' }" :drop-animation="false" />

Каждая дорожка ниже — отдельный провайдер, который задаёт animation, dropAnimation и animateChanges значения одного вида (animateChanges в move принимает функцию).

Live

Загружаем демо…

<script setup lang="ts">
import { ref } from 'vue';
import { DnDProvider, type AutoAnimation, type DropAnimation, type LayoutAnimation } from '@vue-dnd-kit/core';
import AnimLane from './AnimLane.vue';
import { tiltDrop, tiltMove } from './tilt';

const SLOW = { duration: 700, easing: 'ease-in-out' };

// One shape per lane, for all three options: sorting, the drop, and changes no drag made.
const lanes: { label: string; animation: LayoutAnimation; dropAnimation: DropAnimation; animateChanges: AutoAnimation }[] = [
  { label: 'true', animation: true, dropAnimation: true, animateChanges: true },
  { label: 'false', animation: false, dropAnimation: false, animateChanges: false },
  { label: '{ duration: 700 }', animation: SLOW, dropAnimation: SLOW, animateChanges: SLOW },
  // `animateChanges` takes no function itself: its parts (`move`, `enter`, `leave`) do.
  { label: 'ƒ tilt', animation: tiltMove, dropAnimation: tiltDrop, animateChanges: { move: tiltMove } },
];

const letters = ['A', 'B', 'C', 'D'];
const rows = ref(lanes.map(() => letters.map((id, i) => ({ id, hue: 150 + i * 40 }))));

/** The same new order in every lane (Fisher–Yates: every order as likely): `animateChanges` plays it four ways. */
const shuffle = () => {
  const order = [...letters];
  for (let i = order.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [order[i], order[j]] = [order[j]!, order[i]!];
  }
  rows.value = rows.value.map((lane) => order.map((id) => lane.find((row) => row.id === id)!));
};
</script>

<template>
  <div class="demo">
    <code>&lt;DnDProvider :animation="shape" :drop-animation="shape" :animate-changes="shape"&gt;</code>
    <div class="lanes">
      <!-- A provider per lane: each one has its own animations. -->
      <DnDProvider
        v-for="(lane, index) in lanes"
        :key="lane.label"
        :animation="lane.animation"
        :drop-animation="lane.dropAnimation"
        :animate-changes="lane.animateChanges"
      >
        <AnimLane v-model="rows[index]!" :label="lane.label" />
      </DnDProvider>
    </div>
    <button type="button" @click="shuffle">Shuffle all</button>
  </div>
</template>

<style scoped>
.demo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

code {
  max-width: 100%;
  font: 11px/1.4 ui-monospace, Menlo, Consolas, monospace;
  text-align: center;
  opacity: 0.7;
}

button {
  padding: 6px 12px;
  border: 0;
  border-radius: 8px;
  background: #42b883;
  color: #fff;
  font: 600 12px/1 system-ui, sans-serif;
  cursor: pointer;
}

button:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

.lanes {
  display: grid;
  grid-template-columns: repeat(4, 128px);
  gap: 8px;
}

@media (max-width: 560px) {
  .lanes {
    grid-template-columns: repeat(2, 128px);
  }
}
</style>

Опции

Тайминг анимации. То, что не указано, остаётся по умолчанию для этой анимации.

number

В мс. По умолчанию 200 для перемещений в раскладке, 250 для броска; 0 выключает анимацию.

string

CSS-функция плавности ('ease-out', cubic-bezier(…)).

Сортировка

Как элементы переезжают на новые места: true (тайминг по умолчанию), опции, false (перескакивают) или функция, которая анимирует один элемент из from в to и возвращает его Animation, промис, который завершается вместе с анимацией, или ничего.

type LayoutAnimation = | boolean | AnimationOptions | ((context: LayoutAnimationContext) => Animation | Promise<unknown> | void)

Что получает функция анимации раскладки — для одного элемента, который переезжает на новое место.

Key

Ключ элемента.

HTMLElement

DOM-элемент элемента, уже на новом месте.

Rect

Видимый прямоугольник до изменения (там, где элемент показывала текущая анимация).

Rect

Прямоугольник в раскладке после изменения.

Required<AnimationOptions>

Тайминг из опций, с подставленными значениями по умолчанию.

'drag' | 'change'

Что сдвинуло элемент: драг ('drag': сортировка, бросок, отмена) или изменение ваших данных, сделанное не драгом ('change', при включённом animateChanges у списка).

AbortSignal

Срабатывает, когда библиотека прерывает анимацию: элемент снова сдвинулся до её окончания (следующая анимация начинается там, где он показан) или анимации выключены. Возвращённую Animation библиотека отменит сама. Всё остальное остановите здесь и сразу уберите выставленные им стили: раскладка измеряется сразу после этого.

boolean

Включён prefers-reduced-motion: reduce. Собственные анимации библиотеки тогда не запускаются; ваши функции запускаются всегда и решают по этому флагу (пропустить анимацию или оставить затухание).

Бросок

Как оверлей приземляется при броске и летит обратно при отмене: true (тайминг по умолчанию), опции, false (без полёта: он остаётся там, где его отпустили) или функция, которая анимирует overlay из from в to и возвращает его Animation, промис, который завершается вместе с анимацией, или ничего.

type DropAnimation = | boolean | AnimationOptions | ((context: DropAnimationContext) => Animation | Promise<unknown> | void)

Что получает функция анимации броска: оверлей, где он находится и куда приземляется.

HTMLElement

Блок оверлея; он приземляется на слот активного элемента. При мульти-драге клоны остальных элементов внутри него (в стандартном оверлее — его клоны, в своём — DragPreview) сами приземляются на свои слоты (с таймингом по умолчанию, если здесь своя функция).

Rect

Где находится оверлей, когда драг заканчивается.

Rect | null

Итоговый прямоугольник брошенного элемента; null, если он не отрендерен или не виден (оверлей растворяется).

Rect | null

Элемент не виден после броска на зону (не на сортируемый список), например его бросили в другой элемент (папку) или в корзину: видимый прямоугольник зоны. Стандартная анимация сжимает оверлей в него, пока тот растворяется, вместо растворения на месте.

'drop' | 'cancel'

'drop': оверлей приземляется туда, куда бросок поместил элемент. 'cancel': он летит обратно туда, где был элемент.

Active

Закончившийся драг.

Over | null

Цель, на которую приземляется бросок (список, зона); null при отмене.

Required<AnimationOptions>

Тайминг из опций, с подставленными значениями по умолчанию.

boolean

Включён prefers-reduced-motion: reduce. Собственные анимации библиотеки тогда не запускаются; ваши функции запускаются всегда и решают по этому флагу (пропустить анимацию или оставить затухание).

Изменения данных

Анимирует изменения элементов списка (или дерева), сделанные не драгом: элементы добавлены, удалены, перемещены (сортировка, перемешивание, перенос между списками одной группы) или отфильтрованы. По умолчанию выключено (false); true анимирует перемещения, появление и исчезновение элементов с таймингом по умолчанию. У драгов остаются свои анимации (animation, dropAnimation). При prefers-reduced-motion: reduce стандартные анимации не запускаются; ваши функции запускаются (с reducedMotion: true). Анимируются только элементы рядом с видимой областью (несмонтированные строки виртуального списка пропускаются).

type AutoAnimation = boolean | AutoAnimationOptions

animateChanges по частям:duration и easing для всех, а для каждого вида изменений — true, опции (поверх общих), false или ваша собственная функция.

LayoutAnimation

Элементы, которые поменялись местами (стандартный FLIP, как у animation; функция его заменяет).

EnterAnimation

Появившиеся элементы. По умолчанию они проявляются на своём месте.

LeaveAnimation

Ушедшие элементы. По умолчанию копия элемента растворяется там, где он был, немного уменьшаясь.

true, опции, false (элемент просто появляется) или функция, которая анимирует его появление.

type EnterAnimation = | boolean | AnimationOptions | ((context: EnterAnimationContext) => Animation | Promise<unknown> | void)

Элемент, который появился в списке с включённым animateChanges: добавлен или снова показан (фильтр, раскрытый узел дерева).

Key

Ключ элемента.

HTMLElement

DOM-элемент элемента списка, уже на своём месте.

Rect

Где он появился (прямоугольник в раскладке).

Required<AnimationOptions>

Тайминг из опций, с подставленными значениями по умолчанию.

boolean

Включён prefers-reduced-motion: reduce. Собственные анимации библиотеки тогда не запускаются; ваши функции запускаются всегда и решают по этому флагу (пропустить анимацию или оставить затухание).

true, опции, false (элемент просто исчезает) или функция, которая анимирует исчезновение копии, оставленной на его месте: верните её Animation или промис, и копия будет удалена, когда анимация закончится (сразу, если функция ничего не возвращает).

type LeaveAnimation = | boolean | AnimationOptions | ((context: LeaveAnimationContext) => Animation | Promise<unknown> | void)

Элемент, который ушёл из списка с включённым animateChanges:удалён или скрыт (фильтр, свёрнутый узел дерева).

Key

Ключ элемента.

HTMLElement

Копия DOM-элемента, показанная там, где был элемент (самого элемента уже нет): спозиционирована абсолютно в прежнем родителе, не реагирует на указатель, помечена data-dnd-leaving. Библиотека удаляет её, когда ваша анимация заканчивается.

Rect

Где был элемент.

Required<AnimationOptions>

Тайминг из опций, с подставленными значениями по умолчанию.

boolean

Включён prefers-reduced-motion: reduce. Собственные анимации библиотеки тогда не запускаются; ваши функции запускаются всегда и решают по этому флагу (пропустить анимацию или оставить затухание).