Cross Flicking
CrossFlicking은 가로·세로 Flicking을 하나의 2D 캐러셀로 결합한 프리셋 클래스입니다. 가로로 스와이프하면 그룹 간 전환, 세로로 스와이프하면 그룹 내 항목 탐색이 이루어집니다.
- JavaScript
- React
- Vue@3
요약
주요 옵션
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
sideOptions | Partial<FlickingOptions> | {} | 자동 생성되는 세로(side) Flicking 인스턴스에 적용되는 옵션 |
preserveIndex | boolean | true | 그룹 전환 시 각 그룹의 side 인덱스를 유지 |
disableSlideOnHold | boolean | true | 한 방향으로 드래그하는 동안 수직 축을 잠금 |
disableIndexSync | boolean | false | main/side 간 자동 인덱스 동기화 비활성화 |
CrossFlicking은 모든 FlickingOptions(예: moveType, bound)도 받으며, 이들은 가로 방향 main 축에 적용됩니다.
구조
| 레벨 | 방향 | 역할 |
|---|---|---|
Main Flicking (CrossFlicking) | 가로 (↔) | 그룹 간 이동 |
| Side Flicking (자동 생성) | 세로 (↕) | 그룹 내 이동 |
각 그룹은 camera의 직속 자식으로, 그 자식들이 세로 side 패널이 되는 래퍼 <div>입니다.
상세 설명
CrossFlicking 동작 방식
CrossFlicking은 초기화 시 DOM에서 그룹 구조를 읽어 각 그룹을 독립적인 세로 Flicking으로 재구성합니다. 외부 인스턴스는 그룹 간 가로 이동을 처리하고, 각 그룹은 자체 세로 이동을 관리하여 — 하나의 클래스로 격자형 2D 네비게이션을 만들어냅니다.
프레임워크별 작성법
모든 프레임워크에서 데모는 코어 CrossFlicking 클래스를 명령형으로 구동합니다. 패널을 래퍼 <div>로 묶고 뷰포트 요소를 생성자에 전달합니다.
import { CrossFlicking } from "@egjs/flicking"; // 또는 "@egjs/vue3-flicking"
new CrossFlicking("#cross", {
align: "prev",
moveType: "strict",
bound: true,
sideOptions: { moveType: "strict", bound: true }
});
<div id="cross" class="flicking-viewport">
<div class="flicking-camera">
<div><!-- 그룹: Nature -->
<div class="cross-panel">Forest</div>
<div class="cross-panel">Meadow</div>
</div>
<div><!-- 그룹: Ocean -->
<div class="cross-panel">Reef</div>
<div class="cross-panel">Wave</div>
</div>
</div>
</div>
@egjs/react-flicking도 CrossFlicking/CrossGroup 컴포넌트를 export하지만, 현재 React StrictMode에서 정상 동작하지 않습니다(비동기 init이 끝나기 전에 인스턴스가 destroy됨). 이 문제가 해결되기 전까지는 이 데모처럼 useEffect/onMounted에서 코어 클래스를 직접 구동하세요. Vue3에는 전용 래퍼가 없으므로 코어 클래스가 유일한 방법입니다.
이벤트
Main 축 이벤트(changed, willChange)는 활성 그룹의 side 인덱스를 가리키는 sideIndex 필드를 추가로 전달합니다. Side 축 이벤트는 side 접두어가 붙으며, 어느 그룹이 이동했는지 식별하는 mainIndex를 전달합니다.
| 이벤트 | 페이로드 | 설명 |
|---|---|---|
changed | { index, sideIndex } | 가로(그룹) 인덱스 변경됨 |
sideChanged | { index, mainIndex } | 그룹의 세로(항목) 인덱스 변경됨 |
sideWillChange | { index, mainIndex } | 그룹의 세로 인덱스가 변경되기 직전 |
연관 옵션
moveType: "strict"와의 조합: 스와이프 한 번에 정확히 그룹/항목 하나씩 이동하여 격자 네비게이션이 명확해집니다.bound: true와의 조합: 양쪽 축 가장자리에서 빈 공간을 방지합니다.sideOptions: 가로 인스턴스와 별개로 세로 인스턴스를 설정합니다.
사용 시나리오
- 카테고리 기반 갤러리 (가로로 카테고리, 세로로 항목)
- 스토리/릴 뷰어 (가로로 작성자, 세로로 게시물)
- 대시보드 (가로로 섹션, 세로로 카드)
주의사항
- 세로 side 인스턴스는 고정된 레이아웃 높이가 필요하므로, 뷰포트에 명시적인 높이를 지정하세요.
CrossFlicking은 초기화 시 그룹 DOM을 재구성합니다. 원본 마크업이 그대로 유지된다고 가정하지 말고 그룹을 래퍼 요소로 작성하세요.- Vue에는
CrossFlicking/CrossGroup컴포넌트 래퍼가 없습니다 —ref+onMounted로 코어 클래스를 사용하고, 언마운트 시destroy()를 호출하세요.
관련 링크
관련 API
CrossFlicking: 2D 크로스 방향 캐러셀 프리셋 클래스CrossFlickingOptions: CrossFlicking 설정
관련 데모
- Nested: 같은 방향 중첩을 위한
nested옵션의 on/off 비교 - Fullpage Scroll: 세로 방향 풀페이지 패턴