트랜지션으로 두 상태 사이를 부드럽게 잇게 되자, 곧 그것만으로는 부족한 상황이 찾아왔다. 계속 빙글빙글 도는 로딩 표시나, 여러 단계를 거치며 통통 튀는 움직임은 상태가 둘뿐인 트랜지션으로는 표현할 수 없었다. 시작과 끝만이 아니라 그 사이의 여러 지점을 내가 직접 정의하고, 그 흐름을 스스로 반복하게 만들 도구가 필요했다. 그게 바로 애니메이션이었다.


이번 편은 여러 단계를 스스로 밟아가는 애니메이션을 다룬다. 트랜지션과 무엇이 다른지, 움직임의 각 단계를 정의하는 키프레임을 어떻게 쓰는지, 애니메이션을 세밀하게 조율하는 여러 설정과 실전에서 자주 쓰는 패턴, 그리고 성능과 접근성까지 살펴본다. 키프레임을 손에 쥐면 화면 위에서 훨씬 풍부하고 자율적인 움직임을 만들 수 있다.

1. 트랜지션을 넘어서는 움직임

트랜지션과 애니메이션은 둘 다 시간에 걸쳐 값을 변화시킨다는 점에서 닮았지만 성격이 다르다. 트랜지션은 어떤 계기로 상태가 바뀔 때 두 값 사이를 한 번 이어주는 것이고, 애니메이션은 여러 단계로 구성된 움직임을 스스로 재생하는 것이다. 나는 이 차이를 계기의 유무로 이해한다. 트랜지션은 변화의 계기가 있어야 하지만, 애니메이션은 스스로 시작된다.


애니메이션의 가장 큰 장점은 중간 단계를 마음대로 정의할 수 있다는 점이다. 트랜지션이 시작과 끝만 알 수 있는 데 비해, 애니메이션은 진행 과정의 여러 지점에서 값을 지정할 수 있다. 나는 요소를 위로 올렸다가 다시 제자리로 내리는 것처럼, 왔다 갔다 하는 움직임을 만들 때 이 중간 단계의 힘을 실감한다. 트랜지션으로는 이런 왕복이 불가능하다.


또 하나의 차이는 반복이다. 애니메이션은 정해진 횟수만큼, 혹은 무한히 스스로 반복할 수 있다. 로딩 표시가 사용자의 개입 없이 계속 도는 것이 대표적이다. 트랜지션은 계기가 있을 때마다 한 번씩 일어나지만, 애니메이션은 한 번 걸어두면 알아서 되풀이된다. 나는 지속적으로 살아 움직여야 하는 요소에는 반드시 애니메이션을 쓴다.


애니메이션은 요소가 화면에 나타나는 순간 자동으로 재생될 수 있다. 사용자가 아무 동작을 하지 않아도, 요소가 등장하면서 정해진 움직임을 펼치는 것이다. 나는 화면이 처음 뜰 때 요소들이 부드럽게 떠오르며 나타나는 효과를 애니메이션으로 만든다. 이런 진입 효과는 사용자의 계기가 없으므로 트랜지션으로는 낼 수 없고 애니메이션의 몫이다.


물론 애니메이션이 항상 트랜지션보다 나은 건 아니다. 단순히 마우스를 올렸을 때 색이 바뀌는 정도라면 트랜지션이 더 간결하고 적합하다. 나는 상태가 둘뿐이고 계기가 명확하면 트랜지션을, 여러 단계나 반복이 필요하면 애니메이션을 고른다. 도구가 강력하다고 무조건 쓰는 게 아니라, 상황의 복잡도에 맞게 고르는 것이 중요하다.


두 도구는 함께 쓰이기도 한다. 나는 한 요소에 진입 애니메이션을 걸어 자연스럽게 등장시킨 뒤, 그 요소의 상호작용에는 트랜지션을 걸어 반응하게 한다. 자율적인 움직임과 반응적인 움직임이 한 요소 안에 공존하는 것이다. 둘의 성격을 이해하면 각자를 제 역할에 배치해 풍부한 움직임을 조율할 수 있다.

