sn: zoom level 디자인 및 기능 변경

This commit is contained in:
2026-03-18 18:07:26 +09:00
parent f9a1af43f5
commit 96db2b4ed4
2 changed files with 48 additions and 7 deletions
@@ -1,8 +1,9 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { useGisContext } from './Gis';
export default React.memo(function GisZoomLevel() {
const { gisMap } = useGisContext();
const trackRef = useRef(null);
const [zoomInfo, setZoomInfo] = useState({
zoom: 0,
minZoom: 0,
@@ -39,6 +40,17 @@ export default React.memo(function GisZoomLevel() {
const fillHeight = `${normalized * 100}%`;
const thumbBottom = `calc(${fillHeight} - 1px)`;
const updateZoomFromClientY = clientY => {
if (!gisMap || !trackRef.current) return;
const view = gisMap.getView();
const rect = trackRef.current.getBoundingClientRect();
const offsetY = rect.bottom - clientY;
const nextNormalized = Math.min(Math.max(offsetY / rect.height, 0), 1);
const nextZoom = minZoom + nextNormalized * range;
view.setZoom(nextZoom);
};
const zoomIn = () => {
const view = gisMap.getView();
if (view.getMaxZoom() > view.getZoom()) {
@@ -59,6 +71,23 @@ export default React.memo(function GisZoomLevel() {
}
};
const handleTrackPointerDown = event => {
event.preventDefault();
updateZoomFromClientY(event.clientY);
const handlePointerMove = moveEvent => {
updateZoomFromClientY(moveEvent.clientY);
};
const handlePointerUp = () => {
window.removeEventListener('pointermove', handlePointerMove);
window.removeEventListener('pointerup', handlePointerUp);
};
window.addEventListener('pointermove', handlePointerMove);
window.addEventListener('pointerup', handlePointerUp);
};
return (
<div className="zoom-level-control" title={`현재 줌 레벨 ${zoom.toFixed(1)}`}>
<div className="zoom-level-panel">
@@ -66,7 +95,11 @@ export default React.memo(function GisZoomLevel() {
+
</button>
<div className="zoom-level-gauge">
<div className="zoom-level-track">
<div
ref={trackRef}
className="zoom-level-track"
onPointerDown={handleTrackPointerDown}
>
<div className="zoom-level-fill" style={{ height: fillHeight }} />
<div className="zoom-level-thumb" style={{ bottom: thumbBottom }} />
</div>
@@ -195,7 +195,7 @@
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
height: 30px;
padding: 0;
border: 0;
border-bottom: 1px solid #eeeeee;
@@ -230,7 +230,10 @@
width: 12px;
height: 96px;
border-radius: 6px;
cursor: ns-resize;
touch-action: none;
background:
linear-gradient(to top, #b8b8b8, #b8b8b8) center / 4px 100% no-repeat,
repeating-linear-gradient(
to top,
transparent 0,
@@ -243,20 +246,25 @@
.zoom-level-fill {
position: absolute;
left: 5px;
left: 50%;
bottom: 0;
width: 2px;
width: 4px;
background: #3b82f6;
border-radius: 999px;
transform: translateX(-50%);
}
.zoom-level-thumb {
position: absolute;
left: 50%;
width: 22px;
height: 2px;
background: #111;
height: 5px;
border: 0.5px solid #111;
border-radius: 2px;
background: #fff;
transform: translateX(-50%);
box-sizing: border-box;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}
.ol-scale-line {