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,
};
}
|