2. 움직임의 단계를 그리는 키프레임

애니메이션의 움직임은 키프레임으로 정의한다. 키프레임은 움직임의 각 시점에 요소가 어떤 상태여야 하는지를 적어두는 설계도다. 나는 키프레임을 애니메이션의 대본이라고 생각한다. 언제 어떤 모습이어야 하는지를 몇 개의 장면으로 적어두면, 브라우저가 그 장면들 사이를 부드럽게 이어 하나의 연속된 움직임으로 만들어 준다.


가장 간단한 키프레임은 시작과 끝, 두 지점만 정의하는 것이다. 시작 상태와 끝 상태를 적으면 그 사이를 브라우저가 보간한다. 이 정도라면 트랜지션과 비슷하지만, 애니메이션은 여기에 반복이나 방향 조절 같은 힘을 더 얹을 수 있다. 나는 단순한 진입 효과라도 반복이나 지연을 조합할 여지를 위해 키프레임으로 정의하곤 한다.


키프레임의 진가는 중간 지점들을 정의할 때 드러난다. 진행 과정을 백분율로 나누어 각 지점의 상태를 지정하면, 여러 단계를 거치는 복잡한 움직임을 만들 수 있다. 나는 요소가 커졌다 작아졌다 하는 맥박 같은 효과를 만들 때, 시작과 중간과 끝의 크기를 각각 지정한다. 중간 지점이 있어야 단조로운 직선 변화를 넘어선 표현이 가능하다.


여러 속성을 한 키프레임 안에서 함께 변화시킬 수도 있다. 각 시점마다 위치와 투명도와 크기를 동시에 지정하면, 여러 변화가 어우러진 입체적인 움직임이 나온다. 나는 요소가 아래에서 떠오르며 서서히 진해지는 진입 효과를 만들 때, 한 키프레임에서 위치와 투명도를 함께 다룬다. 속성들이 조화롭게 움직이면 훨씬 정교한 인상을 준다.


키프레임은 이름을 붙여 정의해두고, 필요한 요소에서 그 이름을 불러 쓴다. 한 번 정의한 움직임을 여러 요소에서 재사용할 수 있는 것이다. 나는 자주 쓰는 진입 효과나 회전 움직임을 이름 붙인 키프레임으로 만들어두고, 여러 곳에서 불러 쓴다. 움직임을 규칙으로 떼어내 재사용한다는 점에서 스타일의 다른 부분과 철학이 같다.


키프레임을 정의할 때는 각 지점 사이의 값이 자연스럽게 이어지는지 신경 써야 한다. 지점들의 값 차이가 너무 급격하면 움직임이 뚝뚝 끊겨 보인다. 나는 키프레임을 짠 뒤 실제로 재생해 보며, 단계 사이가 매끄러운지 확인하고 필요하면 중간 지점을 더한다. 대본을 잘 써도 장면 전환이 어색하면 안 되듯, 키프레임도 흐름을 다듬어야 완성된다.

3. 애니메이션을 조율하는 설정들

키프레임으로 움직임을 정의했다면, 이제 그 움직임을 어떻게 재생할지를 여러 설정으로 조율한다. 얼마 동안 재생할지, 어떤 곡선으로 진행할지, 몇 번 반복할지, 어느 방향으로 재생할지 같은 것들이다. 나는 같은 키프레임이라도 이 설정들을 바꾸면 전혀 다른 느낌이 난다는 걸 알고 나서, 재생 설정을 세밀하게 다루기 시작했다.


지속 시간과 진행 곡선은 트랜지션에서 다룬 것과 같은 원리로 작동한다. 한 번의 재생이 얼마나 걸리는지, 그 안에서 속도가 어떻게 변하는지를 정한다. 나는 회전하는 로딩 표시에는 일정한 속도의 곡선을, 요소가 등장하는 효과에는 끝에서 감속하는 곡선을 쓴다. 재생 시간과 곡선은 애니메이션의 기본 리듬을 만든다.


