Svelte의 전환 및 애니메이션 이해

애니메이션은 적절하게 사용될 때 사용자 경험을 크게 향상시키고 사용자에게 즉각적인 피드백을 제공하는 훌륭한 도구가 됩니다. Svelte를 활용하면 별도의 JavaScript 라이브러리 없이도 애플리케이션에 애니메이션과 전환 효과를 손쉽게 통합할 수 있습니다.

Svelte 프로젝트 환경 설정

Svelte를 시작하려면 먼저 컴퓨터에 Node.js 런타임과 NPM(Node Package Manager)이 정상적으로 설치되어 있어야 합니다. 터미널을 열고 다음 명령어를 입력하십시오.

npm create vite

이 명령어는 새로운 Vite.js 프로젝트를 생성합니다. 프로젝트 이름을 지정하고 프레임워크로 Svelte를 선택한 다음, 변형을 JavaScript로 설정합니다. 그 후, 프로젝트 디렉토리로 이동하여 다음 명령어를 실행하여 필요한 종속성을 설치합니다.

npm install

불필요한 기본 코드를 제거하기 위해 assets 및 lib 폴더를 삭제하고, App.svelte 및 App.css 파일의 내용을 비워줍니다.

Svelte에서 트위닝 활용법

트위닝은 애니메이션 및 컴퓨터 그래픽 분야에서 사용되는 기술로, 부드럽고 자연스러운 움직임이나 전환 효과를 만들기 위해 키프레임 사이의 중간 프레임을 생성합니다. Svelte는 숫자 값을 사용하여 요소에 애니메이션을 적용할 수 있는 트위닝 유틸리티를 제공하므로 웹 애플리케이션에서 유연한 전환 및 애니메이션을 손쉽게 구현할 수 있습니다.

트위닝 유틸리티는 `svelte/motion` 모듈에 포함되어 있습니다. 컴포넌트에서 트위닝을 사용하려면 다음과 같이 가져와야 합니다.

import { tweened } from 'svelte/motion'

내부적으로 트위닝 유틸리티는 쓰기 가능한 Svelte 스토어입니다. Svelte 스토어는 기본적으로 상태 관리를 처리하는 데 사용할 수 있는 JavaScript 객체입니다. 트위닝된 스토어에는 `set`과 `update`라는 두 가지 메서드가 있습니다. 기본적인 수준에서 트위닝된 스토어의 구문은 다음과 같습니다.

const y = tweened(defaultValue, {
    duration: [시간(밀리초)],
    easing: [이징 함수],
})

위 코드 블록은 변수 `y`를 정의하고 이를 트위닝된 스토어에 바인딩합니다. 스토어는 두 가지 매개변수를 가집니다. 첫 번째 매개변수는 `y` 바인딩이 가져야 할 기본값을 나타내고, 다음 매개변수는 `duration`(지속 시간)과 `easing`(이징 함수)의 두 키를 가진 객체입니다. `duration`은 트윈 효과가 지속되어야 하는 시간(밀리초)을 정의하며, `easing` 함수는 트윈의 움직임 패턴을 결정합니다.

Svelte의 이징 함수는 트윈 효과의 동작 방식을 제어합니다. 이러한 함수는 `svelte/easing` 모듈에 포함되어 있으며, 트위닝된 스토어에 전달하기 전에 모듈에서 특정 함수를 가져와야 합니다. Svelte는 다양한 이징 함수의 동작을 시각적으로 확인할 수 있는 이징 시각화 도구도 제공합니다.

트위닝 유틸리티 사용법을 자세히 설명하기 위해 트위닝 스토어를 사용하여 Svelte에서 요소의 크기를 증가시키는 예제를 살펴보겠습니다.

<script>
  import { tweened } from "svelte/motion";
  import { bounceOut } from "svelte/easing";

  const size = tweened(0, {
    easing:bounceOut
  })
</script>
<div class="container">
  <div style={`height: ${$size * 30}px;`}>
  </div>
</div>
<button on:click={()=>(size.update(()=>$size+3))}>크기 증가</button>

<style>
  .container{
    display: flex;
    align-items: flex-end;
    margin-top: 400px;
  }
  div{
    height:0;
    width:100px;
    background-color: red;
  }
</style>

위 코드 블록은 `svelte/motion` 및 `svelte/easing` 모듈에서 각각 `tweened` 및 `bounceOut` 함수를 가져옵니다. 다음으로, 트위닝된 스토어에 바인딩된 상수 변수가 있습니다. 이 스토어의 기본값은 0입니다. 이 기본값(스토어의 값)은 `$` 기호를 사용하여 접근할 수 있습니다. 트위닝 함수의 다음 매개변수는 `bounceOut` 이징 함수를 가리키는 `easing` 키가 있는 객체입니다.

마크업 섹션에서 버튼 요소에는 `size` 바인딩에 대한 `update` 메서드를 호출하는 `on:click` 지시어가 있습니다. 이 메서드는 버튼을 클릭할 때마다 `$size` 스토어 값을 3씩 증가시킵니다. `div` 요소에는 `$size` 스토어 값에 따라 달라지는 인라인 스타일이 적용되어 있습니다. 브라우저에서 이 코드를 실행하면 다음과 같은 결과가 표시됩니다.

