5 changed files with 257 additions and 14 deletions
@ -0,0 +1,201 @@
|
||||
import $ from 'jquery'; |
||||
import { useState, useEffect } from 'react'; |
||||
import { useSelector } from 'react-redux'; |
||||
|
||||
export default function ControlDraw(props) { |
||||
const mapControl = useSelector(state => state.controlMapReducer); |
||||
|
||||
const naver = props.naver; |
||||
const map = props.map; |
||||
|
||||
const [circleArr, setCircleArr] = useState([]); |
||||
const [markerArr, setMarkerArr] = useState([]); |
||||
|
||||
const [upCircle, setUpCircle] = useState(false); |
||||
|
||||
useEffect(() => { |
||||
if (upCircle) { |
||||
const delay = 100; |
||||
const timer = setTimeout(() => { |
||||
resumeMapClick(); |
||||
setUpCircle(false); |
||||
|
||||
const index = circleArr.findIndex( |
||||
prev => prev.center === upCircle.getCenter() |
||||
); |
||||
|
||||
markerArr.map((prev, idx) => { |
||||
if (idx === index) { |
||||
const text = fromMetersToText(upCircle.getRadius()); |
||||
const content = |
||||
'<div style="display:inline-block;padding:5px;text-align:center;background-color:#fff;border:1px solid #000;font-size:13px;color:#737373;"><span>' + |
||||
text + |
||||
'</span></div>'; |
||||
prev.setIcon({ |
||||
...prev.getIcon(), |
||||
content: content |
||||
}); |
||||
} |
||||
}); |
||||
}, delay); |
||||
|
||||
return () => { |
||||
clearTimeout(timer); |
||||
}; |
||||
} |
||||
}, [upCircle]); |
||||
|
||||
useEffect(() => { |
||||
naver.maps.Event.addListener(map, 'click', onClickCircle); |
||||
stopMapClick(); |
||||
}, []); |
||||
|
||||
useEffect(() => { |
||||
drawInit(); |
||||
}, [mapControl.ctrlDrawType]); |
||||
|
||||
const drawInit = () => { |
||||
if (mapControl.ctrlDrawType === 'CIRCLE') { |
||||
onClickButton('CIRCLE'); |
||||
} else if (mapControl.ctrlDrawType === 'RESET') { |
||||
clearMode(); |
||||
} |
||||
}; |
||||
|
||||
const onClickButton = newMode => { |
||||
clearMode(); |
||||
startMode(newMode); |
||||
}; |
||||
|
||||
const clearMode = () => { |
||||
if (circleArr.length != 0) { |
||||
circleArr.map(obj => obj.circle.setMap(null)); |
||||
setCircleArr([]); |
||||
|
||||
markerArr.map(marker => marker.setMap(null)); |
||||
setMarkerArr([]); |
||||
|
||||
stopMapClick(); |
||||
} |
||||
}; |
||||
|
||||
const startMode = mode => { |
||||
if (!mode) return; |
||||
|
||||
if (mode === 'CIRCLE') { |
||||
resumeMapClick(); |
||||
} |
||||
}; |
||||
|
||||
const stopMapClick = () => { |
||||
naver.maps.Event.stopDispatch(map, 'click'); |
||||
}; |
||||
|
||||
const resumeMapClick = () => { |
||||
naver.maps.Event.resumeDispatch(map, 'click'); |
||||
}; |
||||
|
||||
const onClickCircle = e => { |
||||
const coord = e.coord; |
||||
|
||||
const circle = new naver.maps.Circle({ |
||||
strokeColor: '#ff0000', |
||||
strokeOpacity: 1, |
||||
fillColor: '#ff0000', |
||||
fillOpacity: 0.3, |
||||
center: coord, |
||||
radius: 100, |
||||
map: map, |
||||
clickable: true |
||||
}); |
||||
setCircleArr(prev => [ |
||||
...prev, |
||||
{ center: coord, circle: circle, radius: 100 } |
||||
]); |
||||
|
||||
naver.maps.Event.addListener(circle, 'mousedown', function () { |
||||
onMouseDown(circle); |
||||
}); |
||||
|
||||
addMileStone(coord, fromMetersToText(100)); |
||||
}; |
||||
|
||||
const onMouseDown = circle => { |
||||
map.setOptions({ |
||||
draggable: false, |
||||
pinchZoom: false, |
||||
scrollWheel: false, |
||||
keyboardShortcuts: false, |
||||
disableDoubleTapZoom: true, |
||||
disableDoubleClickZoom: true, |
||||
disableTwoFingerTapZoom: true |
||||
}); |
||||
|
||||
$(document).on('mousemove.measure', function (e) { |
||||
onMouseMove(e, circle); |
||||
}); |
||||
|
||||
$(document).on('mouseup.measure', function () { |
||||
onMouseUp(circle); |
||||
}); |
||||
}; |
||||
|
||||
const onMouseMove = (e, circle) => { |
||||
const proj = map.getProjection(); |
||||
const coord = proj.fromPageXYToCoord( |
||||
new naver.maps.Point(e.pageX, e.pageY) |
||||
); |
||||
|
||||
const center = circle.getCenter(); |
||||
const r = proj.getDistance(coord, center); |
||||
|
||||
circle.setRadius(r); |
||||
}; |
||||
|
||||
const onMouseUp = circle => { |
||||
map.setOptions({ |
||||
draggable: true, |
||||
pinchZoom: true, |
||||
scrollWheel: true, |
||||
keyboardShortcuts: true, |
||||
disableDoubleTapZoom: false, |
||||
disableDoubleClickZoom: false, |
||||
disableTwoFingerTapZoom: false |
||||
}); |
||||
|
||||
$(document).off('mousemove.measure'); |
||||
$(document).off('mouseup.measure'); |
||||
|
||||
stopMapClick(); |
||||
setUpCircle(circle); |
||||
}; |
||||
|
||||
const addMileStone = (coord, text) => { |
||||
const content = |
||||
'<div style="display:inline-block;padding:5px;text-align:center;background-color:#fff;border:1px solid #000;font-size:13px;color:#737373;"><span>' + |
||||
text + |
||||
'</span></div>'; |
||||
|
||||
const midPoint = coord; |
||||
|
||||
const anchor = new naver.maps.Point(20, 35); |
||||
|
||||
const marker = new naver.maps.Marker({ |
||||
position: midPoint, |
||||
icon: { |
||||
content: content, |
||||
anchor: anchor |
||||
} |
||||
}); |
||||
marker.setMap(map); |
||||
setMarkerArr(prev => [...prev, marker]); |
||||
}; |
||||
|
||||
const fromMetersToText = meters => { |
||||
meters = meters || 0; |
||||
const text = parseFloat(meters.toFixed(1)) + 'm'; |
||||
return text; |
||||
}; |
||||
|
||||
return null; |
||||
} |
Loading…
Reference in new issue