반복 횟수는 애니메이션만의 중요한 설정이다. 한 번만 재생할 수도, 정해진 횟수만큼 반복할 수도, 무한히 반복하게 할 수도 있다. 나는 진입 효과처럼 한 번이면 충분한 움직임은 한 번만 재생하고, 로딩 표시처럼 작업이 끝날 때까지 계속되어야 하는 움직임은 무한 반복으로 둔다. 반복 설정 하나로 움직임의 성격이 완전히 달라진다.


재생 방향도 조절할 수 있다. 매번 같은 방향으로 재생할 수도 있고, 갈 때와 올 때를 번갈아 뒤집을 수도 있다. 나는 요소가 커졌다 작아지기를 반복하는 효과를 만들 때, 방향을 번갈아 뒤집는 설정을 쓴다. 그러면 키프레임을 끝까지 갔다가 거꾸로 돌아오므로, 시작으로 툭 되돌아가는 어색함 없이 자연스럽게 왕복한다.


재생 전후에 요소가 어떤 상태를 유지할지도 정할 수 있다. 기본적으로 애니메이션이 끝나면 요소는 원래 상태로 돌아가는데, 끝난 상태를 그대로 유지하게 만들 수도 있다. 나는 요소가 나타나 자리를 잡는 진입 효과에서, 끝 상태를 유지하도록 설정한다. 그러지 않으면 애니메이션이 끝나는 순간 요소가 원위치로 튕겨 돌아가 버리기 때문이다.


시작을 미루는 지연과, 재생을 잠시 멈추는 설정도 있다. 지연으로 여러 요소를 차례로 등장시키거나, 특정 조건에서 애니메이션을 일시 정지시킬 수 있다. 나는 목록의 항목들이 하나씩 순서대로 나타나게 할 때 각 항목에 조금씩 다른 지연을 준다. 이런 세밀한 설정들을 조합하면 단순한 키프레임에서 다채로운 연출을 끌어낼 수 있다.

4. 실전에서 자주 쓰는 패턴

실무에서 가장 흔히 쓰는 애니메이션은 로딩 표시다. 작업이 진행 중임을 알리기 위해 무언가가 계속 회전하는 이 효과는, 회전하는 키프레임을 무한 반복으로 재생하고 일정한 속도의 곡선을 주면 완성된다. 나는 데이터를 기다리는 거의 모든 화면에 이런 로딩 표시를 둔다. 사용자에게 시스템이 멈춘 게 아니라 일하고 있음을 알리는 최소한의 예의다.


진입 효과도 자주 쓴다. 요소가 아래에서 떠오르며 서서히 진해지는 움직임은, 위치와 투명도를 함께 바꾸는 키프레임을 한 번 재생하고 끝 상태를 유지하게 하면 된다. 나는 화면이 처음 뜰 때나 새 요소가 추가될 때 이 효과를 써서, 요소가 갑자기 툭 나타나지 않고 부드럽게 자리 잡게 한다. 등장에 약간의 결을 더하는 것만으로 화면이 세련되어 보인다.


주의를 끄는 맥박 효과도 유용하다. 요소가 은은하게 커졌다 작아지기를 반복하면 시선을 부드럽게 유도할 수 있다. 나는 사용자가 놓치면 안 되는 알림이나 새 소식 표시에 이런 효과를 쓴다. 다만 너무 강하거나 빠르면 오히려 거슬리므로, 변화의 폭을 작게 두고 속도를 느긋하게 잡는다. 주의를 끌되 방해하지 않는 선을 지키는 것이 관건이다.


깜빡이며 나타나는 자리표시 효과도 흔하다. 콘텐츠가 로딩되기 전, 회색 상자가 은은하게 밝아졌다 어두워지기를 반복하며 곧 내용이 들어올 자리를 미리 보여주는 것이다. 나는 이 효과로 로딩 중에도 화면의 뼈대를 먼저 보여준다. 빈 화면을 멍하니 기다리는 것보다, 곧 채워질 윤곽이 보이면 사용자가 훨씬 덜 답답해한다.


