Lottie Inspector

Lottie 색상을 코드로 바꾸기 — keypath 완벽 정리

THEMING · 2026. 8. 13

다크모드를 지원하는 순간 모든 Lottie 에셋이 문제가 됩니다. 라이트용·다크용 파일을 두 벌씩 관리할 수도 있지만, 파일 수가 두 배가 되고 디자이너의 수정도 두 배가 됩니다. 정석은 파일은 한 벌, 색은 코드에서 교체하는 것이고, 그 열쇠가 keypath입니다. 이 글은 keypath가 무엇인지, 어떻게 찾는지, 플랫폼별로 어떻게 쓰는지, 그리고 제가 실제로 밟았던 함정들을 정리한 것입니다.

keypath란 — 레이어를 찾아가는 주소

Lottie 애니메이션은 레이어의 트리 구조입니다. keypath는 그 트리에서 특정 속성까지 내려가는 경로 문자열로, 폴더 경로와 비슷하게 생겼습니다. 예를 들어 Heart / Fill 1 / Color는 "Heart 레이어 안의 Fill 1 셰이프의 색상 속성"을 가리킵니다. 중간 단계를 생략하고 싶을 때는 와일드카드를 씁니다.

그래서 실무에서 가장 많이 쓰는 형태는 **.primary_fill.**.Color처럼 "이름이 primary_fill인 레이어를 어디에 있든 찾아서 색을 바꿔라"입니다.

레이어 이름부터 확인하기

keypath를 쓰려면 대상 레이어의 이름을 알아야 합니다. 파일을 Lottie Inspector에 올리면 카드마다 레이어 수가 표시되는데, 이름까지 봐야 한다면 JSON을 직접 열어 "nm" 필드를 찾는 것이 가장 확실합니다. 레이어 이름이 Shape Layer 24 같은 기본값이라면 — 그 파일은 코드로 색을 바꾸기 어려운 파일입니다. 디자이너에게 교체 대상 레이어만이라도 약속된 이름(primary_fill, surface_fill 등)으로 정리해 달라고 요청하는 것이 순서입니다. 이 네이밍 약속 하나가 플랫폼 세 곳의 코드를 전부 안정시킵니다.

플랫폼별 색 교체 코드

웹 (lottie-web)

// SVG 렌더러라면 CSS로도 가능하지만, 정석은 재로드 전 데이터 수정 또는
// 렌더 후 SVG 엘리먼트 선택입니다. 간단한 경우:
document.querySelectorAll('#anim path[fill="#0089A6"]')
  .forEach(function (p) { p.setAttribute('fill', newColor); });

lottie-web에는 iOS·Android 같은 공식 동적 속성 API가 없어서, 웹은 SVG DOM을 직접 만지거나 로드 전에 JSON의 색 값을 치환하는 방식을 씁니다. 색 값이 JSON에 [0.0, 0.537, 0.651, 1]처럼 0~1 RGBA 배열로 저장된다는 것만 알면 치환 코드는 단순합니다.

iOS (lottie-ios)

LottieView(animation: .named("spinner"))
  .valueProvider(
    ColorValueProvider(UIColor.label.lottieColorValue),
    for: AnimationKeypath(keypath: "**.primary_fill.**.Color")
  )

Android (lottie-compose)

rememberLottieDynamicProperty(
  property = LottieProperty.COLOR,
  value = MaterialTheme.colorScheme.primary.toArgb(),
  keyPath = arrayOf("**", "primary_fill", "**"),
)

Flutter (lottie 패키지)

ValueDelegate.color(const ['**', 'primary_fill', '**'],
    value: Theme.of(context).colorScheme.primary)

제가 밟았던 함정 3가지

교체가 잘 됐는지는 라이트/다크 배경 위에서 직접 봐야 확실합니다. 뷰어의 배경 전환으로 두 테마 모두 확인한 뒤 통합하세요.