Svelte의 전환 효과

DOM(Document Object Model) 안팎으로 요소가 전환될 때 Svelte는 전환 지시어와 함께 사용할 수 있는 다양한 유틸리티 함수를 내보내는 `svelte/transition` 모듈을 제공합니다. 예를 들어, DOM 내부와 외부에서 요소를 흐리게 만드는 효과를 주려면 먼저 `svelte/transition`에서 `blur` 함수를 가져와야 합니다.

<script>
import { blur } from 'svelte/transition';
</script>

그런 다음 DOM에서 요소를 마운트 및 마운트 해제하는 기능을 추가합니다. 스크립트 태그에서 `visible` 변수를 생성하고 초기값을 `false`로 설정합니다.

<script>
import { blur } from 'svelte/transition';
let visible = false;
</script>

다음으로, `if` 블록을 사용하여 `div` 요소를 조건부로 렌더링합니다. `div`에 전환 지시어를 추가하고 `blur` 효과를 적용하도록 설정합니다.

{#if visible}
<div transition:blur>여기 있어요...</div>
{/if}

마지막으로 `div`를 표시하거나 숨기는 버튼을 추가합니다.

<button on:click={()=>visible=!visible}>
{visible ? "숨기기" : "보이기"}
</button>

브라우저에서 코드를 실행하면 다음과 같이 표시됩니다.

`svelte/transition` 모듈은 `fade`, `blur`, `fly`, `slide`, `scale`, `draw`, `crossfade`의 7가지 기능을 제공합니다. Svelte의 전환 효과는 매개변수를 가질 수 있습니다. 예를 들어, 앞서 사용한 `blur` 함수는 `delay`, `duration`, `easing` (이징 함수), `opacity`, `amount` (흐림 효과의 정도) 등의 매개변수를 허용합니다.

전환 효과에 대한 매개변수 외에도 Svelte는 요소 전환을 더욱 세밀하게 제어할 수 있는 `in` 및 `out` 전환 효과도 제공합니다. 앞선 예시를 다시 살펴보면, 요소가 나타날 때 흐림 효과를 적용하고 사라질 때 슬라이드 효과를 적용하고 싶다면 어떻게 해야 할까요? 그 방법은 다음과 같습니다.

<script>
  import { blur, slide } from 'svelte/transition';
  let visible = false;
</script>
{#if visible}
<div in:blur out:slide>여기 있어요...</div>
{/if}
<button on:click={()=>visible=!visible}>
  {visible ? "숨기기" : "보이기"}
</button>

위 코드 블록에서 `div` 요소에 전환 지시어가 없는 것을 볼 수 있습니다. 대신, 전환 지시어는 각각 `blur` 및 `slide` 효과를 가리키는 `in` 및 `out` 지시어로 대체되었습니다.

Svelte 요소에 애니메이션 적용하기

Svelte에서 요소에 애니메이션을 적용하는 가장 편리한 방법 중 하나는 `svelte/animate`의 `flip` 기능을 사용하는 것입니다. `flip`은 ‘First, Last, Invert, Play’의 약자입니다. 이 함수는 `delay`, `duration`, `easing`의 세 가지 매개변수를 허용합니다. 다음 코드를 살펴보세요.

<script>
  import { flip } from "svelte/animate";
  let originalList = ["토마토", "빵", "생선", "우유", "고양이 사료"];
  let shoppingList = [...originalList];
</script>
<div class="container">
  {#each shoppingList as item (item)}
    {@const number = shoppingList.indexOf(item)}
    <div animate:flip>
      {number + 1}. {item}
    </div>
  {/each}
</div>
<button on:click={() => shoppingList = shoppingList.sort()}>정렬</button>
<button on:click={() => shoppingList = [...originalList]}>초기화</button>

위의 코드 블록은 Svelte에서 `animate` 지시어를 사용하는 방법을 보여줍니다. 스크립트 태그에서 첫 번째 줄은 `flip` 함수를 가져옵니다. `originalList`와 `shoppingList`라는 두 개의 배열이 있습니다. “container” `div` 내에서 키 지정된 `each` 블록은 `shoppingList` 배열의 모든 요소를 렌더링하는 역할을 합니다.

“container” `div`의 하위 `div`에는 `flip` 기능을 가리키는 `animate` 지시어가 있습니다. 첫 번째 버튼을 누르면 목록이 알파벳순으로 정렬되고, 두 번째 버튼을 누르면 목록이 초기 상태로 재설정됩니다. 브라우저에서 코드를 실행하면 다음과 같은 결과가 표시됩니다.

웹 애플리케이션에서 애니메이션이 중요한 이유

애니메이션의 중요성은 단순히 시각적으로 보기 좋은 것 이상입니다. 애니메이션은 사용자 경험을 향상시키고 효과적인 의사소통을 가능하게 하는 핵심 요소입니다. 애니메이션은 미학과 기능성을 결합하여 웹 애플리케이션에 생동감을 불어넣어 더욱 매력적이고 직관적으로 만듭니다.