여러 요소를 시차를 두고 등장시키는 연출도 자주 쓴다. 각 요소에 조금씩 다른 지연을 주면, 하나씩 차례로 나타나며 리듬감 있는 흐름이 생긴다. 나는 카드 목록이나 메뉴 항목이 처음 나타날 때 이 시차 효과를 준다. 모두가 동시에 나타나는 것보다, 순서대로 등장하는 편이 시선을 자연스럽게 이끌고 생동감을 준다.


이런 패턴들은 대부분 이름 붙인 키프레임 몇 개로 정리해두면 반복해서 쓸 수 있다. 나는 프로젝트를 시작할 때 자주 쓰는 움직임들을 미리 키프레임으로 만들어 모아둔다. 그러면 새 컴포넌트에 움직임이 필요할 때마다 처음부터 짜지 않고 불러 쓰기만 하면 된다. 검증된 패턴을 재사용하면 작업이 빨라지고 움직임의 일관성도 유지된다.

5. 성능과 접근성을 지키는 애니메이션

애니메이션은 트랜지션보다 오래, 자주 재생되므로 성능에 더 민감하다. 특히 무한 반복하는 애니메이션은 화면에 계속 남아 끊임없이 자원을 쓴다. 나는 무한 반복 애니메이션일수록 성능이 좋은 속성만 쓰도록 각별히 신경 쓴다. 배치를 다시 계산하게 하는 속성을 무한 반복하면, 저사양 기기에서 화면 전체가 무거워지기 때문이다.


앞선 편에서 다룬 원칙이 여기서도 그대로 적용된다. 요소를 움직이거나 키우는 것은 변형으로, 나타나고 사라지는 것은 투명도로 처리하면 배치 계산 없이 매끄럽게 재생된다. 나는 키프레임을 짤 때 되도록 변형과 투명도만으로 표현하려 한다. 같은 움직임이라도 비용이 적은 속성으로 짜면 어떤 기기에서든 부드럽게 돌아간다.


화면 밖에 있는 요소의 애니메이션도 신경 쓸 지점이다. 보이지 않는 곳에서 애니메이션이 계속 돌면 아무도 보지 못하는 움직임에 자원을 낭비하는 셈이다. 나는 화면에 보일 때만 애니메이션이 재생되도록 관리해서 불필요한 낭비를 줄인다. 특히 무한 반복 효과는 화면 밖에서 멈추게 하는 것만으로도 성능이 눈에 띄게 나아진다.


접근성은 애니메이션에서 특히 중요하다. 크고 반복적인 움직임은 어떤 사용자에게 어지럼증이나 불편을 유발할 수 있다. 나는 움직임을 줄이고 싶어 하는 사용자의 설정을 감지해, 애니메이션을 멈추거나 아주 약하게 줄이는 대비를 반드시 함께 둔다. 화려한 연출보다 모두가 편히 볼 수 있는 화면이 먼저다. 이 배려는 선택이 아니라 기본이라고 생각한다.


움직임을 완전히 없애는 대신, 대체 표현을 두는 절충도 좋다. 이를테면 위치가 크게 움직이는 진입 효과를 움직임 없이 투명도만 바뀌는 은은한 효과로 대체하는 식이다. 나는 움직임에 민감한 사용자에게도 정보 전달에 필요한 최소한의 신호는 남기려 한다. 무조건 다 끄는 것이 아니라, 불편을 주는 요소만 덜어내는 세심함이 더 나은 배려다.


정리하면 애니메이션은 키프레임으로 여러 단계를 정의하고 반복과 방향을 조율해 스스로 재생되는 움직임이며, 성능이 좋은 속성으로 짜고 접근성을 챙길 때 비로소 완성된다. 나는 검증된 패턴을 재사용하며, 부드러움과 배려를 함께 담으려 한다. 다음 편에서는 이 움직임의 핵심 도구였던 변형을 더 깊이, 특히 입체적인 삼차원 공간까지 파고든다.