728x90
300x250
SMALL
지난 글에서 모바일까지 지원하는 터치 드래그 이벤트를 알아봤습니다. 이번에는 실제로 많이 쓰이는 모바일 바텀 시트 형식의 모달을 드래그로 조절하는 예제를 만들어보겠습니다.
카카오톡 이모티콘 창, 네이버의 검색창 모달 등에서 자주 보는 UI입니다.
기본 개념 : 바텀시트란?
바텀 시트(Bottom Sheet)는 화면 아래에서 위로 슬라이드 되는 UI 이다. 사용자가 내용을 보기 위해 스크롤하거나, 드래그하여 펼칠 수 있다.
이 UI는 크게 3단계로 나뉜다.
1. 닫힌 상태(height: 0 또는 hidden)
2. 중간 상태(예: 높이 50%)
3. 완전히 펼친 상태(예 : 높이 100%)
기본 html 구조
<div class="bottom-sheet">
<div class="drag-handle"></div>
<div class="sheet-content">
<!-- 원하는 콘텐츠 -->
</div>
</div>
- .bottom-sheet : 전체 모달
- .drag-handle : 유저가 드래그할 수 있는 손잡이 역할
- .sheet-content : 모달의 내용 부분
css 예시
.bottom-sheet {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 50%;
background: #fff;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
transition: height 0.3s ease;
overflow: hidden;
}
.drag-handle {
width: 40px;
height: 6px;
background: #ccc;
border-radius: 3px;
margin: 12px auto;
cursor: grab;
}
핵심 JavaScript 로직
const bottomSheet = document.querySelector('.bottom-sheet');
const dragHandle = document.querySelector('.drag-handle');
let startY = 0;
let currentY = 0;
let sheetHeight = 0;
let dragging = false;
function startDrag(y) {
dragging = true;
startY = y;
sheetHeight = bottomSheet.getBoundingClientRect().height;
}
function duringDrag(y) {
if (!dragging) return;
const deltaY = y - startY;
const newHeight = sheetHeight - deltaY;
// 최소/최대값 제한
const maxHeight = window.innerHeight;
const minHeight = 100;
bottomSheet.style.height = `${Math.max(minHeight, Math.min(newHeight, maxHeight))}px`;
}
function endDrag() {
dragging = false;
const currentHeight = bottomSheet.getBoundingClientRect().height;
const windowHeight = window.innerHeight;
// 위치에 따라 상태 결정 (닫힘 / 중간 / 전체)
if (currentHeight < windowHeight * 0.25) {
bottomSheet.style.height = '0px';
} else if (currentHeight < windowHeight * 0.75) {
bottomSheet.style.height = '50%';
} else {
bottomSheet.style.height = '100%';
}
}
// 마우스 이벤트
dragHandle.addEventListener('mousedown', e => startDrag(e.clientY));
window.addEventListener('mousemove', e => duringDrag(e.clientY));
window.addEventListener('mouseup', endDrag);
// 터치 이벤트
dragHandle.addEventListener('touchstart', e => startDrag(e.touches[0].clientY), { passive: true });
window.addEventListener('touchmove', e => duringDrag(e.touches[0].clientY), { passive: true });
window.addEventListener('touchend', endDrag);
동작 시뮬레이션
1. 드래그 시작 시 startY를 기억
2. mousemove 또는 touchmove에서 현재 Y값과의 차이로 높이를 계산
3. 드래그를 마친 뒤, 높이에 따라 바텀 시트 상태를 결정
728x90
반응형
LIST
'javaScript' 카테고리의 다른 글
| 모바일도 완벽하게! touchstart, touchmove 터치 드래그 (0) | 2025.07.02 |
|---|---|
| 드래그 앤 드롭의 시작! mousedown과 mousemove로 배우는 DOM 이벤트 (0) | 2025.06.29 |
| 타입스크립트 컴파일러 설치하기 (0) | 2025.04.03 |
| 타입스크립트 초보자 가이드 - 기초 문법과 컴파일 방법 (0) | 2025.04.02 |
| ES6 모듈 시스템 : import/export를 활용한 최신 개발 방법 (0) | 2025.03.13 |
댓글