From 15766231d69cc76437df49aac10966c86186fa8f Mon Sep 17 00:00:00 2001 From: thinkinggis Date: Wed, 18 Dec 2019 00:33:25 +0800 Subject: [PATCH] =?UTF-8?q?feat(layer):=20add=20setSelect=20setActive=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95=20&=20refactor=20color=20=20util?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/component/src/popup.ts | 8 +- .../src/services/component/PopupService.ts | 4 +- .../core/src/services/config/ConfigService.ts | 2 + .../interaction/IInteractionService.ts | 16 ++- .../interaction/InteractionService.ts | 10 +- .../core/src/services/layer/ILayerService.ts | 7 + .../renderer/passes/BaseNormalPass.ts | 8 +- .../renderer/passes/PixelPickingPass.ts | 135 +++++++++++------- packages/layers/src/core/BaseLayer.ts | 43 +++++- packages/layers/src/heatmap/models/heatmap.ts | 2 +- .../layers/src/plugins/DataMappingPlugin.ts | 2 +- .../layers/src/plugins/DataSourcePlugin.ts | 2 +- .../layers/src/plugins/LayerStylePlugin.ts | 2 +- .../layers/src/plugins/PixelPickingPlugin.ts | 20 ++- packages/layers/src/point/models/fill.ts | 2 +- packages/layers/src/point/models/normal.ts | 2 +- packages/layers/src/raster/raster.ts | 2 +- packages/layers/src/raster/raster2d.ts | 2 +- .../{layers/src/utils => utils/src}/color.ts | 7 + packages/utils/src/index.ts | 1 + stories/Layers/components/Point.tsx | 13 +- stories/Layers/components/Point3D.tsx | 11 +- stories/Layers/components/Polygon3D.tsx | 1 + stories/Picking/components/Tooltip.tsx | 20 +-- 24 files changed, 234 insertions(+), 88 deletions(-) rename packages/{layers/src/utils => utils/src}/color.ts (86%) diff --git a/packages/component/src/popup.ts b/packages/component/src/popup.ts index b72653a452..76fee84a81 100644 --- a/packages/component/src/popup.ts +++ b/packages/component/src/popup.ts @@ -165,7 +165,10 @@ export default class Popup extends EventEmitter implements IPopup { }; } - private onClickClose() { + private onClickClose(e: Event) { + if (e.stopPropagation) { + e.stopPropagation(); + } this.remove(); } @@ -193,6 +196,9 @@ export default class Popup extends EventEmitter implements IPopup { this.container.addEventListener('mousedown', (e) => { e.stopPropagation(); }); + this.container.addEventListener('click', (e) => { + e.stopPropagation(); + }); } if (maxWidth && this.container.style.maxWidth !== maxWidth) { this.container.style.maxWidth = maxWidth; diff --git a/packages/core/src/services/component/PopupService.ts b/packages/core/src/services/component/PopupService.ts index cdde3d992b..49080d4179 100644 --- a/packages/core/src/services/component/PopupService.ts +++ b/packages/core/src/services/component/PopupService.ts @@ -17,7 +17,9 @@ export default class PopupService implements IPopupService { } public addPopup(popup: IPopup) { - this.popup.remove(); + if (this.popup) { + this.popup.remove(); + } popup.addTo(this.scene); this.popup = popup; } diff --git a/packages/core/src/services/config/ConfigService.ts b/packages/core/src/services/config/ConfigService.ts index 09db7ed6d1..2f607ee31a 100644 --- a/packages/core/src/services/config/ConfigService.ts +++ b/packages/core/src/services/config/ConfigService.ts @@ -56,7 +56,9 @@ const defaultLayerConfig: Partial = { active: false, activeColor: 'red', enableHighlight: false, + enableSelect: false, highlightColor: 'red', + selectColor: 'blue', enableTAA: false, jitterScale: 1, enableLighting: false, diff --git a/packages/core/src/services/interaction/IInteractionService.ts b/packages/core/src/services/interaction/IInteractionService.ts index ed351c574e..396021e854 100644 --- a/packages/core/src/services/interaction/IInteractionService.ts +++ b/packages/core/src/services/interaction/IInteractionService.ts @@ -1,6 +1,16 @@ +import { ILngLat } from '../map/IMapService'; export enum InteractionEvent { Hover = 'hover', Click = 'click', + Select = 'select', + Active = 'active', +} +export interface IInteractionTarget { + x: number; + y: number; + lngLat: ILngLat; + type: string; + featureId?: number; } export interface IInteractionService { @@ -8,7 +18,9 @@ export interface IInteractionService { destroy(): void; on( eventName: InteractionEvent, - callback: (params: { x: number; y: number; type: string }) => void, + callback: (params: IInteractionTarget) => void, ): void; - triggerHover({ x, y, type }: { x: number; y: number; type?: string }): void; + triggerHover({ x, y, type }: Partial): void; + triggerSelect(id: number): void; + triggerActive(id: number): void; } diff --git a/packages/core/src/services/interaction/InteractionService.ts b/packages/core/src/services/interaction/InteractionService.ts index add63327e4..82be0ee533 100644 --- a/packages/core/src/services/interaction/InteractionService.ts +++ b/packages/core/src/services/interaction/InteractionService.ts @@ -36,6 +36,13 @@ export default class InteractionService extends EventEmitter public triggerHover({ x, y }: { x: number; y: number }) { this.emit(InteractionEvent.Hover, { x, y }); } + public triggerSelect(id: number): void { + this.emit(InteractionEvent.Select, { featureId: id }); + } + + public triggerActive(id: number): void { + this.emit(InteractionEvent.Active, { featureId: id }); + } private addEventListenerOnMap() { const $containter = this.mapService.getMapContainer(); @@ -81,6 +88,7 @@ export default class InteractionService extends EventEmitter x -= left; y -= top; } - this.emit(InteractionEvent.Hover, { x, y, type }); + const lngLat = this.mapService.containerToLngLat([x, y]); + this.emit(InteractionEvent.Hover, { x, y, lngLat, type }); }; } diff --git a/packages/core/src/services/layer/ILayerService.ts b/packages/core/src/services/layer/ILayerService.ts index c3164a439a..81b7339f36 100644 --- a/packages/core/src/services/layer/ILayerService.ts +++ b/packages/core/src/services/layer/ILayerService.ts @@ -73,6 +73,8 @@ export interface ILayer { beforePickingEncode: SyncHook; afterPickingEncode: SyncHook; beforeHighlight: SyncHook<[number[]]>; + beforeSelect: SyncHook<[number[]]>; + afterSelect: SyncHook; afterHighlight: SyncHook; beforeDestroy: SyncHook; afterDestroy: SyncHook; @@ -86,6 +88,8 @@ export interface ILayer { getLayerConfig(): Partial; getContainer(): Container; setContainer(container: Container): void; + setCurrentPickId(id: number | null): void; + getCurrentPickId(): number | null; buildLayerModel( options: ILayerModelInitializationOptions & Partial, @@ -198,10 +202,13 @@ export interface ILayerConfig { * 开启高亮 */ enableHighlight: boolean; + + enableSelect: boolean; /** * 高亮颜色 */ highlightColor: string | number[]; + selectColor: string | number[]; active: boolean; activeColor: string | number[]; /** diff --git a/packages/core/src/services/renderer/passes/BaseNormalPass.ts b/packages/core/src/services/renderer/passes/BaseNormalPass.ts index 048c187775..384586e928 100644 --- a/packages/core/src/services/renderer/passes/BaseNormalPass.ts +++ b/packages/core/src/services/renderer/passes/BaseNormalPass.ts @@ -1,5 +1,9 @@ import { inject, injectable } from 'inversify'; -import { IRendererService, IShaderModuleService } from '../../../index'; +import { + IMapService, + IRendererService, + IShaderModuleService, +} from '../../../index'; import { TYPES } from '../../../types'; import { ICameraService } from '../../camera/ICameraService'; import { IInteractionService } from '../../interaction/IInteractionService'; @@ -17,6 +21,7 @@ export default class BaseNormalPass protected rendererService: IRendererService; protected cameraService: ICameraService; + protected mapService: IMapService; protected interactionService: IInteractionService; protected layerService: ILayerService; @@ -38,6 +43,7 @@ export default class BaseNormalPass this.cameraService = layer .getContainer() .get(TYPES.ICameraService); + this.mapService = layer.getContainer().get(TYPES.IMapService); this.interactionService = layer .getContainer() .get(TYPES.IInteractionService); diff --git a/packages/core/src/services/renderer/passes/PixelPickingPass.ts b/packages/core/src/services/renderer/passes/PixelPickingPass.ts index a9c50ee8d7..7f0421ee39 100644 --- a/packages/core/src/services/renderer/passes/PixelPickingPass.ts +++ b/packages/core/src/services/renderer/passes/PixelPickingPass.ts @@ -1,20 +1,18 @@ +import { decodePickingColor, encodePickingColor } from '@antv/l7-utils'; import { inject, injectable } from 'inversify'; import { TYPES } from '../../../types'; -import { InteractionEvent } from '../../interaction/IInteractionService'; +import { + IInteractionTarget, + InteractionEvent, +} from '../../interaction/IInteractionService'; import { ILayer } from '../../layer/ILayerService'; import { ILogService } from '../../log/ILogService'; +import { ILngLat } from '../../map/IMapService'; import { gl } from '../gl'; import { IFramebuffer } from '../IFramebuffer'; import { PassType } from '../IMultiPassRenderer'; import BaseNormalPass from './BaseNormalPass'; -function decodePickingColor(color: Uint8Array): number { - const [i1, i2, i3] = color; - // 1 was added to seperate from no selection - const index = i1 + i2 * 256 + i3 * 65536 - 1; - return index; -} - /** * color-based PixelPickingPass * @see https://github.com/antvis/L7/blob/next/dev-docs/PixelPickingEngine.md @@ -66,6 +64,14 @@ export default class PixelPickingPass< // 监听 hover 事件 this.interactionService.on(InteractionEvent.Hover, this.pickFromPickingFBO); + this.interactionService.on( + InteractionEvent.Select, + this.selectFeatureHander.bind(this), + ); + this.interactionService.on( + InteractionEvent.Active, + this.highlightFeatureHander.bind(this), + ); } public render(layer: ILayer) { @@ -112,15 +118,7 @@ export default class PixelPickingPass< * 拾取视口指定坐标属于的要素 * TODO:支持区域拾取 */ - private pickFromPickingFBO = ({ - x, - y, - type, - }: { - x: number; - y: number; - type: string; - }) => { + private pickFromPickingFBO = ({ x, y, lngLat, type }: IInteractionTarget) => { if (!this.layer.isVisible()) { return; } @@ -130,7 +128,7 @@ export default class PixelPickingPass< useFramebuffer, } = this.rendererService; const { width, height } = getViewportSize(); - const { enableHighlight } = this.layer.getLayerConfig(); + const { enableHighlight, enableSelect } = this.layer.getLayerConfig(); const xInDevicePixel = x * window.devicePixelRatio; const yInDevicePixel = y * window.devicePixelRatio; @@ -142,7 +140,6 @@ export default class PixelPickingPass< ) { return; } - let pickedColors: Uint8Array | undefined; useFramebuffer(this.pickingFBO, () => { // avoid realloc @@ -166,54 +163,58 @@ export default class PixelPickingPass< const rawFeature = this.layer .getSource() .getFeatureById(pickedFeatureIdx); - + const target = { + x, + y, + type, + lngLat, + featureId: pickedFeatureIdx, + feature: rawFeature, + }; if (!rawFeature) { // this.logger.error( // '未找到颜色编码解码后的原始 feature,请检查 fragment shader 中末尾是否添加了 `gl_FragColor = filterColor(gl_FragColor);`', // ); } else { // trigger onHover/Click callback on layer - this.triggerHoverOnLayer({ x, y, type, feature: rawFeature }); + this.layer.setCurrentPickId(pickedFeatureIdx); + this.triggerHoverOnLayer(target); } + } else { + const target = { + x, + y, + lngLat, + type: this.layer.getCurrentPickId() === null ? 'unpick' : 'mouseout', + featureId: null, + feature: null, + }; + this.triggerHoverOnLayer(target); + this.layer.setCurrentPickId(null); } }); if (enableHighlight) { this.highlightPickedFeature(pickedColors); } + if ( + enableSelect && + type === 'click' && + pickedColors?.toString() !== [0, 0, 0, 0].toString() + ) { + this.selectFeature(pickedColors); + } }; - private triggerHoverOnLayer({ - x, - y, - type, - feature, - }: { + private triggerHoverOnLayer(target: { x: number; y: number; type: string; + lngLat: ILngLat; feature: unknown; + featureId: number | null; }) { - const { onHover, onClick } = this.layer.getLayerConfig(); - // if (onHover) { - // onHover({ - // x, - // y, - // feature, - // }); - // } - // if (onClick) { - // onClick({ - // x, - // y, - // feature, - // }); - // } - this.layer.emit(type, { - x, - y, - feature, - }); + this.layer.emit(target.type, target); } /** @@ -232,7 +233,6 @@ export default class PixelPickingPass< private highlightPickedFeature(pickedColors: Uint8Array | undefined) { const [r, g, b] = pickedColors; const { clear, useFramebuffer } = this.rendererService; - // 先输出到 PostProcessor const readFBO = this.layer.multiPassRenderer .getPostProcessor() @@ -257,4 +257,43 @@ export default class PixelPickingPass< }); this.layer.multiPassRenderer.getPostProcessor().render(this.layer); } + + private selectFeature(pickedColors: Uint8Array | undefined) { + const [r, g, b] = pickedColors; + const { clear, useFramebuffer } = this.rendererService; + + // 先输出到 PostProcessor + const readFBO = this.layer.multiPassRenderer + .getPostProcessor() + .getReadFBO(); + this.layer.hooks.beforeRender.call(); + useFramebuffer(readFBO, () => { + clear({ + color: [0, 0, 0, 0], + depth: 1, + stencil: 0, + framebuffer: readFBO, + }); + + // TODO: highlight pass 需要 multipass + const originRenderFlag = this.layer.multiPassRenderer.getRenderFlag(); + this.layer.multiPassRenderer.setRenderFlag(false); + this.layer.hooks.beforeSelect.call([r, g, b]); + this.layer.render(); + this.layer.hooks.afterSelect.call(); + this.layer.hooks.afterRender.call(); + this.layer.multiPassRenderer.setRenderFlag(originRenderFlag); + }); + this.layer.multiPassRenderer.getPostProcessor().render(this.layer); + } + + private selectFeatureHander({ featureId }: Partial) { + const pickedColors = encodePickingColor(featureId as number); + this.selectFeature(new Uint8Array(pickedColors)); + } + + private highlightFeatureHander({ featureId }: Partial) { + const pickedColors = encodePickingColor(featureId as number); + this.highlightPickedFeature(new Uint8Array(pickedColors)); + } } diff --git a/packages/layers/src/core/BaseLayer.ts b/packages/layers/src/core/BaseLayer.ts index d6627c2875..4a2f628691 100644 --- a/packages/layers/src/core/BaseLayer.ts +++ b/packages/layers/src/core/BaseLayer.ts @@ -81,6 +81,8 @@ export default class BaseLayer extends EventEmitter afterPickingEncode: new SyncHook(), beforeHighlight: new SyncHook<[number[]]>(['pickedColor']), afterHighlight: new SyncHook(), + beforeSelect: new SyncHook<[number[]]>(['pickedColor']), + afterSelect: new SyncHook(), beforeDestroy: new SyncHook(), afterDestroy: new SyncHook(), }; @@ -142,6 +144,8 @@ export default class BaseLayer extends EventEmitter private configSchema: object; + private currentPickId: number | null = null; + private rawConfig: Partial; private needUpdateConfig: Partial; @@ -159,7 +163,7 @@ export default class BaseLayer extends EventEmitter private scaleOptions: IScaleOptions = {}; - constructor(config: Partial) { + constructor(config: Partial = {}) { super(); this.rawConfig = config; } @@ -469,10 +473,22 @@ export default class BaseLayer extends EventEmitter ? options.color : this.getLayerConfig().highlightColor, }); + this.interactionService.triggerActive(id); } } public select(option: IActiveOption | false): ILayer { + const activeOption: Partial = {}; + activeOption.enableSelect = isObject(option) ? true : option; + if (isObject(option)) { + activeOption.enableSelect = true; + if (option.color) { + activeOption.selectColor = option.color; + } + } else { + activeOption.enableHighlight = !!option; + } + this.updateLayerConfig(activeOption); return this; } @@ -480,7 +496,23 @@ export default class BaseLayer extends EventEmitter id: number | { x: number; y: number }, options?: IActiveOption, ): void { - throw new Error('Method not implemented.'); + if (isObject(id)) { + const { x = 0, y = 0 } = id; + this.updateLayerConfig({ + selectColor: isObject(options) + ? options.color + : this.getLayerConfig().selectColor, + }); + this.pick({ x, y }); + } else { + this.updateLayerConfig({ + pickedFeatureID: id, + selectColor: isObject(options) + ? options.color + : this.getLayerConfig().selectColor, + }); + this.interactionService.triggerSelect(id); + } } public show(): ILayer { this.updateLayerConfig({ @@ -502,6 +534,13 @@ export default class BaseLayer extends EventEmitter return this; } + public setCurrentPickId(id: number) { + this.currentPickId = id; + } + + public getCurrentPickId(): number | null { + return this.currentPickId; + } public isVisible(): boolean { const zoom = this.mapService.getZoom(); diff --git a/packages/layers/src/heatmap/models/heatmap.ts b/packages/layers/src/heatmap/models/heatmap.ts index 48d7ccdada..9487b00b43 100644 --- a/packages/layers/src/heatmap/models/heatmap.ts +++ b/packages/layers/src/heatmap/models/heatmap.ts @@ -7,10 +7,10 @@ import { IModelUniform, ITexture2D, } from '@antv/l7-core'; +import { generateColorRamp, IColorRamp } from '@antv/l7-utils'; import { mat4 } from 'gl-matrix'; import BaseModel from '../../core/BaseModel'; import { HeatmapTriangulation } from '../../core/triangulation'; -import { generateColorRamp, IColorRamp } from '../../utils/color'; import heatmap3DFrag from '../shaders/heatmap_3d_frag.glsl'; import heatmap3DVert from '../shaders/heatmap_3d_vert.glsl'; import heatmapColorFrag from '../shaders/heatmap_frag.glsl'; diff --git a/packages/layers/src/plugins/DataMappingPlugin.ts b/packages/layers/src/plugins/DataMappingPlugin.ts index bd7a897893..8123bb6604 100644 --- a/packages/layers/src/plugins/DataMappingPlugin.ts +++ b/packages/layers/src/plugins/DataMappingPlugin.ts @@ -9,8 +9,8 @@ import { IStyleAttributeService, TYPES, } from '@antv/l7-core'; +import { rgb2arr } from '@antv/l7-utils'; import { inject, injectable } from 'inversify'; -import { rgb2arr } from '../utils/color'; @injectable() export default class DataMappingPlugin implements ILayerPlugin { diff --git a/packages/layers/src/plugins/DataSourcePlugin.ts b/packages/layers/src/plugins/DataSourcePlugin.ts index 6de90f0b61..371fe51bb2 100644 --- a/packages/layers/src/plugins/DataSourcePlugin.ts +++ b/packages/layers/src/plugins/DataSourcePlugin.ts @@ -23,7 +23,7 @@ export default class DataSourcePlugin implements ILayerPlugin { const source = layer.getSource(); const cluster = source.cluster; const { zoom = 0, maxZoom = 16 } = source.clusterOptions; - const newZoom = this.mapService.getZoom(); + const newZoom = this.mapService.getZoom() - 1; if (cluster && Math.abs(zoom - newZoom) > 1 && maxZoom > zoom) { source.updateClusterData(Math.floor(newZoom)); return true; diff --git a/packages/layers/src/plugins/LayerStylePlugin.ts b/packages/layers/src/plugins/LayerStylePlugin.ts index c6d3915604..9b61ae1bbc 100644 --- a/packages/layers/src/plugins/LayerStylePlugin.ts +++ b/packages/layers/src/plugins/LayerStylePlugin.ts @@ -1,7 +1,7 @@ import { ILayer, ILayerPlugin, IMapService, TYPES } from '@antv/l7-core'; import Source from '@antv/l7-source'; +import { encodePickingColor, rgb2arr } from '@antv/l7-utils'; import { injectable } from 'inversify'; -import { encodePickingColor, rgb2arr } from '../utils/color'; @injectable() export default class LayerStylePlugin implements ILayerPlugin { public apply(layer: ILayer) { diff --git a/packages/layers/src/plugins/PixelPickingPlugin.ts b/packages/layers/src/plugins/PixelPickingPlugin.ts index 3afd3f0387..6e51cdd563 100644 --- a/packages/layers/src/plugins/PixelPickingPlugin.ts +++ b/packages/layers/src/plugins/PixelPickingPlugin.ts @@ -7,8 +7,8 @@ import { IRendererService, IStyleAttributeService, } from '@antv/l7-core'; +import { encodePickingColor, rgb2arr } from '@antv/l7-utils'; import { injectable } from 'inversify'; -import { encodePickingColor, rgb2arr } from '../utils/color'; const PickingStage = { NONE: 0.0, @@ -95,6 +95,24 @@ export default class PixelPickingPlugin implements ILayerPlugin { ); }, ); + + layer.hooks.beforeSelect.tap( + 'PixelPickingPlugin', + (pickedColor: number[]) => { + const { selectColor } = layer.getLayerConfig(); + const highlightColorInArray = + typeof selectColor === 'string' + ? rgb2arr(selectColor) + : selectColor || [1, 0, 0, 1]; + layer.models.forEach((model) => + model.addUniforms({ + u_PickingStage: PickingStage.HIGHLIGHT, + u_PickingColor: pickedColor, + u_HighlightColor: highlightColorInArray.map((c) => c * 255), + }), + ); + }, + ); // } } } diff --git a/packages/layers/src/point/models/fill.ts b/packages/layers/src/point/models/fill.ts index d87821a542..0b068eb6ca 100644 --- a/packages/layers/src/point/models/fill.ts +++ b/packages/layers/src/point/models/fill.ts @@ -7,9 +7,9 @@ import { IModel, IModelUniform, } from '@antv/l7-core'; +import { rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; import { PointFillTriangulation } from '../../core/triangulation'; -import { rgb2arr } from '../../utils/color'; import pointFillFrag from '../shaders/fill_frag.glsl'; import pointFillVert from '../shaders/fill_vert.glsl'; interface IPointLayerStyleOptions { diff --git a/packages/layers/src/point/models/normal.ts b/packages/layers/src/point/models/normal.ts index 9b3f9a2cc8..987a3924ee 100644 --- a/packages/layers/src/point/models/normal.ts +++ b/packages/layers/src/point/models/normal.ts @@ -6,8 +6,8 @@ import { IModelUniform, } from '@antv/l7-core'; +import { rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { rgb2arr } from '../../utils/color'; import normalFrag from '../shaders/normal_frag.glsl'; import normalVert from '../shaders/normal_vert.glsl'; diff --git a/packages/layers/src/raster/raster.ts b/packages/layers/src/raster/raster.ts index 9fb9d7e963..b8035e2ab6 100644 --- a/packages/layers/src/raster/raster.ts +++ b/packages/layers/src/raster/raster.ts @@ -11,8 +11,8 @@ import { lazyInject, TYPES, } from '@antv/l7-core'; +import { generateColorRamp, IColorRamp } from '@antv/l7-utils'; import BaseLayer from '../core/BaseLayer'; -import { generateColorRamp, IColorRamp } from '../utils/color'; import { RasterTriangulation } from './buffers/triangulation'; import rasterFrag from './shaders/raster_frag.glsl'; import rasterVert from './shaders/raster_vert.glsl'; diff --git a/packages/layers/src/raster/raster2d.ts b/packages/layers/src/raster/raster2d.ts index 5a5e438c6c..f82581ffbb 100644 --- a/packages/layers/src/raster/raster2d.ts +++ b/packages/layers/src/raster/raster2d.ts @@ -1,7 +1,7 @@ import { AttributeType, gl, IEncodeFeature, ITexture2D } from '@antv/l7-core'; +import { generateColorRamp, IColorRamp } from '@antv/l7-utils'; import BaseLayer from '../core/BaseLayer'; import { RasterImageTriangulation } from '../core/triangulation'; -import { generateColorRamp, IColorRamp } from '../utils/color'; import rasterImageFrag from './shaders/raster_2d_frag.glsl'; import rasterImageVert from './shaders/raster_2d_vert.glsl'; interface IRasterLayerStyleOptions { diff --git a/packages/layers/src/utils/color.ts b/packages/utils/src/color.ts similarity index 86% rename from packages/layers/src/utils/color.ts rename to packages/utils/src/color.ts index f366874639..e0c0082391 100644 --- a/packages/layers/src/utils/color.ts +++ b/packages/utils/src/color.ts @@ -15,6 +15,13 @@ export function rgb2arr(str: string) { return arr; } +export function decodePickingColor(color: Uint8Array): number { + const [i1, i2, i3] = color; + // 1 was added to seperate from no selection + const index = i1 + i2 * 256 + i3 * 65536 - 1; + return index; +} + export function encodePickingColor( featureIdx: number, ): [number, number, number] { diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index d3e73b4277..6d36fb0879 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -4,4 +4,5 @@ export * from './fetchData'; export * from './geo'; export * from './lru_cache'; export * from './event'; +export * from './color'; export { DOM }; diff --git a/stories/Layers/components/Point.tsx b/stories/Layers/components/Point.tsx index d1a3f1102b..dc8998259c 100644 --- a/stories/Layers/components/Point.tsx +++ b/stories/Layers/components/Point.tsx @@ -19,7 +19,7 @@ export default class Point3D extends React.Component { const scene = new Scene({ id: 'map', - map: new GaodeMap({ + map: new Mapbox({ center: [120.19382669582967, 30.258134], pitch: 0, style: 'dark', @@ -36,13 +36,18 @@ export default class Point3D extends React.Component { type: 'quantile', }) .size('point_count', [5, 10, 15, 20, 25]) - .active(true) - .color('red') + .color('yellow') .style({ - opacity: 0.3, + opacity: 0.5, strokeWidth: 1, }); scene.addLayer(pointLayer); + pointLayer.on('mousemove', (e) => { + const id = e.featureId; + console.log(id); + pointLayer.setActive(id); + }); + this.scene = scene; }); } diff --git a/stories/Layers/components/Point3D.tsx b/stories/Layers/components/Point3D.tsx index dc9f08f207..8861432e01 100644 --- a/stories/Layers/components/Point3D.tsx +++ b/stories/Layers/components/Point3D.tsx @@ -21,21 +21,14 @@ export default class Point3D extends React.Component { zoom: 1, }), }); - const pointLayer = new PointLayer({ - enablePicking: false, - enableHighlight: false, - enableTAA: false, - onHover: (pickedFeature: any) => { - // tslint:disable-next-line:no-console - console.log('Scene4', pickedFeature.feature.name); - }, - }); + const pointLayer = new PointLayer(); pointLayer .source(data, { cluster: true, }) .color('red') .shape('cylinder') + .active({ color: 'blue' }) .size([15, 10]); scene.addLayer(pointLayer); scene.render(); diff --git a/stories/Layers/components/Polygon3D.tsx b/stories/Layers/components/Polygon3D.tsx index bf42016185..2b9740c454 100644 --- a/stories/Layers/components/Polygon3D.tsx +++ b/stories/Layers/components/Polygon3D.tsx @@ -41,6 +41,7 @@ export default class Polygon3D extends React.Component { .source(await response.json()) .shape('extrude') .size('h20', [100, 120, 160, 200, 260, 500]) + .active({ color: 'blue' }) .color('h20', [ '#816CAD', '#A67FB5', diff --git a/stories/Picking/components/Tooltip.tsx b/stories/Picking/components/Tooltip.tsx index 426c68d6dd..36956f6f6b 100644 --- a/stories/Picking/components/Tooltip.tsx +++ b/stories/Picking/components/Tooltip.tsx @@ -1,5 +1,5 @@ // @ts-ignore -import { PolygonLayer, Scene } from '@antv/l7'; +import { PolygonLayer, Popup, Scene } from '@antv/l7'; import { Mapbox } from '@antv/l7-maps'; import * as dat from 'dat.gui'; import * as React from 'react'; @@ -24,15 +24,7 @@ export default class Tooltip extends React.Component { zoom: 3, }), }); - const layer = new PolygonLayer({ - enablePicking: true, - enableHighlight: false, - onHover: (pickedFeature) => { - // tslint:disable-next-line:no-console - console.log(pickedFeature); - }, - }); - + const layer = new PolygonLayer(); layer .source(await response.json()) .size('name', [0, 10000, 50000, 30000, 100000]) @@ -49,6 +41,14 @@ export default class Tooltip extends React.Component { opacity: 0.8, }); scene.addLayer(layer); + layer.on('click', (e) => { + const popup = new Popup({ + offsets: [0, 0], + }) + .setLnglat(e.lngLat) + .setText(e.feature.properties.name); + scene.addPopup(popup); + }); this.scene = scene; }