const openSheetButtons = document.querySelectorAll(".open-sheet"); const sheets = document.querySelectorAll(".sheet"); let sheetHeight; let currentSheet = null; const sheetsMap = new Map(); let vh = window.innerHeight / 100; const setSheetHeight = (value) => { if (!currentSheet) return; const sheetContents = currentSheet.querySelector(".contents"); sheetHeight = Math.max(0, Math.min(90, value)); sheetContents.style.height = `${sheetHeight * vh}px`; }; const setIsSheetShown = (isShown) => { if (!currentSheet) return; currentSheet.setAttribute("aria-hidden", String(!isShown)); document.body.style.overflow = isShown ? "hidden" : ""; document.querySelector(".screen-wrap").classList.toggle("is-fixed", isShown); if (!isShown) { currentSheet = null; } }; const throttle = (func, limit) => { let lastFunc; let lastRan; return function (...args) { const context = this; if (!lastRan) { func.apply(context, args); lastRan = Date.now(); } else { clearTimeout(lastFunc); lastFunc = setTimeout(function () { if (Date.now() - lastRan >= limit) { func.apply(context, args); lastRan = Date.now(); } }, limit - (Date.now() - lastRan)); } }; }; const initializeSheet = (sheet, openButtons) => { const sheetContents = sheet.querySelector(".contents"); const draggableArea = sheet.querySelector(".draggable-area"); // 버튼 클릭 시 시트 열기 openButtons.forEach((openButton) => { openButton.addEventListener("click", () => { currentSheet = sheet; setSheetHeight(Math.min(50, (720 / window.innerHeight) * 100)); setIsSheetShown(true); }); }); // 닫기 버튼 클릭 시 시트 닫기 sheet.querySelector(".close-sheet").addEventListener("click", () => { setIsSheetShown(false); }); // 배경 클릭 시 시트 닫기 sheet.querySelector(".overlay").addEventListener("click", () => { setIsSheetShown(false); }); // 드래그 이벤트 const touchPosition = (event) => (event.touches ? event.touches[0] : event); let dragPosition; const onDragStart = (event) => { currentSheet = sheet; dragPosition = touchPosition(event).pageY; sheetContents.classList.add("not-selectable"); draggableArea.style.cursor = document.body.style.cursor = "grabbing"; window.addEventListener("mousemove", onDragMove); window.addEventListener("touchmove", onDragMove, { passive: false }); window.addEventListener("mouseup", onDragEnd); window.addEventListener("touchend", onDragEnd); }; // const onDragMove = (event) => { // if (dragPosition === undefined || !currentSheet) return; // event.preventDefault(); // const y = touchPosition(event).pageY; // const deltaY = dragPosition - y; // const deltaHeight = (deltaY / window.innerHeight) * 100; // setSheetHeight(sheetHeight + deltaHeight); // dragPosition = y; // }; const onDragMove = throttle((event) => { if (dragPosition === undefined || !currentSheet) return; event.preventDefault(); const y = touchPosition(event).pageY; const deltaY = dragPosition - y; const deltaHeight = (deltaY / window.innerHeight) * 100; setSheetHeight(sheetHeight + deltaHeight); dragPosition = y; }, 25); const onDragEnd = () => { dragPosition = undefined; if (currentSheet) { const sheetContents = currentSheet.querySelector(".contents"); sheetContents.classList.remove("not-selectable"); draggableArea.style.cursor = document.body.style.cursor = ""; if (sheetHeight < 45) { setIsSheetShown(false); return; } else if ( sheetHeight > 55 && sheetHeight < 85 && !sheetContents.classList.contains("fullscreen") ) { setSheetHeight(90); sheetContents.classList.add("fullscreen"); return; } else if (sheetHeight < 85 && sheetContents.classList.contains("fullscreen")) { setSheetHeight(50); sheetContents.classList.remove("fullscreen"); return; } else if (sheetHeight === 90) { return; } else if (sheetHeight > 85) { setSheetHeight(90); sheetContents.classList.add("fullscreen"); return; } else if (sheetHeight < 85) { setSheetHeight(50); sheetContents.classList.remove("fullscreen"); } } window.removeEventListener("mousemove", onDragMove); window.removeEventListener("touchmove", onDragMove); window.removeEventListener("mouseup", onDragEnd); window.removeEventListener("touchend", onDragEnd); }; draggableArea.addEventListener("mousedown", onDragStart); draggableArea.addEventListener("touchstart", onDragStart, { passive: false }); }; // 버튼의 data-sheet-target와 일치하는 시트를 찾아서 sheetsMap에 추가 openSheetButtons.forEach((button) => { const sheetId = button.dataset.sheetTarget; const sheet = document.getElementById(sheetId); if (sheet) { if (!sheetsMap.has(sheet)) { sheetsMap.set(sheet, []); } sheetsMap.get(sheet).push(button); } }); // 각 시트를 초기화 sheetsMap.forEach((buttons, sheet) => { initializeSheet(sheet, buttons); }); // esc 키로 바텀시트 닫기 window.addEventListener("keyup", (event) => { if (currentSheet && document.activeElement !== currentSheet) { const isSheetElementFocused = currentSheet.contains(event.target) && document.activeElement === event.target; if (event.key === "Escape" && !isSheetElementFocused) { setIsSheetShown(false); } } });