프로바이더의 animation(정렬 중 레이아웃 이동), dropAnimation(오버레이 안착), animateChanges(드래그가
아닌 데이터 변경)는 false, 옵션, 또는 직접 만든 함수를 받습니다. GSAP이나 motion에 쓸 수 있습니다.
리스트와 트리는 animation과 animateChanges를 재정의할 수 있고, draggable, 항목, 리스트는
자기만의 dropAnimation을, 드롭 대상은 overDropAnimation을 가질 수 있습니다. 애니메이션을 참고하세요.
<DnDProvider :animation="{ duration: 180, easing: 'ease-out' }" :drop-animation="false" />
아래의 각 레인은 독립된 프로바이더이며, animation, dropAnimation, animateChanges에 같은 종류의
값을 줍니다(animateChanges는 move에서 함수를 받습니다).
데모 불러오는 중…
<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><DnDProvider :animation="shape" :drop-animation="shape" :animate-changes="shape"></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>옵션
애니메이션의 타이밍. 생략한 부분은 그 애니메이션의 기본값을 유지합니다.
정렬
항목이 새 자리로 움직이는 방식: true(기본 타이밍), 옵션, false(즉시 이동), 또는 항목 하나를 from에서 to로 애니메이션하고 그 Animation, 끝날 때 처리되는 Promise, 또는 아무것도 반환하지 않는 함수.
type LayoutAnimation = | boolean | AnimationOptions | ((context: LayoutAnimationContext) => Animation | Promise<unknown> | void)레이아웃 애니메이션 함수가 받는 것. 새 자리로 이동하는 항목 하나에 대한 정보입니다.
Key항목의 key.
HTMLElement항목의 요소. 이미 새 자리에 있습니다.
Rect변경 전의 시각적 사각형(진행 중인 애니메이션이 항목을 보여 주던 위치).
Rect변경 후의 레이아웃 사각형.
Required<AnimationOptions>옵션이 정한 타이밍. 기본값이 채워져 있습니다.
'drag' | 'change'항목을 움직인 원인: 드래그('drag': 정렬, 드롭, 취소), 또는 드래그가 아닌 데이터 변경('change', 리스트의 animateChanges가 켜진 경우).
AbortSignal라이브러리가 애니메이션을 중단할 때 abort됩니다. 애니메이션이 끝나기 전에 항목이 다시 움직이거나(다음 애니메이션은 현재 보이는 위치에서 시작합니다), 애니메이션이 꺼진 경우입니다. 반환한 Animation은 자동으로 취소됩니다. 그 밖의 것은 여기서 즉시 멈추고 설정한 스타일을 되돌리세요. 바로 다음에 레이아웃을 측정합니다.
booleanprefers-reduced-motion: reduce가 설정되어 있습니다. 이때 라이브러리 자체 애니메이션은 실행되지 않지만, 직접 만든 함수는 항상 실행되며 이 값으로 결정합니다(건너뛰거나, 페이드만 남기거나).
드롭
드롭할 때 오버레이가 안착하고 취소할 때 원래 자리로 돌아가는 방식: true(기본 타이밍), 옵션, false(날아가지 않음: 놓은 곳에서 끝납니다), 또는 overlay를 from에서 to로 애니메이션하고 그 Animation이나 끝날 때 처리되는 promise를 반환하거나 아무것도 반환하지 않는 함수.
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>옵션이 정한 타이밍. 기본값이 채워져 있습니다.
booleanprefers-reduced-motion: reduce가 설정되어 있습니다. 이때 라이브러리 자체 애니메이션은 실행되지 않지만, 직접 만든 함수는 항상 실행되며 이 값으로 결정합니다(건너뛰거나, 페이드만 남기거나).
데이터 변경
드래그가 아닌, 리스트(또는 트리) 항목의 변경을 애니메이션합니다: 추가, 제거, 이동(정렬, 섞기, 한 그룹의 리스트 사이 이동), 필터링된 항목. 기본으로 꺼져 있습니다(false). true는 이동, 나타나는 항목, 사라지는 항목을 기본 타이밍으로 애니메이션합니다. 드래그는 자체 애니메이션(animation, dropAnimation)을 유지합니다. prefers-reduced-motion: reduce이면 기본 애니메이션은 실행되지 않지만, 직접 만든 함수는 여전히 실행됩니다(reducedMotion: true와 함께). 보이는 영역 근처의 항목만 애니메이션됩니다(가상 리스트의 마운트되지 않은 행은 건너뜁니다).
type AutoAnimation = boolean | AutoAnimationOptions부분별로 나눈 animateChanges: 모든 부분에 적용할 duration과 easing, 그리고 변경 종류별로 true, 옵션(공통 옵션 위에 덮어씀), false, 또는 직접 만든 함수.
true, 옵션, false(항목이 그냥 나타납니다), 또는 항목이 나타나는 애니메이션을 하는 함수.
type EnterAnimation = | boolean | AnimationOptions | ((context: EnterAnimationContext) => Animation | Promise<unknown> | void)animateChanges가 켜진 리스트에 나타난 항목: 추가되었거나 다시 표시된 항목(필터, 펼친 트리 노드).
Key항목의 key.
HTMLElement이미 제자리에 있는 항목의 요소.
Rect항목이 나타난 위치(레이아웃 사각형).
Required<AnimationOptions>옵션이 정한 타이밍. 기본값이 채워져 있습니다.
booleanprefers-reduced-motion: reduce가 설정되어 있습니다. 이때 라이브러리 자체 애니메이션은 실행되지 않지만, 직접 만든 함수는 항상 실행되며 이 값으로 결정합니다(건너뛰거나, 페이드만 남기거나).
true, 옵션, false(항목이 그냥 사라집니다), 또는 항목 자리에 남은 복사본이 사라지는 애니메이션을 하는 함수. 그 Animation이나 Promise를 반환하면 끝날 때 복사본이 제거됩니다(함수가 아무것도 반환하지 않으면 즉시 제거됩니다).
type LeaveAnimation = | boolean | AnimationOptions | ((context: LeaveAnimationContext) => Animation | Promise<unknown> | void)animateChanges가 켜진 리스트에서 사라진 항목: 제거되었거나 숨겨진 항목(필터, 접은 트리 노드).
Key항목의 key.
HTMLElement항목이 있던 자리에 표시되는 항목 요소의 복사본(항목 자체는 이미 없습니다). 이전 부모 안에 절대 위치로 배치되고, 포인터를 무시하며, data-dnd-leaving이 표시됩니다. 애니메이션이 끝나면 라이브러리가 제거합니다.
Rect항목이 있던 위치.
Required<AnimationOptions>옵션이 정한 타이밍. 기본값이 채워져 있습니다.
booleanprefers-reduced-motion: reduce가 설정되어 있습니다. 이때 라이브러리 자체 애니메이션은 실행되지 않지만, 직접 만든 함수는 항상 실행되며 이 값으로 결정합니다(건너뛰거나, 페이드만 남기거나).