import React, { useEffect, useState, forwardRef, useRef, useImperativeHandle } from 'react'; import { registerEvents, unRegisterEvents } from '../_utils/help-tools'; import { usePreviousProps } from '../_utils/hooks'; import { applyUpdatersToProps } from '../_utils/help'; import { useMap } from '../map-context'; import { IPoint, EventParamsBase } from '../_utils/point'; export interface ICircleProps { center: IPoint; radius: number; strokeColor?: string; fillColor?: string; strokeOpacity?: number; fillOpacity?: number; strokeWeight?: number; strokeStyle?: string; enableEditing?: boolean; enableMassClear?: boolean; onClick?: (event: Pick) => void; onDblClick?: (event: Pick) => void; onMouseDown?: (event: Pick) => void; onMouseUp?: (event: Pick) => void; onMouseOut?: (event: Pick) => void; onMouseOver?: (event: Pick) => void; onRemove?: (event: Pick) => void; onLineUpdate?: (event: Pick) => void; } const defaultProps: Partial = {}; const updaterMap = { center(instance: BMap.Circle, center: IPoint) { const { lng, lat } = center; const point = new BMap.Point(lng, lat); instance.setCenter(point); }, radius(instance: BMap.Circle, radius: number) { instance.setRadius(radius); }, strokeColor(instance: BMap.Circle, color: string) { instance.setStrokeColor(color); }, fillColor(instance: BMap.Circle, color: string) { instance.setFillColor(color); }, strokeOpacity(instance: BMap.Circle, opacity: number) { instance.setStrokeOpacity(opacity); }, fillOpacity(instance: BMap.Circle, opacity: number) { instance.setFillOpacity(opacity); }, strokeWeight(instance: BMap.Circle, weight: number) { instance.setStrokeWeight(weight); }, strokeStyle(instance: BMap.Circle, style: string) { instance.setStrokeStyle(style); }, enableEditing(instance: BMap.Circle, enable: boolean) { if (enable) instance.enableEditing(); else instance.disableEditing(); }, enableMassClear(instance: BMap.Circle, enable: boolean) { if (enable) instance.enableMassClear(); else instance.disableMassClear(); }, }; const eventMap = { onClick: 'click', onDblClick: 'dblclick', onMouseDown: 'mousedown', onMouseUp: 'mouseup', onMouseOut: 'mouseout', onMouseOver: 'mouseover', onRemove: 'remove', onLineUpdate: 'lineupdate', }; const Circle = forwardRef((props: ICircleProps, ref: React.RefObject>) => { const map = useMap() as BMap.Map; const { center = map.getCenter(), radius = 1 } = props; const registeredEventsRef = useRef([]); const [circleInstance, setCircleInstance] = useState(); const prevProps = usePreviousProps(props); useEffect(function initInstance() { const { lng, lat } = center; const point = new BMap.Point(lng, lat); const circle = new BMap.Circle(point, radius); map.addOverlay(circle); applyUpdatersToProps(updaterMap, {}, props, circle, map); setCircleInstance(circle); }, []); useEffect(function updatersToProps() { if (circleInstance) { applyUpdatersToProps(updaterMap, prevProps, props, circleInstance, map); } }); useEffect(function setEvents() { if (circleInstance) { registeredEventsRef.current = registerEvents(circleInstance, props, eventMap); return function clean() { registeredEventsRef.current.length > 0 && unRegisterEvents(circleInstance, registeredEventsRef.current); }; } return; }); useImperativeHandle( ref, () => ({ instance: circleInstance, }), [circleInstance], ); return null; }); Circle.defaultProps = defaultProps; export default Circle;