시선을 사로잡는 캐로셀 컴포넌트 Flicking 을 소개합니다

Jongmoon Yoon
NAVER FE Platform
Published in
12 min readJul 5, 2019

당신이 사용하는 캐로셀 컴포넌트는 콘텐츠에 활력을 불어넣어주는 역할을 하고 있나요? 아니면 그냥 익숙한 그저 그런 캐로셀 컴포넌트인가요?

Flicking 은 2011년 부터 NAVER 모바일 메인 페이지에 적용되기 시작하여 이제는 매일 3,000 만 명이 사용하는 NAVER 서비스에서 널리 활용되는 캐로셀(Carousel) 컴포넌트입니다. 2015년 부터 egjs 라는 오픈소스 프로젝트로 공개된 이후 현재는 egjs-flicking 이라는 별도의 github 저장소에서 운영되고 있습니다.

콘텐츠를 더욱 돋보일 수 있게 하는 스포트라이터가 되어야 한다는 Flicking v3 의 철학을 README 에서 전달하고 싶었지만 모든 내용을 다루기에는 너무 제한 적이었습니다.

이 문서를 통해 README 에서 다루지 못했던 Flicking 컴포넌트의 주요 특징들이 여러분께 잘 전달되길 바라며 이 글을 시작합니다.

크로스 프레임워크를 ‘제대로’ 지원할 수 있는 구조

더욱 높은 개발 생산성을 위한 개발 패러다임의 변화에 맞춰 Flicking 은 다양한 프레임워크를 효과적이며 효율적으로 지원할 수 있는 구조를 고안했습니다.

이로인해 (2019년 7월 1일 현재) Vanilla JavaScript 개발 환경 뿐만 아니라 React, Vue, Angular 프레임워크 컴포넌트도 제공할 수 있게 되었으며 향후에도 적은 비용으로 다양한 프레임워크를 지원할 수 있는 기반을 갖추었습니다.

다양한 프레임워크의 지원

이런 구조적 기반으로 인해 Flicking 은 각 프레임워크 전용 컴포넌트와 동일한 사용성과 동작방식을 갖습니다. (크로스 플랫폼 지원 방식에 대해서는 다른 글로 소개할 수 있도록 하겠습니다.)

실제로 많은 프레임워크 용 라이브러리들은 유명 캐로셀 라이브러리를 단순히 감싸서 구현하는 경우가 많은데요. 이런 방식은 프레임워크의 동작방식과 다른 방식으로 사용해야 하거나 기능을 제한적으로 사용할 수 밖에 없는 등의 문제가 있습니다. 특히 프레임워크의 DOM 관리와 충돌하여 데이터 동기화 이슈를 유발하기도 합니다. 그러나 Flicking v3 에서는 이런 문제들을 해결하였습니다.

다이나믹한 인터렉션

무미건조한 당신의 캐로셀 영역을 생동감있는 영역으로 탈바꿈 시키기 위한 특별한 기능을 제공합니다.

Various Progress

