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