지그재그는 상품 판매를 촉진하기 위해 이벤트나 기획전을 주요 마케팅 수단으로 활용합니다. 기획전은 한정된 기간 동안 고객에게 특정 상품 정보와 추가적인 할인 혜택을 명확하게 제시하여 판매를 유도하는 역할을 합니다. 따라서 다양한 기획전을 지속적으로 발행해 고객의 관심을 유도하고, 브랜드 충성도를 높이며, 구매율을 증가시키고 있습니다. 또한, 다양한 테마와 카테고리별 기획전을 통해 고객의 소비 패턴과 선호도에 맞춘 맞춤형 쇼핑 경험을 제공합니다. 이러한 전략은 이커머스 사이트의 경쟁력을 강화하고 지속적인 성장을 도모하는 데 중요한 역할을 합니다.
지그재그 앱에서는 다양한 지면에 기획전을 노출시키고 있어요!
기획전 제작에는 여러 고려사항과 어려움이 따랐습니다.
첫째, 기획전은 대부분 특정 기간에만 활용됩니다. 패션 산업의 특성상, 시즌별로 특정 상품이 강조되며 그에 맞는 혜택이 제공됩니다. 이러한 특성 때문에 기획전은 일회성이 강하며, 매 시즌마다 새로운 기획전을 준비해야 했습니다.
둘째, 각 기획전은 고유의 컨셉과 다양한 콘텐츠 형태를 요구합니다. 상품의 판매 상태, 재고 변동, 고객 반응 등 동적인 요소가 기획전 콘텐츠에 반영되므로 매번 요구사항이 다를 수밖에 없습니다. 이로 인해 개발 기간과 범위를 명확히 설정하고 효율적으로 개발을 진행해야 합니다.
셋째, 기획전 제작에는 다양한 전문가들의 협업이 필수적입니다. 상품 기획, 디자인, 개발, 품질 테스트 등 여러 분야의 전문가들이 함께 작업해야 합니다. 예를 들어, MD는 상품 선택과 정렬을, 디자이너는 시각적 표현을, 개발자는 기능 구현을, QA는 최종 검증을 담당합니다. 이러한 협업은 기획전의 완성도를 높이는 중요한 과정입니다.
마지막으로, 기획전의 성과를 평가하기 위해 방문자 수, 판매량, 클릭률 등의 지표를 추적하고 분석해야 합니다. 이 데이터를 바탕으로 다음 기획전을 최적화하거나 전략을 재조정할 수 있습니다. 이 과정은 지속적인 관리와 업데이트를 필요로 합니다.
우리 팀은 이러한 어려움을 해결하기 위해 CMS(Content Management System)를 도입했습니다. 이를 통해 개발자가 매번 기획전을 직접 만드는 대신, 기획자가 스스로 콘텐츠를 입력하고 기획전을 구성할 수 있게 되었습니다. 특별한 컨셉이나 디자인이 필요할 때만 디자이너의 도움을 받는 방식으로, 개발자의 작업 부담을 줄이면서 기획전 운영의 유연성을 높였습니다. 우리는 이 도구를 ‘콘텐츠 에디터’라고 부르고 있습니다.
기획전 페이지는 평균적으로 2주에 260여 개의 기획전이 생성되며, 대부분의 경우 CMS를 통해 제작할 수 있었습니다. 그러나 일반 기획전과 달리 동적인 콘텐츠로 사용자에게 강렬한 인상을 남기고 후킹 요소를 포함하는 ‘프로모션 기획전’이 분기별로 7~8회 정도 진행됐고, 이 기획전을 위한 콘텐츠는 개발자가 직접 작업해야 했습니다.
따라서, 콘텐츠 에디터에서 다양한 애니메이션 효과를 간편하게 설정할 수 있도록 하는 것이 필요했습니다. 이를 통해 모든 종류의 기획전을 개발자에게 의존하지 않고, 기획자들이 직접 제작할 수 있는 환경을 구축하고자 했습니다. 이 목표를 달성하기 위해, 우리는 애니메이션 설정을 직관적이고 쉽게 사용할 수 있는 방식으로 콘텐츠 에디터에 통합하는 작업을 진행했습니다.
사실, 요구된 애니메이션 효과는 그다지 복잡하지 않았습니다. 대부분의 쇼케이스 애니메이션은 화면에 등장할 때 페이드 인(fade in) 되면서 자연스럽게 위로 이동하는 정도의 애니메이션이었습니다. 그러나 여러 요소가 그룹으로 묶여 동시 또는 시차를 두고 발생하는 애니메이션이 필요했습니다.
애니메이션 편집 모듈을 개발하는데, 몇 가지 고민사항이 있었습니다.
intersectionObserver
를 통해 발생하는데, 개발자가 아닌 사람이 이를 어떻게 직관적으로 이해할 수 있을지 고민이 있었습니다.framer-motion
을 이용해 여러 애니메이션 효과를 어떻게 독립적으로 적용할 수 있을지 고민했습니다.당시에는 기획은 있었으나, 별도의 디자이너 없이 메뉴 구성을 고민해야 했습니다. 원래는 모달 창을 사용하여 편집하는 방식을 계획했지만, 이미 이미지 선택과 액션 설정 등에서 모달이 사용되고 있어 중복으로 모달 창이 열리는 UI 문제가 발생할 수 있었습니다. 따라서, 다른 편집 요소와 조화롭게 통합될 수 있도록 더 매끄러운 디자인을 구현하는 데 주력했습니다.
위 애니메이션은 기존 쇼케이스에서 사용된 샘플로, 배경 이미지 위에 4개의 요소가 약간의 시차를 두고 동시에 등장하는 방식입니다. 이 샘플을 바탕으로 애니메이션을 어떻게 계층화했는지 소개하겠습니다.
애니메이션 씬
(Scene) > 애니메이션
(Group) > 클립
(이미지, 문자, 모듈)> 효과
(나타나기, 사라지기)
Fade In/Out
, Move In/Out
, Floating
, Swipe In/Out
, Scale In/Out
등의 효과를 적용할 수 있습니다. 효과는 중복 적용이 가능합니다.하나의 설정 영역에서 모든 애니메이션을 편집하려 했다면, 복잡한 UI 요소와 많은 공간이 필요했을 것입니다. 그러나 애니메이션 씬과 애니메이션 그룹을 분리함으로써, 배경 설정과 다수의 애니메이션을 효과적으로 배치할 수 있었습니다. 이렇게 분리된 편집 영역 덕분에, 각 애니메이션의 구성 요소가 한눈에 파악 가능해졌습니다.
애니메이션은 스크롤하다가 화면에 보일 때 발생을 해야 합니다. 그리고 발생하는 위치는 요구사항에 따라 조금씩 변경이 필요합니다. 콘텐츠 에디터에서는 미리보기 영역이 존재하여 현재 콘텐츠의 편집 내용을 바로 확인할 수 있습니다. 여기서 애니메이션에는 하단에 굵은 선이 있어서, 해당 선이 보이는 타이밍에 애니메이션이 발생하도록 설정되어 있어서 직관적으로 설정할 수 있게 했습니다.
Framer Motion
은 React
기반 애니메이션 라이브러리로, 복잡한 애니메이션을 쉽게 구현할 수 있도록 도와줍니다. 기존 쇼케이스에서도 이를 사용해 다양한 애니메이션을 제작해왔으며, Framer Motion
을 통해 사용자들이 어떻게 쉽게 애니메이션을 설정하고, 여러 애니메이션을 서로 독립적으로 적용할 수 있는지에 대해 다루어 보겠습니다.
위 애니메이션은 오른쪽으로 이동하면서, 불투명도가 높아지는 애니메이션이고, 코드로 나타내면 다음과 같습니다.
const moveEffect = {
before: { x: 0, y: 0, opacity: 0.3 },
after: { x: 13, y: 0, opacity: 1 },
transition: { duration: 300, delay: 0 },
};
이 코드는 애니메이션 시작과 끝에서의 값을 지정하며, x 값이 0에서 13으로 변하고, 불투명도(opacity)가 0.3에서 1로 변화하는 애니메이션입니다. 300ms 동안 지연 없이 애니메이션이 실행됩니다.
애니메이션 설정 시, 구체적인 수치보다는 추상화된 옵션을 제공하는 것이 좋습니다. 예를 들어, 이동 방향을 x축 값으로 지정하기보다는 상/하/좌/우로 설정하고, 이동 거리를 보통
, 조금
, 많이
등으로 구분해 제공하는 방식이 더 유용합니다.
이제 애니메이션 효과를 중복 적용할 때 발생할 수 있는 문제를 살펴보겠습니다. 서로 다른 애니메이션 효과가 동일한 속성을 변경하려 할 경우, 예상치 못한 충돌이 발생할 수 있습니다.
예를 들어, Fade In
과 Move In
애니메이션이 동시에 적용된 경우, Fade In
은 opacity
만 변경하고, Move In
은 x
값만 변경하므로 충돌이 발생하지 않습니다.
그러나 다음의 상황에서는 문제가 있을 수 있습니다.
아래 클립에 적용된 효과는 Floating
효과입니다. x
축 또는 y
축으로 진자 운동을 표현합니다. 이 경우에 Move In 효과와 함께 사용되면 같은 x 또는 y 속성을 서로 변경하려고 할것 입니다. 이 경우에 서로 어떤 영향을 미칠지 쉽게 예측이 안됩니다.
애니메이션 효과의 시작 값과 끝나는 값 사이의 변화를 델타(delta
)라고 할 때, 중복 애니메이션 효과를 적용하기 위해 처음에는 모든 애니메이션 효과의 델타를 각 속성별로 일일이 계산하려 했습니다. 예를 들어, y
와 x
값은 더하고, opacity
는 곱하는 방식이었습니다. 그러나 곧 이것이 너무 복잡하다는 것을 깨달았습니다. 이렇게 하면 테스트 코드의 양이 크게 증가할 뿐만 아니라, 새로운 효과가 추가될 때마다 계속해서 검증 코드를 작성해야 하고, 다른 효과까지 영향을 미칠 가능성이 높았습니다. 이 방법이 정말 옳은 방향일까 고민하게 되었습니다.
모든 애니메이션 효과의 상호작용을 다 테스트하려면 너무나 복잡해질 뿐만 아니라, 애니메이션 효과의 수가 증가할수록 테스트 난이도도 급격히 올라갈 것입니다.
이 문제를 해결하기 위해, 애니메이션 효과를 여러 레이어로 나누어 각각의 레이어가 독립적으로 애니메이션 효과를 계산하고 렌더링하도록 했습니다. 이렇게 하면 개별 애니메이션 효과가 검증되면, 다른 효과에 영향을 미치지 않도록 할 수 있습니다.
다음은 간단하게 도식화한 코드입니다.
AnimationClip
에서 실제로 Clip
을 렌더링하며, FilterOverlap
과 MotionOverlap
이 각각 애니메이션 효과를 발생시킵니다. MotionOverlap
은 위치와 크기를 변경하는 애니메이션 효과를, FilterOverlap
은 클립의 크기는 유지하면서 투명도나 그레이스케일, 색상 보정, 부분 노출 등의 애니메이션 효과를 처리합니다.
FilterOverlap
을 조금 더 상세히 보면, 내부적으로 fade_in/out
, scale_in/out
등의 애니메이션 효과가 중첩되어 있으며, Filter
효과끼리도 서로 간섭 없이 독립적으로 작동하는 구조를 가지고 있습니다. 다만, fade_in/out
처럼 한 효과의 끝이 다른 효과의 시작이 되는 쌍은 하나의 효과로 관리됩니다.
지금까지 지그재그에서 기획전 페이지의 애니메이션 편집 기능을 개발한 과정을 다루었습니다. 이 기능이 개발된 후로, 프로모션용 페이지 제작에 소요되던 시간이 크게 절약되었습니다. 그 결과, 급작스러운 업무 증가를 줄이고 인적 자원을 많이 절감할 수 있었으며, 지속적으로 요구되는 애니메이션 효과를 안정적으로 추가할 수 있는 구조를 갖추게 되었습니다.