From fe300a4c9bc0a97c2fa26c31256bbf09ccd6425d Mon Sep 17 00:00:00 2001 From: YiQianYao <42212176+2912401452@users.noreply.github.com> Date: Mon, 28 Mar 2022 15:59:02 +0800 Subject: [PATCH] Shihui (#1020) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 图层支持配置 cursor * style: lint style --- .../services/interaction/PickingService.ts | 22 +++- .../core/src/services/layer/ILayerService.ts | 2 + stories/Object/components/cursor.tsx | 119 ++++++++++++++++++ stories/Object/components/plane.tsx | 28 +++-- stories/Object/map.stories.tsx | 4 +- 5 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 stories/Object/components/cursor.tsx diff --git a/packages/core/src/services/interaction/PickingService.ts b/packages/core/src/services/interaction/PickingService.ts index 38a302923f..ae949b0dba 100644 --- a/packages/core/src/services/interaction/PickingService.ts +++ b/packages/core/src/services/interaction/PickingService.ts @@ -15,13 +15,16 @@ import { InteractionEvent, } from '../interaction/IInteractionService'; import { ILayer, ILayerService } from '../layer/ILayerService'; -import { ILngLat } from '../map/IMapService'; +import { ILngLat, IMapService } from '../map/IMapService'; import { gl } from '../renderer/gl'; import { IFramebuffer } from '../renderer/IFramebuffer'; import { IRendererService } from '../renderer/IRendererService'; import { IPickingService } from './IPickingService'; @injectable() export default class PickingService implements IPickingService { + @inject(TYPES.IMapService) + private readonly mapService: IMapService; + @inject(TYPES.IRendererService) private rendererService: IRendererService; @@ -149,6 +152,20 @@ export default class PickingService implements IPickingService { return features; } + // 动态设置鼠标光标 + public handleCursor(layer: ILayer, type: string) { + const { cursor = '', cursorEnabled } = layer.getLayerConfig(); + if (cursorEnabled) { + const domContainer = this.mapService.getMarkerContainer(); + const defaultCursor = domContainer?.style.getPropertyValue('cursor'); + if (type === 'unmousemove' && defaultCursor !== '') { + domContainer?.style.setProperty('cursor', ''); + } else if (type === 'mousemove') { + domContainer?.style.setProperty('cursor', cursor); + } + } + } + // 获取容器的大小 - 兼容小程序环境 private getContainerSize(container: HTMLCanvasElement | HTMLElement) { if (!!(container as HTMLCanvasElement).getContext) { @@ -370,6 +387,9 @@ export default class PickingService implements IPickingService { // layer.emit(target.type, target); // 判断是否发生事件冲突 if (isEventCrash(target)) { + // Tip: 允许用户动态设置鼠标光标 + this.handleCursor(layer, target.type); + layer.emit(target.type, target); } } diff --git a/packages/core/src/services/layer/ILayerService.ts b/packages/core/src/services/layer/ILayerService.ts index bd57aef940..5eed6fe470 100644 --- a/packages/core/src/services/layer/ILayerService.ts +++ b/packages/core/src/services/layer/ILayerService.ts @@ -352,6 +352,8 @@ export interface ILayerConfig { // layerType 指定 shape 的类型 layerType?: string | undefined; + cursorEnabled?: boolean; + cursor?: string; forward: boolean; // 正方向 /** diff --git a/stories/Object/components/cursor.tsx b/stories/Object/components/cursor.tsx new file mode 100644 index 0000000000..ac7d9fde08 --- /dev/null +++ b/stories/Object/components/cursor.tsx @@ -0,0 +1,119 @@ +import { GeometryLayer, PointLayer, Scene, IMapService } from '@antv/l7'; +import { GaodeMap, GaodeMapV2, Mapbox } from '@antv/l7-maps'; +import * as React from 'react'; + +export default class Demo extends React.Component { + // @ts-ignore + private scene: Scene; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + const scene = new Scene({ + id: 'map', + map: new GaodeMap({ + // map: new GaodeMapV2({ + // map: new Mapbox({ + pitch: 0, + // style: 'dark', + center: [120, 30], + zoom: 5, + }), + }); + this.scene = scene; + let pointLayer = new PointLayer() + .source([{ lng: 120, lat: 33 }], { + parser: { + type: 'json', + x: 'lng', + y: 'lat', + }, + }) + .shape('circle') + .size(20) + .color('#f00') + .active(true) + .style({ + cursor: 'move', + cursorEnabled: true, + }); + + let layer0 = new GeometryLayer() + .style({ + width: 2, + height: 2, + opacity: 0.8, + widthSegments: 3, + heightSegments: 3, + center: [115, 30], + cursor: + "url('https://gw.alipayobjects.com/zos/bmw-prod/e2421e49-87b0-4b4d-aef7-03f4f93f0b54.ico'),pointer", + cursorEnabled: true, + }) + .active({ + color: '#00f', + mix: 0.5, + }) + .color('#ff0'); + + let layer = new GeometryLayer() + .style({ + width: 2, + height: 2, + opacity: 0.8, + widthSegments: 3, + heightSegments: 3, + center: [120, 30], + cursor: 'pointer', + cursorEnabled: true, + }) + .active({ + color: '#00f', + mix: 0.5, + }) + .color('#ff0'); + + let layer2 = new GeometryLayer() + .style({ + width: 2, + height: 2, + opacity: 0.8, + widthSegments: 3, + heightSegments: 3, + center: [125, 30], + cursor: 'wait', + cursorEnabled: true, + }) + .active({ + color: '#00f', + mix: 0.5, + }) + .color('#ff0'); + + scene.on('loaded', () => { + scene.addLayer(pointLayer); + scene.addLayer(layer0); + scene.addLayer(layer); + scene.addLayer(layer2); + }); + } + + public render() { + return ( + <> +
+ + ); + } +} diff --git a/stories/Object/components/plane.tsx b/stories/Object/components/plane.tsx index 8765d77f04..084faabca3 100644 --- a/stories/Object/components/plane.tsx +++ b/stories/Object/components/plane.tsx @@ -25,13 +25,6 @@ export default class Demo extends React.Component { this.scene = scene; let layer = new GeometryLayer() - .source([{ lng: 120, lat: 30 }], { - parser: { - type: 'json', - x: 'lng', - y: 'lat', - }, - }) .style({ width: 2, height: 2, @@ -39,6 +32,26 @@ export default class Demo extends React.Component { widthSegments: 3, heightSegments: 3, center: [120, 30], + cursor: 'pointer', + cursorEnabled: true, + // mapTexture: 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*FG4fT7h5AYMAAAAAAAAAAAAAARQnAQ' + }) + .active({ + color: '#00f', + mix: 0.5, + }) + .color('#ff0'); + + let layer2 = new GeometryLayer() + .style({ + width: 2, + height: 2, + opacity: 0.8, + widthSegments: 3, + heightSegments: 3, + center: [125, 30], + cursor: 'wait', + cursorEnabled: true, // mapTexture: 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*FG4fT7h5AYMAAAAAAAAAAAAAARQnAQ' }) .active({ @@ -49,6 +62,7 @@ export default class Demo extends React.Component { scene.on('loaded', () => { scene.addLayer(layer); + scene.addLayer(layer2); // setTimeout(() => { // // layer.style({ diff --git a/stories/Object/map.stories.tsx b/stories/Object/map.stories.tsx index e848784777..709f1bea67 100644 --- a/stories/Object/map.stories.tsx +++ b/stories/Object/map.stories.tsx @@ -7,6 +7,7 @@ import Radar from './components/radar'; import CanvasDemo from './components/canvas'; import Plane from './components/plane'; import PlaneTerrain from './components/planeTerrain'; +import Cursor from './components/cursor'; storiesOf('Object', module) .add('water', () => ) @@ -15,4 +16,5 @@ storiesOf('Object', module) .add('Radar', () => ) .add('CanvasDemo', () => ) .add('Plane', () => ) - .add('PlaneTerrain', () => ) \ No newline at end of file + .add('PlaneTerrain', () => ) + .add('Cursor', () => ) \ No newline at end of file