Skip to content

Commit

Permalink
feat(marker): 标记点基本实现
Browse files Browse the repository at this point in the history
  • Loading branch information
wangxingkang committed Aug 31, 2022
1 parent 5f80172 commit 0936357
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './map';
export * from './marker';
export * from './hooks/useMap';
11 changes: 9 additions & 2 deletions src/map/demos/basic.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState } from 'react';
import { Map } from '@pansy/react-mapbox-gl';
import { Map, Marker } from '@pansy/react-mapbox-gl';

export default () => {
const [enable, setEnable] = useState(true);
Expand All @@ -22,7 +22,14 @@ export default () => {
测试
</button>
<Map onClick={enable ? handleClick1 : handleClick2}>
<span style={{ zIndex: 100 }}>{123}</span>
<Marker
lngLat={[30.5, 50.5]}
// render={() => {
// return <div style={{ background: 'red' }}>123</div>
// }}
>
<div style={{ background: 'red' }}>123</div>
</Marker>
</Map>
</div>
);
Expand Down
37 changes: 37 additions & 0 deletions src/marker/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Marker } from 'mapbox-gl';

import type { LngLatLike } from 'mapbox-gl';

import type { EventMapping, PropKey } from './types';

export const mapEventMap: EventMapping = {
onDragStart: 'dragstart',
onDrag: 'drag',
onDragEnd: 'dragend',
};

/** 静态属性 */
export const StaticProps: PropKey[] = ['anchor', 'clickTolerance', 'color'];

/** 动态属性 */
export const NativeDynamicProps: PropKey[] = [
'draggable',
'offset',
'rotation',
'rotationAlignment',
'pitchAlignment',
'scale',
'lngLat',
];

export const allProps = NativeDynamicProps.concat(StaticProps);

export const setterMap = {
lngLat(value: LngLatLike, marker: Marker) {
if (!marker) return;

marker.setLngLat(value);
},
};

export const converterMap = {};
2 changes: 2 additions & 0 deletions src/marker/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { Marker } from './marker';
export type { MarkerProps } from './types';
69 changes: 69 additions & 0 deletions src/marker/marker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Marker as MapboxMarker } from 'mapbox-gl';
import { createPortal } from 'react-dom';
import { useGetState } from '@pansy/react-hooks';
import { forwardRef, useEffect, useRef, useImperativeHandle } from 'react';

import { useMap } from '@/hooks/useMap';
import { useReact } from '@/hooks/useReact';

import { allProps, setterMap, converterMap, mapEventMap } from './config';

import type { MarkerProps, EventMapping } from './types';
import type { MarkerOptions } from 'mapbox-gl';

export const Marker = forwardRef<MapboxMarker, MarkerProps>((props, ref) => {
const map = useMap();
const contentWrapper = useRef<HTMLDivElement>();
const [marker, setMarker] = useGetState<MapboxMarker>(null as any);

const { onInstanceCreated } = useReact<MarkerProps, MapboxMarker, EventMapping>(props, {
ins: marker,
events: mapEventMap,
setterMap,
converterMap,
});

useImperativeHandle(ref, () => marker as MapboxMarker, [marker]);

useEffect(() => {
if (map) {
createInstance().then((marker) => {
setMarker(marker);

marker.setLngLat(props.lngLat);
marker.addTo(map);
onInstanceCreated();
});
}
}, [map]);

const createInstance = () => {
const options = getCreateOptions();

contentWrapper.current = document.createElement('div');

const marker = new MapboxMarker(contentWrapper.current, options);

marker.setLngLat(props.lngLat);

marker.addTo(map);

return Promise.resolve(marker);
};

/** 获取创建参数 */
const getCreateOptions = () => {
const options: MarkerOptions = {};

allProps.forEach((key) => {
if (key in props) {
// @ts-ignore
options[key] = props[key];
}
});

return options;
};

return marker && createPortal(props.children, marker.getElement());
});
19 changes: 19 additions & 0 deletions src/marker/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { MarkerOptions, LngLatLike, MapEventType } from 'mapbox-gl';

export type MarkerEvents = {
onDragStart: (e: MapEventType['dragstart']) => void;
onDrag: (e: MapEventType['drag']) => void;
onDragEnd: (e: MapEventType['dragend']) => void;
};

export type EventMapping = { [T in keyof MarkerEvents]: string };

export type KeysOfUnion<T> = T extends T ? keyof T : never;

export interface MarkerProps extends MarkerOptions, Partial<MarkerEvents> {
className?: string;
lngLat: LngLatLike;
children: any;
}

export type PropKey = KeysOfUnion<MarkerProps>;

0 comments on commit 0936357

Please sign in to comment.