Auto Resize
autoResize와 useResizeObserver 옵션으로 뷰포트 크기 변경 감지 방식을 제어합니다.
슬라이더로 컨테이너 너비를 변경하면서, 두 캐러셀의 리사이즈 반응 차이를 비교해 보세요.
- JavaScript
- React
- Vue@3
import Flicking from "@egjs/flicking"; import "@egjs/flicking/dist/flicking.css"; import "./styles.css"; // useResizeObserver: true (default) const flickA = new Flicking("#flick-observer", { autoResize: true, useResizeObserver: true }); // useResizeObserver: false const flickB = new Flicking("#flick-window", { autoResize: true, useResizeObserver: false }); let countA = 0; let countB = 0; const countElA = document.getElementById("count-a"); const countElB = document.getElementById("count-b"); flickA.on("afterResize", () => { countElA.textContent = ++countA; }); flickB.on("afterResize", () => { countElB.textContent = ++countB; }); // Change container width via slider const slider = document.getElementById("width-slider"); const valueLabel = document.getElementById("width-value"); const wrapA = document.getElementById("wrap-a"); const wrapB = document.getElementById("wrap-b"); slider.addEventListener("input", () => { const w = `${slider.value}%`; wrapA.style.width = w; wrapB.style.width = w; valueLabel.textContent = `${slider.value}%`; }); // Toggle autoResize const toggleBtn = document.getElementById("btn-toggle"); let autoResizeOn = true; toggleBtn.addEventListener("click", () => { autoResizeOn = !autoResizeOn; flickA.autoResize = autoResizeOn; flickB.autoResize = autoResizeOn; toggleBtn.textContent = `autoResize: ${autoResizeOn}`; toggleBtn.classList.toggle("active", autoResizeOn); document.getElementById("manual-btn").style.display = autoResizeOn ? "none" : "inline-block"; }); document.getElementById("manual-btn").addEventListener("click", () => { flickA.resize(); flickB.resize(); });
import Flicking from "@egjs/react-flicking"; import { useCallback, useRef, useState } from "react"; import "@egjs/react-flicking/dist/flicking.css"; import "./styles.css"; function FlickingDemo({ label, hint, width, useResizeObserver, autoResize }) { const ref = useRef(null); const [count, setCount] = useState(0); const onAfterResize = useCallback(() => { setCount(c => c + 1); }, []); return ( <div className="demo-section"> <div className="demo-label">{label}</div> <div style={{ width }}> <Flicking ref={ref} key={`${autoResize}-${useResizeObserver}`} autoResize={autoResize} useResizeObserver={useResizeObserver} onAfterResize={onAfterResize} > <div className="flicking-panel panel-1">1</div> <div className="flicking-panel panel-2">2</div> <div className="flicking-panel panel-3">3</div> <div className="flicking-panel panel-4">4</div> <div className="flicking-panel panel-5">5</div> </Flicking> </div> <div className="resize-count">Resize count: {count}</div> <div className="resize-count" style={{ color: "#aaa" }}> {hint} </div> {!autoResize && ( <button className="button" style={{ marginTop: 6 }} onClick={() => ref.current?.resize()}> Manual resize() </button> )} </div> ); } export default function App() { const [width, setWidth] = useState(100); const [autoResize, setAutoResize] = useState(true); return ( <div> <div className="slider-row"> <span>Container width</span> <input type="range" min={30} max={100} value={width} onChange={e => setWidth(Number(e.target.value))} /> <span className="value-label">{width}%</span> </div> <FlickingDemo label="useResizeObserver: true" hint="Responds immediately when width is changed via slider" width={`${width}%`} useResizeObserver={true} autoResize={autoResize} /> <FlickingDemo label="useResizeObserver: false" hint="Does not detect element size changes (only detects window resize)" width={`${width}%`} useResizeObserver={false} autoResize={autoResize} /> <div className="toggle-row"> <button className={`button ${autoResize ? "active" : ""}`} onClick={() => setAutoResize(v => !v)}> autoResize: {autoResize ? "true" : "false"} </button> <span style={{ fontSize: 13, color: "#888" }}> {autoResize ? "Auto resize enabled" : "Auto resize disabled — use the Manual resize() button"} </span> </div> </div> ); }
<template> <div> <div class="slider-row"> <span>Container width</span> <input type="range" :min="30" :max="100" v-model.number="width" /> <span class="value-label">{{ width }}%</span> </div> <div class="demo-section"> <div class="demo-label">useResizeObserver: true</div> <div :style="{ width: width + '%' }"> <Flicking :key="'a-' + autoResize" :options="{ autoResize, useResizeObserver: true }" @afterResize="countA++" > <div class="flicking-panel panel-1">1</div> <div class="flicking-panel panel-2">2</div> <div class="flicking-panel panel-3">3</div> <div class="flicking-panel panel-4">4</div> <div class="flicking-panel panel-5">5</div> </Flicking> </div> <div class="resize-count">Resize count: {{ countA }}</div> <div class="resize-count" style="color: #aaa">Responds immediately when width is changed via slider</div> </div> <div class="demo-section"> <div class="demo-label">useResizeObserver: false</div> <div :style="{ width: width + '%' }"> <Flicking ref="flickB" :key="'b-' + autoResize" :options="{ autoResize, useResizeObserver: false }" @afterResize="countB++" > <div class="flicking-panel panel-1">1</div> <div class="flicking-panel panel-2">2</div> <div class="flicking-panel panel-3">3</div> <div class="flicking-panel panel-4">4</div> <div class="flicking-panel panel-5">5</div> </Flicking> </div> <div class="resize-count">Resize count: {{ countB }}</div> <div class="resize-count" style="color: #aaa">Does not detect element size changes (only detects window resize)</div> <button v-if="!autoResize" class="button" style="margin-top: 6px" @click="flickB?.resize()"> Manual resize() </button> </div> <div class="toggle-row"> <button :class="['button', autoResize && 'active']" @click="autoResize = !autoResize; countA = 0; countB = 0"> autoResize: {{ autoResize }} </button> <span style="font-size: 13px; color: #888"> {{ autoResize ? 'Auto resize enabled' : 'Auto resize disabled — use the Manual resize() button' }} </span> </div> </div> </template> <script setup> import Flicking from "@egjs/vue3-flicking"; import { ref } from "vue"; import "@egjs/vue3-flicking/dist/flicking.css"; const flickB = ref(null); const width = ref(100); const autoResize = ref(true); const countA = ref(0); const countB = ref(0); </script> <style> .flicking-viewport.vertical { display: block; width: 100%; } .flicking-panel { width: 200px; height: 150px; margin-right: 10px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: bold; color: white; } .panel-1 { background: #3e8ed0; } .panel-2 { background: #00d1b2; } .panel-3 { background: #f14668; } .panel-4 { background: #ffe08a; color: #333; } .panel-5 { background: #48c78e; } .demo-container { margin-bottom: 24px; } .demo-label { font-weight: bold; margin-bottom: 8px; color: #666; } .button { padding: 8px 16px; margin: 4px; border: 2px solid #3498db; background: transparent; color: #3498db; border-radius: 4px; cursor: pointer; font-size: 14px; } .button:hover { background: #3498db; color: white; } .controls { display: flex; justify-content: center; margin-top: 16px; gap: 8px; } .slider-row { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; } .slider-row input[type="range"] { flex: 1; } .slider-row .value-label { font-size: 13px; color: #666; min-width: 50px; text-align: right; } .demo-section { margin-bottom: 20px; } .demo-section .demo-label { font-weight: bold; margin-bottom: 6px; font-size: 14px; } .resize-count { font-size: 13px; color: #888; margin-top: 4px; } .toggle-row { display: flex; align-items: center; gap: 12px; margin-top: 12px; } .toggle-row .button { font-size: 13px; padding: 6px 12px; } .toggle-row .button.active { background: #3498db; color: white; } </style>
요약
주요 옵션
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
autoResize | boolean | true | 뷰포트 크기 변경 시 자동 resize() 호출 |
useResizeObserver | boolean | true | ResizeObserver 사용 여부 (false면 window resize) |
옵션 조합 비교
| 조합 | 동작 | 적합한 상황 |
|---|---|---|
autoResize: true + useResizeObserver: true | 요소 크기 변경 즉시 감지 | 일반적인 사용 (기본값) |
autoResize: true + useResizeObserver: false | window resize만 감지 | 요소 크기는 고정, 창 크기만 변하는 경우 |
autoResize: false | 수동 resize() 호출 필요 | 크기 변경 시점을 직접 제어하고 싶을 때 |
상세 설명
autoResize
autoResize: true(기본값)이면 뷰포트 크기가 변경될 때 자동으로 resize() 메소드를 호출합니다. false로 설정하면 개발자가 직접 flicking.resize()를 호출해야 합니다.
useResizeObserver
useResizeObserver: true(기본값)이면 ResizeObserver API로 요소 단위 크기 변경을 감지합니다. false이면 window의 resize 이벤트만 감지하므로, 부모 요소 크기가 변해도 감지하지 못할 수 있습니다.
사용 시나리오
언제 사용하나요?
- 반응형 레이아웃: 기본값 그대로 사용 (autoResize + ResizeObserver)
- 탭 전환 UI:
autoResize: false로 탭이 활성화될 때만 수동 resize - 성능 민감 환경:
useResizeObserver: false로 window resize만 감지
주의사항
주의
autoResize: false로 설정한 경우, 뷰포트 크기 변경 후 반드시resize()를 호출해야 합니다useResizeObserver: false이면 CSS 레이아웃 변경(flex, grid 등)에 의한 크기 변경을 감지하지 못합니다
관련 링크
관련 옵션
autoResize: 자동 리사이즈useResizeObserver: ResizeObserver 사용
관련 데모
- Resize Debounce: 리사이즈 호출 빈도 제어
- Optimize Size Update: 불필요한 축 변경 무시
- Observe Panel Resize: 패널 크기 변경 감지