Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import { useState, useMemo, useEffect } from 'react'; import { createPortal } from 'react-dom'; import { useMapContext } from '@uiw/react-baidu-map-map'; import { useProperties, usePrevious } from '@uiw/react-baidu-map-utils'; import { CustomOverlayProps } from './'; function getCustomOverlay() { return class extends BMap.Overlay { public container: HTMLDivElement; public map!: BMap.Map; public paneName: keyof BMap.MapPanes; public position?: BMap.Point; public offset?: BMap.Size; constructor(elm: HTMLDivElement, position?: BMap.Point, paneName?: CustomOverlayProps['paneName']) { super(); this.container = elm; this.paneName = paneName || 'markerPane'; this.position = position; } public initialize: (map: BMap.Map) => HTMLElement = (map) => { const panes = map.getPanes(); this.container.style.position = 'absolute'; this.map = map; panes[this.paneName]!.appendChild(this.container); return this.container; }; public draw = () => { if (this.position == null || this.map == null) { return; } const position = this.map.pointToOverlayPixel(this.position); const { width = 0, height = 0 } = this.offset || {}; this.container.style.left = `${position.x + width}px`; this.container.style.top = `${position.y + height}px`; }; public setOffset = (offset: BMap.Size) => { this.offset = offset; this.draw(); }; public setPosition = (position: BMap.Point) => { this.position = position; this.draw(); }; public setVisiable = (visiable: boolean) => { this.container.style.display = visiable ? 'block' : 'none'; }; public getPosition = () => { return this.position; }; public setZIndex = (index: number) => { this.container.style.zIndex = index.toString(); }; }; } export interface UseCustomOverlay extends CustomOverlayProps {} export function useCustomOverlay(props = {} as UseCustomOverlay) { const { children, paneName, position } = props; const { map } = useMapContext(); const [customOverlay, setCustomOverlay] = useState<BMap.Overlay>(); const [div, setDiv] = useState<HTMLDivElement>(); const [portal, setPortal] = useState<React.ReactPortal>(); const [count, setCount] = useState(0); useEffect(() => { return () => { if (map && customOverlay) { map.removeOverlay(customOverlay); } }; }, [customOverlay, map]); useMemo(() => { Iif (map && !portal && document) { const elm = document.createElement('div'); const CustomOverlay = getCustomOverlay(); const portalInstance = createPortal(children, elm); const CompOverlay = new CustomOverlay(elm, position, paneName); setCount(count + 1); setDiv(elm); map.addOverlay(CompOverlay); setPortal(portalInstance); setCustomOverlay(CompOverlay); } }, [children, count, map, paneName, portal, position]); const prevCount = usePrevious(count); useMemo(() => { Iif (map && div && children && count === prevCount) { const portalInstance = createPortal(children, div); setPortal(portalInstance); setCount(count + 1); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [children, customOverlay]); useProperties<BMap.Overlay, UseCustomOverlay>(customOverlay!, props, ['ZIndex', 'Offset', 'Position', 'Visiable']); return { portal, setPortal, customOverlay, setCustomOverlay, }; } |