Skip to content

Commit

Permalink
feat: 新增 Scene 与 Layer 相关的事件属性 (#54)
Browse files Browse the repository at this point in the history
* feat: 容器 LarkMap 组件新增 scene 相关的事件 props

* feat: 1.新增 useLayerEvent 用于更新 L7 原子图层的回调函数  2. useSceneEvent 在组件注销时清空事件

* chore: 更新类型文件

* chore: 调整类型路径

* feat: 复合图层支持事件属性绑定

* fix: 类型引入错误

Co-authored-by: yanxiong <[email protected]>
Co-authored-by: yunji <[email protected]>
  • Loading branch information
3 people authored Sep 13, 2022
1 parent 5ddfd4f commit 1af5cec
Show file tree
Hide file tree
Showing 32 changed files with 396 additions and 60 deletions.
30 changes: 15 additions & 15 deletions docs/common/layer/composite-common/event.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
### 事件监听

- 绑定事件
- 通过组件属性

```js
layer.on(eventName: string, callback: (...args) => void);
```jsx | pure
<layerName onEventName={(...args) => {}} />
```

- 绑定一次事件
- 通过实例绑定

```js
// 绑定事件
layer.on(eventName: string, callback: (...args) => void);
// 绑定一次事件
layer.once(eventName: string, callback: (...args) => void);
```

- 解绑事件

```js
// 解绑事件
layer.off(eventName: string, callback: (...args) => void);
```

Expand All @@ -31,12 +30,13 @@ layer.off(eventName: string, callback: (...args) => void);

#### 点击事件

| 事件名 | 类型 | 描述 |
| ------------- | -------- | ------------------------ |
| click | 左键事件 | 左键点击图层事件 |
| unclick | 左键事件 | 图层外左键点击事件 |
| contextmenu | 右键事件 | 图层要素点击右键菜单事件 |
| uncontextmenu | 右键事件 | 图层外点击右键事件 |
| 事件名 | 类型 | 描述 |
| ------------- | -------- | ------------------ |
| click | 左键事件 | 左键点击图层事件 |
| unclick | 左键事件 | 图层外左键点击事件 |
| dblclick | 双击事件 | 双击图层事件 |
| contextmenu | 右键事件 | 右键点击图层事件 |
| uncontextmenu | 右键事件 | 图层外点击右键事件 |

#### 鼠标事件

Expand Down
30 changes: 15 additions & 15 deletions docs/common/layer/core-common/event.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
### 事件监听

- 绑定事件
- 通过组件属性

```js
layer.on(eventName: string, callback: (...args) => void);
```jsx | pure
<layerName onEventName={(...args) => {}} />
```

- 绑定一次事件
- 通过实例绑定

```js
// 绑定事件
layer.on(eventName: string, callback: (...args) => void);
// 绑定一次事件
layer.once(eventName: string, callback: (...args) => void);
```

- 解绑事件

```js
// 解绑事件
layer.off(eventName: string, callback: (...args) => void);
```

Expand All @@ -31,12 +30,13 @@ layer.off(eventName: string, callback: (...args) => void);

#### 点击事件

| 事件名 | 类型 | 描述 |
| ------------- | -------- | ------------------------ |
| click | 左键事件 | 左键点击图层事件 |
| unclick | 左键事件 | 图层外左键点击事件 |
| contextmenu | 右键事件 | 图层要素点击右键菜单事件 |
| uncontextmenu | 右键事件 | 图层外点击右键事件 |
| 事件名 | 类型 | 描述 |
| ------------- | -------- | ------------------ |
| click | 左键事件 | 左键点击图层事件 |
| unclick | 左键事件 | 图层外左键点击事件 |
| dblclick | 双击事件 | 双击图层事件 |
| contextmenu | 右键事件 | 右键点击图层事件 |
| uncontextmenu | 右键事件 | 图层外点击右键事件 |

#### 鼠标事件

Expand Down
2 changes: 1 addition & 1 deletion docs/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ import { LarkMap } from '@antv/larkmap';
import React from 'react';

const config = {
mapType: 'Mapbox',
mapType: 'GaodeV1',
mapOptions: {
style: 'light',
center: [120.210792, 30.246026],
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
},
"dependencies": {
"@antv/event-emitter": "^0.1.3",
"@antv/l7-composite-layers": "^0.5.0",
"@antv/l7-composite-layers": "^0.5.1",
"@antv/l7-draw": "^3.0.6",
"@formily/antd": "^2.1.11",
"@formily/core": "^2.1.11",
Expand Down
2 changes: 1 addition & 1 deletion src/components/LarkMap/hooks/use-layer/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react';
import type { Layer } from '../../../../utils';
import type { Layer } from '../../../../types';
import { useLayerManager } from '../use-layer-manager';

export const useLayer = <T extends Layer = Layer>(id: string): T | undefined => {
Expand Down
38 changes: 38 additions & 0 deletions src/components/LarkMap/hooks/use-scene-event/constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { SceneEventProps } from '../../types';

/**
* 从 LarkMap 的事件名到 Scene 事件名的映射
*/
export const SceneEventMap: Record<keyof SceneEventProps, string> = {
onLoaded: 'loaded',
onDestroy: 'destroy',

onResize: 'resize',

onMapMove: 'mapmove',
onMoveStart: 'movestart',
onMoveEnd: 'moveend',
onZoomChange: 'zoomchange',
onZoomStart: 'zoomstart',
onZoomEnd: 'zoomend',

onClick: 'click',
onDblclick: 'dblclick',
onContextMenu: 'contextmenu',

onMouseMove: 'mousemove',
onMousewheel: 'mousewheel',
onMousedown: 'mousedown',
onMouseOver: 'mouseover',
onMouseOut: 'mouseout',
onMouseUp: 'mouseup',

onDragStart: 'dragstart',
onDragging: 'dragging',
onDragEnd: 'dragend',
};

/**
* LarkMap 事件名列表
*/
export const SceneEventList = Object.keys(SceneEventMap);
48 changes: 48 additions & 0 deletions src/components/LarkMap/hooks/use-scene-event/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { Scene } from '@antv/l7';
import { useTrackedEffect, useUnmount } from 'ahooks';
import type { SceneEventProps, SceneEventCallback } from '../../types';
import { SceneEventList, SceneEventMap } from './constant';

export const useSceneEvent = (scene: Scene, props: SceneEventProps) => {
useTrackedEffect(
(changeIndexList: number[], previousDeps: SceneEventCallback[] = [], currentDeps: SceneEventCallback[] = []) => {
if (!scene) {
return;
}
// 需要更新的事件对应到 deps 的数组下标,但是不包含 scene 实例的更新
let indexList = changeIndexList.filter((index) => index);

// 如果本次变化为 scene 的实例化则无差别遍历所有事件类型
if (changeIndexList.includes(0)) {
indexList = SceneEventList.map((_, index) => index + 1);
}

indexList.forEach((index) => {
const eventName = SceneEventMap[SceneEventList[index]] as string;
const previousCallback = previousDeps[index];
const currentCallback = currentDeps[index];
// 分别注销旧的事件回调并绑定新的事件
if (previousCallback) {
scene.off(eventName, previousCallback);
}
if (currentCallback) {
scene.on(eventName, currentCallback);
}
});
},
[scene, ...SceneEventList.map((eventName) => props[eventName])],
);

useUnmount(() => {
if (!scene) {
return;
}
SceneEventList.forEach((key) => {
const eventName = SceneEventMap[key];
const callback = props[key];
if (eventName && callback) {
scene.off(eventName, callback);
}
});
});
};
64 changes: 64 additions & 0 deletions src/components/LarkMap/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,70 @@ LarkMap 是地图容器组件,相关地图组件与 Hooks 需放到容器组
| getScene | 获取 Scene 实例 | `() => Scene` | -- |
| getMap | 获取 Map 实例 | `() => MapInstance` | -- |

## Event

### 事件监听

- 通过组件属性

```jsx | pure
<LarkMap onEventName={(...args) => {}} />
```

- 通过实例绑定

```js
// 绑定事件
scene.on(eventName: string, callback: (...args) => void);
// 绑定一次事件
scene.once(eventName: string, callback: (...args) => void);
// 解绑事件
scene.off(eventName: string, callback: (...args) => void);
```

### 事件类别

#### 生命周期事件

| 事件名 | 类型 | 描述 |
| ------- | ------------ | ------------ |
| loaded | 生命周期事件 | 加载完成事件 |
| destroy | 生命周期事件 | 销毁事件 |

#### 地图容器事件

| 事件名 | 类型 | 描述 |
| ---------- | -------- | -------------------------------------------------------------------------------------------- |
| resize | 容器事件 | 地图容器大小改变事件 |
| mapmove | 地图事件 | 地图平移时触发事件 |
| movestart | 地图事件 | 地图平移开始时触发事件 |
| moveend | 地图事件 | 地图移动结束后触发,包括平移,以及中心点变化的缩放。如地图有拖拽缓动效果,则在缓动结束后触发 |
| zoomchange | 地图事件 | 地图缩放级别更改后触发 |
| zoomstart | 地图事件 | 缩放开始时触发 |
| zoomend | 地图事件 | 缩放停止时触发 |

#### 点击事件

| 事件名 | 类型 | 描述 |
| ----------- | -------- | ------------ |
| click | 左键事件 | 点击事件 |
| dblclick | 双击事件 | 双击事件 |
| contextmenu | 右键事件 | 右键点击事件 |

#### 鼠标事件

| 事件名 | 类型 | 描述 |
| ---------- | -------- | -------------------------------------------------------------------- |
| mousemove | 鼠标事件 | 鼠标在地图上移动时触发 |
| mousewheel | 鼠标事件 | 鼠标滚轮开始缩放地图时触发 |
| mouseover | 鼠标事件 | 鼠标移入地图容器内时触发 |
| mouseout | 鼠标事件 | 鼠标移出地图容器时触发 |
| mouseup | 鼠标事件 | 鼠标在地图上单击抬起时触发 |
| mousedown | 鼠标事件 | 鼠标在地图上单击按下时触发 |
| dragstart | 滑动事件 | 开始拖拽地图时触发 |
| dragging | 滑动事件 | 拖拽地图过程中触发 |
| dragend | 滑动事件 | 停止拖拽地图时触发,如地图有拖拽缓动效果,则在拽停止,缓动开始前触发 |

## FAQ

### 1. 如何禁止地图的交互状态?
Expand Down
3 changes: 3 additions & 0 deletions src/components/LarkMap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import React, { memo, forwardRef, useEffect, useImperativeHandle, useMemo, useRe
import { LayerManager } from '../../utils';
import { createMap } from './helper';
import type { LarkMapContextValue, LarkMapProps, LarkMapRefAttributes } from './types';
import { useSceneEvent } from './hooks/use-scene-event';

export const LarkMapContext = React.createContext<LarkMapContextValue>(null);

Expand Down Expand Up @@ -74,6 +75,8 @@ export const LarkMap = memo(
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useSceneEvent(sceneInstance, props);

useImperativeHandle(ref, () => ({ getScene: () => sceneInstance, getMap: () => sceneInstance.map }), [
sceneInstance,
]);
Expand Down
38 changes: 37 additions & 1 deletion src/components/LarkMap/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,46 @@ export type LarkMapRefAttributes = {
getMap: () => Scene['map'];
};

/**
* 场景事件回调
*/
export type SceneEventCallback = (e?: any) => void;

/**
* 场景事件
*/
export type SceneEventProps = Partial<{
// 生命周期事件
onLoaded: SceneEventCallback;
onDestroy: SceneEventCallback;
// 地图容器事件
onResize: SceneEventCallback;
onMapMove: SceneEventCallback;
onMoveStart: SceneEventCallback;
onMoveEnd: SceneEventCallback;
onZoomChange: SceneEventCallback;
onZoomStart: SceneEventCallback;
onZoomEnd: SceneEventCallback;
// 点击事件
onClick: SceneEventCallback;
onDblclick: SceneEventCallback;
onContextMenu: SceneEventCallback;
// 鼠标事件
onMouseMove: SceneEventCallback;
onMousewheel: SceneEventCallback;
onMousedown: SceneEventCallback;
onMouseOver: SceneEventCallback;
onMouseOut: SceneEventCallback;
onMouseUp: SceneEventCallback;
onDragStart: SceneEventCallback;
onDragging: SceneEventCallback;
onDragEnd: SceneEventCallback;
}>;

/**
* 组件类型定义
*/
export interface LarkMapProps extends CommonProps, Omit<ISceneConfig, 'id' | 'canvas' | 'map'> {
export interface LarkMapProps extends CommonProps, Omit<ISceneConfig, 'id' | 'canvas' | 'map'>, SceneEventProps {
/** 容器 id */
id?: string;
/** 地图实例,可选,也可以通过配置项自动生成实例 */
Expand Down
3 changes: 2 additions & 1 deletion src/components/Layers/BaseLayers/HeatmapLayer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { HeatmapLayer as L7HeatmapLayer } from '@antv/l7-composite-layers';
import { forwardRef, memo, useImperativeHandle } from 'react';
import { useCreateLayer } from '../../hooks/use-create-layer';
import { useCreateLayer, useLayerEvent } from '../../hooks';
import type { HeatmapLayerProps } from './types';

export const HeatmapLayer = memo(
forwardRef<L7HeatmapLayer, HeatmapLayerProps>(function HeatmapLayer(props, ref) {
const layerRef = useCreateLayer<L7HeatmapLayer, HeatmapLayerProps>(L7HeatmapLayer, props);

useLayerEvent(layerRef.current, props);
useImperativeHandle(ref, () => layerRef.current);

return null;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Layers/BaseLayers/HeatmapLayer/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { HeatmapLayer, HeatmapLayerOptions } from '@antv/l7-composite-layers';
import type { LayerCommonProps } from '../../../../types/common';
import type { LayerCommonProps } from '../../../../types';

/**
* 组件类型定义
Expand Down
3 changes: 2 additions & 1 deletion src/components/Layers/BaseLayers/LineLayer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { LineLayer as L7LineLayer } from '@antv/l7-composite-layers';
import { forwardRef, memo, useImperativeHandle } from 'react';
import { useCreateLayer } from '../../hooks/use-create-layer';
import { useCreateLayer, useLayerEvent } from '../../hooks';
import type { LineLayerProps } from './types';

export const LineLayer = memo(
forwardRef<L7LineLayer, LineLayerProps>(function LineLayer(props, ref) {
const layerRef = useCreateLayer<L7LineLayer, LineLayerProps>(L7LineLayer, props);

useLayerEvent(layerRef.current, props);
useImperativeHandle(ref, () => layerRef.current);

return null;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Layers/BaseLayers/LineLayer/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { LineLayer, LineLayerOptions } from '@antv/l7-composite-layers';
import type { LayerCommonProps } from '../../../../types/common';
import type { LayerCommonProps } from '../../../../types';

/**
* 组件类型定义
Expand Down
Loading

0 comments on commit 1af5cec

Please sign in to comment.