문서/API

애니메이션

애니메이션의 옵션과 훅. 정렬, 드롭, 그리고 드래그가 아닌 변경.

이 페이지 편집

이 페이지는 AI가 번역했으며 부정확한 내용이 있을 수 있습니다. 영어 원문 읽기

프로바이더의 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에서 함수를 받습니다).

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

ms 단위. 기본값은 레이아웃 이동 200, 드롭 250입니다. 0이면 애니메이션이 꺼집니다.

string

CSS 이징('ease-out', cubic-bezier(…)).

정렬

항목이 새 자리로 움직이는 방식: 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은 자동으로 취소됩니다. 그 밖의 것은 여기서 즉시 멈추고 설정한 스타일을 되돌리세요. 바로 다음에 레이아웃을 측정합니다.

boolean

prefers-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>

옵션이 정한 타이밍. 기본값이 채워져 있습니다.

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

자리가 바뀐 항목(animation과 같은 기본 FLIP. 함수를 넘기면 대체됩니다).

EnterAnimation

나타난 항목. 기본값: 제자리에서 서서히 나타납니다.

LeaveAnimation

사라진 항목. 기본값: 항목의 복사본이 원래 자리에서 조금 줄어들며 서서히 사라집니다.

true, 옵션, false(항목이 그냥 나타납니다), 또는 항목이 나타나는 애니메이션을 하는 함수.

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

animateChanges가 켜진 리스트에 나타난 항목: 추가되었거나 다시 표시된 항목(필터, 펼친 트리 노드).

Key

항목의 key.

HTMLElement

이미 제자리에 있는 항목의 요소.

Rect

항목이 나타난 위치(레이아웃 사각형).

Required<AnimationOptions>

옵션이 정한 타이밍. 기본값이 채워져 있습니다.

boolean

prefers-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>

옵션이 정한 타이밍. 기본값이 채워져 있습니다.

boolean

prefers-reduced-motion: reduce가 설정되어 있습니다. 이때 라이브러리 자체 애니메이션은 실행되지 않지만, 직접 만든 함수는 항상 실행되며 이 값으로 결정합니다(건너뛰거나, 페이드만 남기거나).