패널(아이템)의 움직임에 따른 각 패널의 위치 정보, 화면에 보이는 비율 등 무려 4가지의 동적인 진행 상태 정보를 제공합니다.
(참고: https://naver.github.io/egjs-flicking/features/progress.html)

예를 들어 getProgress() 는 각 패널 이동 시 각 패널이 특정 위치(hanger, anchor)를 0으로 기준으로 각 패널의 상대적인 위치를 반환합니다.

getProgress() 는 각 패널 별 위치 정보를 반환합니다.
var flicking1 = new eg.Flicking(".flicking1", {
gap: 10,
circular: true,
});

flicking1.on("move", () => {
flicking1.getAllPanels(true).forEach(function (panel) {
panel.getElement().innerHTML = panel.getProgress().toFixed(2);
});
});

이 패널 별 상태 값을 활용하여 각 패널 진행 상태에 따른 다이나믹한 UI 를 만들 수 있습니다

getProgress — Mobile
getProgress — Codepen

또한 전체 진행률(progress)을 기반으로 감각적인 UI 를 구성할 수 있게 됩니다.

progress — Mobile
progress — Codepen

이 외에도 제공되는 진행 상태 정보(getOutsetProgress, getVisibleRatio )를 활용한다면 만들 수 있는 UI 효과들은 무궁무진합니다.

Plugins 지원

위의 진행 상태 정보를 기반으로 사용빈도가 높은 Parallax, Fade, AutoPlay Plugin 을 제공하고 있습니다.

다음은 Parallax 플러그인을 활용한 구현 사례입니다.

Parallax Plugin — Mobile
Parallax Plugin — Codepen

다음과 Parallax 와 투명효과를 적절히 조합하여 다음과 같은 서비스를 구현해 볼 수도 있습니다.

https://m.shopping.naver.com/art/home

Plugin 은 Flicking 컴포넌트와 분리되어 다음의 Plugin 저장소에서 운영하고 있습니다.

이렇게 분리된 Plugin 은 Flicking 컴포넌트의 용량을 가볍게 유지할 수 있게 하면서도 필요 시 다양한 Plugin 의 조합을 통해 화려한 UI 를 구현할 수 있습니다. 앞으로 콘텐츠를 더욱 돋보일 수 있게 하는 플러그인들을 더욱 늘려갈 계획입니다.

Free Scroll

패널이 움직인 후 패널 단위(Hanger/Anchor)로 멈추는 것이 기본 동작이지만 옵션을 통해 사용자 터치의 힘에 따라 자유로운 지점에서 멈출 수 있도록 옵션을 지정할 수 있습니다.

Free Scroll 은 사용자의 힘에 따라 패널이 자유로운 위치에서 멈춥니다.
var flicking = new eg.Flicking(".flicking0", {
gap: 10,
circular: true,
moveType: "freeScroll",
});

동일한 기능을 제공하는 라이브러리로 iScroll 이 있습니다. 그러나 iScroll 은 이제 더 이상 운영하지 않고 아카이빙 모드로 전환된 상황이기 때문에 향후 어떠한 개선이나 이슈에 대한 도움을 받기 어려워진 상황입니다.

아카이브 모드로 전환된 iScroll

대체 가능한 솔루션으로서 Flicking 은 좋은 대안이 될 수 있습니다.

높은 UI 자유도

Flicking 은 다년 간 다양한 서비스에 반영되었습니다. 피드백을 받으면서 각 서비스에서 세부적인 UI 커스터마이징 역시 매우 중요한 요소였습니다. 그 결과 Flicking v3 은 캐로셀 형태에서 활용가능한 다양한 UI 들이 현실화 될 수 있도록 많은 옵션들을 제공하게 되었습니다.

UI 커스터마이징 — Mobile
UI 커스터마이징 — Codepen

Multiple & Variable

Flicking 은 각 패널에 지정된 CSS 속성을 자동으로 읽어와 Flicking 영역에 배치하는 방식으로 서로 다른 다양한 Panel 크기와 여러 개의 패널 동시 보기를 지원할 수 있습니다.

다양한 크기의 패널을 여러 개 보여줄 수 있습니다.
var flicking = new eg.Flicking(".flicking", {
circular: true,
});

이런 옵션은 다음과 같이 각 패널(아이템)의 크기가 다르거나 한번에 여러 패널을 보여주어야 하는 요구 사항을 만족시킬 수 있게 됩니다.

예제1, 예제2 를 통해 적용 예제를 확인할 수 있습니다.

Flexible Alignment

정렬 기준을 자유롭게 조절하여 각 서비스에 딱 들어맞는 UI 를 만들 수 있습니다.

Hanger 와 Anchor 개념을 도입하여 자유로운 정렬 기능이 가능합니다. Hanger 는 캐로셀 전체 영역의 기준점, Anchor 는 각 패널 마다 기준점입니다.각 패널 별 Anchor 는 플리킹 영역의 Hanger 와 맞닿는 부분을 기준으로 정렬됩니다. 이 방식을 적용하면 Left, Center, Right 정렬 외에도 세부적인 정렬이 가능합니다.

Haner & Anchor 를 이용한 중앙 정렬
var flicking1 = new eg.Flicking(".flicking1", {
hanger: "50%",
anchor: "50%"
});
Haner & Anchor 를 이용한 좌측 정렬
var flicking1 = new eg.Flicking(".flicking1", {
hanger: 0,
anchor: 0
});

아래와 같이 원하는 위치를 기준점으로 지정할 수 있습니다.

예제3 에서는 Hanger, Anchor 를 이용해서 좌측 정렬한 사례를 확인할 수 있습니다.

Gap

또한 패널간 간격 지정이 가능합니다. gap 옵션을 지정하면 각 패널 간 간격을 지정할 수 있습니다.

gap: 20px
var flicking1 = new eg.Flicking(".flicking1", {
gap: 20,
bound: true,
});

각 서비스 요구 사항에 따라 미세한 조정이 필요한 패널 간 간격의 지정을 쉽게 할 수 있습니다.

예제 4 에서는 gap 을 지정 함으로써 패널간의 구분이 명확해 지는 효과를 확인할 수 있습니다.

편리한 동적 패널 관리

패널의 동적 추가가 편리합니다.

  • 신규 Panel 이 필요한 시점에 이벤트를 통해 새로운 패널이 필요한 시점을 알려줍니다.
  • 패널의 동적 추가 작업을 위한 메소드를 제공합니다.(단, 프레임워크에서는 패널 정보를 기반으로 패널을 구성하면 자동으로 DOM 으로 추가가 됩니다.)
패널의 갯수의 동적 증가가 편리합니다.
var flicking1 = new eg.Flicking(".flicking1", {
gap: 10,
infinite: true,
infiniteThreshold: 50,
});
flicking1.on("needPanel", function (e) {
var length = flicking1.getPanelCount();
e.panel.insertAfter(/* panel to add*/);
flickingPagination1.update(flicking1);
});

예제5 에서는 더 다양한 예제를 확인할 수 있습니다.

안정적인 서비스의 운용

매일 3000 만 명의 사용자가 방문하는 네이버 서비스에서 널리 사용 되고 있는 만큼 각 서비스의 요구 사항들과 이슈 대응에 더욱 철두철미 할 수 밖에 없습니다.

여러 서비스를 통해 다양한 환경에서 발생하는 예외 사항들에 대한 피드백을 꾸준히 반영하고 있습니다. 더불어 좋은 품질 유지를 위해 (2019년 7월) 현재 91% 이상의 높은 수준의 코드 커버리지를 갖는 Unit Test 를 정례화 하고 있고 코드 품질 관리 도구와 연계하여 Good 등급을 유지하고 있습니다.

Flicking v3 표현할 수 있는 다양한 뱃지들

맺는말

지난 7년 동안 Flicking 은 네이버 서비스의 전 영역에 걸쳐 활용되어 왔습니다. 매일 3,000 만명의 사용자에게 더욱 안정적이고 신뢰도 있는 품질을 제공하기 위해 피드백을 받으며 지속적으로 개선해왔습니다.

이번 Flicking v3 버전은 그 동안의 안정적인 품질을 기반으로 사용자의 눈길을 사로잡을 수 있는 UI 를 구현할 수 있게 하였습니다. 또한 변화해 가는 개발 환경에 맞춘 효과적인 다양한 프레임워크 지원 방식을 고민하였습니다. 더불어 어떻게 하면 개발자가 직관적이고 편하게 개발할 수 있을지를 고민하였습니다.

이런 고민들과 네이버 개발자들의 피드백을 통해 만들어진 Flicking 이 더욱 더 많은 분들의 공감대를 얻을 수 있었으면 좋겠습니다. 그래서 더 많은 페이지에서 Flicking 이 더 많이 활용될 수 있기를 기대합니다.

마지막으로 egjs 는 오픈소스 프로젝트인 만큼 항상 여러분들의 참여와 피드백을 애타게 기다리고 있습니다. 여러분들의 피드백과 참여가 더 좋은 제품을 만들 수 있는 원동력이 되어줍니다.

여러분의 Star 는 저희에게 많은 힘이 됩니다. 🙏

--

--