UNPKG

react-kakao-maps-sdk

Version:
135 lines (132 loc) 3.98 kB
import React, { useMemo, useImperativeHandle, useLayoutEffect } from 'react'; import { useMap } from '../hooks/useMap.js'; /** * `API` 사용자가 직접 정의할 수 있는 오버레이. * AbstractOverlay를 상속 받아 사용할 객체를 생성하고 prototype을 연결해 준다. * 온전히 동작하는 오버레이를 만들고자 한다면 3가지 인터페이스 메소드( onAdd, draw, onRemove )를 구현해야 한다. * * 해당 Component 내부에서 `ReactAbstractOveraly` class를 만들어 `onAdd`, `draw`, `onRemove` 를 연결한 후 React Life Cycle에 맞춰 `setMap` 를 자동으로 호출 합니다. * * *경고* `draw`, `onAdd`, `onRemove` 의 경우 반드시 익명함수가 **아닌** 형태로 만들어서 전달해야 합니다. * `this.~` 를 통한 접근이 가능하니 해당 부분을 이용해서 구현 해주세요! * * ### Example Code * * ```jsx live * function () { * const TooltipMarker = ({ * position, * }) => { * const node = useRef(document.createElement("div")) * * const positionLatlng = useMemo(() => { * return new kakao.maps.LatLng(position.lat, position.lng) * }, [position.lat, position.lng]) * * function onAdd() { * const panel = this.getPanels() * .overlayLayer * panel.appendChild(node.current) * } * * function onRemove() { * node.current.parentNode.removeChild(node.current) * } * * function draw() { * var projection = this.getProjection() * var point = projection.pointFromCoords(positionLatlng) * var width = node.current.offsetWidth * var height = node.current.offsetHeight * * console.log(point, width, height) * * node.current.style.left = point.x - width / 2 + "px" * node.current.style.top = point.y - height / 2 + "px" * } * * useEffect(() => { * node.current.style.position = "absolute" * node.current.style.whiteSpace = "nowrap" * }, []) * * return ( * <> * <AbstractOverlay onAdd={onAdd} onRemove={onRemove} draw={draw} /> * {ReactDOM.createPortal( * <div * style={{ * color: "#000", * backgroundColor: "#fff", * padding: "5px", * borderRadius: "15px", * }} * > * Hello Marker! * </div>, * node.current * )} * </> * ) * } * * return ( * <> * <Map // 지도를 표시할 Container * center={{ * // 지도의 중심좌표 * lat: 37.54699, * lng: 127.09598, * }} * style={{ * // 지도의 크기 * width: "100%", * height: "450px", * }} * level={3} // 지도의 확대 레벨 * > * <TooltipMarker * position={{ * lat: 37.54699, * lng: 127.09598, * }} * /> * </Map> * </> * ) *} * ``` */ const AbstractOverlay = /*#__PURE__*/React.forwardRef(function AbstractOverlay(_ref, ref) { let { draw, onAdd, onRemove, onCreate } = _ref; const map = useMap(); const reactAbstractOverlay = useMemo(() => { class ReactAbstractOveraly extends kakao.maps.AbstractOverlay { constructor(draw, onAdd, onRemove) { super(); this.draw = draw; this.onAdd = onAdd; this.onRemove = onRemove; } } const overlay = new ReactAbstractOveraly(draw, onAdd, onRemove); return overlay; }, [draw, onAdd, onRemove]); useImperativeHandle(ref, () => reactAbstractOverlay, [reactAbstractOverlay]); useLayoutEffect(() => { reactAbstractOverlay.setMap(map); return () => { reactAbstractOverlay.setMap(null); }; }, [map, reactAbstractOverlay]); useLayoutEffect(() => { if (onCreate) onCreate(reactAbstractOverlay); }, [reactAbstractOverlay, onCreate]); return null; }); export { AbstractOverlay };