Spring 물리 애니메이션?

하늘·2025년 12월 9일

며칠 전, 벨로그 트렌드에서 상당히 재미있는 글을 발견했다. 타락한스벨트전도사 님의 글인데, 내용 중 Spring이라는 단어가 등장한다.

Spring? 자바 그거..?

나름 애니메이션, UX를 공부 중이라고는 했지만 Spring이라는 말을 처음 들어 본 게 조금 부끄럽기도 하고 해서 관련 포스팅을 작성하리라 마음을 먹었다!

Spring은 용수철이다!

그냥 뜻이 그렇다. Spring은 늘어난 만큼 반대로 당기는 힘을 가진 용수철이다.

손으로 용수철을 잡아당겨서 기준점(rest)에서 멀어지면, 그 거리(x)에 비례해서 원래 자리로 돌아오려는 힘이 생긴다.
그래서 용수철을 놓으면 → 기준점으로 향하는 힘(스프링 힘) 때문에 돌아오고, 감쇠(damping) 힘 때문에 속도가 점점 줄어들어 결국 제자리에서 멈춘다.

즉, 용수철을 멀리 잡아당기면 강하게 퐁! 하고 돌아오고, 가까이 잡아당기면 부드럽게 돌아간다. 여기에서 끝나지 않고, 퐁 → 통통 → 통토로로로롱..스르륵.. 하고 점차 움직임이 줄어들고 결국 원래의 위치(기준점)으로 돌아오게 된다.

스프링 애니메이션이 Easing과 무엇이 다를까?

Easing 애니메이션은 시간(duration)에 따라 움직임을 정의하는 방식이다. 애니메이션이 시작되면, 정해진 시간 안에 시작점에서 목표값으로 이동한다.

시간 0% → 시작점
시간 100% → 목표점

이 두 지점을 미리 정해진 곡선 (easing function)을 따라 이동한다.

그래서, easing은 애니메이션의 기준이 duration이므로 목표 위치가 중간에 바뀌면 애니메이션을 다시 시작해야 한다.

발전하는 UX 애니메이션 홍수 속에서, 애니메이션이 다 끝날 때까지 기다려 주는 착한 심성을 가진 사용자가 많을까? 아니면 애니메이션이 끝나기도 전에 애니메이션 트리거 버튼을 누르는 사용자가 많을까?


닫히는 중에도 닫힘 버튼 누르는 K-성질머리!

스프링 애니메이션을 구현해 보자

불행히도 나는 문과 중 쌉1문과생이다. 🥲 스프링 물리 애니메이션을 이해하는 데에 많은 시간이 든 만큼 이 글을 읽는 사람들에게 쉽게 설명해 주고 싶지만, 마음과 달리 애초에 물리학.. 이라서 온전히 내가 배운 이론을 전달하지 못할 때도 있다. 양해 바란다.

Fs = -k * x

Fs는 스프링 힘(Force)이고,
k는 탄성, 즉 스프링의 빡셈 정도(k가 클수록 더 세게, 더 빨리 돌아오려고 함),
x는 기준점에서 얼마나 벗어났느냐(변위)다.

스프링 힘은 오른쪽으로 당기면 왼쪽으로 돌아가고 싶어 하는 탄성(그래서 음수다!)과 거리를 곱하면 된다.
즉, 멀리 벗어날수록 더 크게 발생하고, 항상 원래 자리(rest) 쪽으로 작용한다.

그런데 스프링이 잡아당기고 놓으면 바로 rest로 이동할까?

Fd = -d * v

Fd는 감쇠(damping) 힘이고,
d는 감쇠(damping), v는 velocity(속도)다.

댐핑은 속도의 반대 방향으로 작용하는 힘이라서 수식에서 음수가 붙는다.

속도가 너무 빠를 때 브레이크를 밟으면 → 브레이크도 세게 걸리고,
속도가 느릴 때 브레이크를 밟으면 → 브레이크도 천천히 걸리는 것처럼 말이다.

만약 음수가 아니라 댐핑이 양수라면, 무한 폭주 애니메이션이 생기는 것이다.

결국, 이 수식은

F = Fs + Fd
F = -kv + -dv

이렇게 되는 것이다.

자세한 것은 훅의 법칙에서 더 알아볼 수 있다.

응용해서 만들었어요

Spring 물리 애니메이션을 알면 생각보다 엄청나고 많은 걸 만들 수 있다. GPT에게 스프링 애니메이션을 배웠으니, 무슨 예제를 만들어야 할까? 싶어서 나온 의견을 토대로 아래 데모를 만들었다.

여기에서 확인할 수 있다.

k / d / m를 튜닝해 보자

다시 한 번 더 정리하자면,

k(탄성): 원래 자리로 돌아가려는 힘, UI에서는 탱!! 팡!! 강하게/빨리
d(감쇠): 속도를 줄이고 안정화시키는 브레이크, 통통통 -> 스르륵....
m(질량): 움직이기 어려운 정도, 무거움/묵직함

k ↑ + d ↓: 탄성이 크고 감쇠가 낮으면 팡!! 팅!! 활발하고 발랄한 탄성
k ↓ + d ↑: 탄성이 작고 감쇠가 크면 스르륵... 잔잔..한 느낌

더 탄성 있게 튀기고 싶다면 k를 높이고,
더 빨리 안정시키고 싶으면 d를 높이고,
더 묵직하게 만들고 싶다면 m을 높인다.

위 카드 스프링 데모 사이트에 lil-gui 라이브러리를 활용하여 탄성과 감쇠, 질량의 수치를 변경하여 테스트할 수 있도록 만들었다.

느낀점

어렵다! 어려워!
물리는 역시 어렵다. 그래도 three.jsGLSL Shader 공부할 때 언뜻 들어본 용어들이 있어서 이해 자체가 어렵지는 않았는데, 이걸 어떻게 응용해야 다양하고 재미있는 애니메이션을 구현할지가 큰 고민이다.

하지만 어려운 만큼 재미있다. 이걸 통해서 만들어 보고 싶은 레퍼런스가 마구마구 떠오른다. 기회 되면 더 만들어 보는 걸로! 일단은 모션 블로그 만드는 게 최우선이다..

참고자료

https://velog.io/@k-svelte-master/optimize-frontend-performance-interview
https://www.kyoyoung.dev/posts/spring
https://ko.wikipedia.org/wiki/%ED%9B%85%EC%9D%98_%EB%B2%95%EC%B9%99
https://bepyan.me/post/animations-on-the-web/
https://www.joshwcomeau.com/animation/a-friendly-introduction-to-spring-physics/

profile
아무튼 어찌저찌 하고 있습니다.... 🫠

2개의 댓글

comment-user-thumbnail
2025년 12월 21일

게쩐다

1개의 답글