diff --git a/demos/tutorial/data/demo/line.js b/demos/tutorial/data/demo/line.js index a1722e38b5..6edbd261ca 100644 --- a/demos/tutorial/data/demo/line.js +++ b/demos/tutorial/data/demo/line.js @@ -33,6 +33,5 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/ZVfOvhVCzwBkISNsuKCc.json') ].reverse(), ) scene.addLayer(layer); - console.log(layer); }); diff --git a/packages/core/src/services/config/ConfigService.ts b/packages/core/src/services/config/ConfigService.ts index ccd6e92559..7025ab6dd4 100644 --- a/packages/core/src/services/config/ConfigService.ts +++ b/packages/core/src/services/config/ConfigService.ts @@ -56,10 +56,10 @@ const defaultLayerConfig: Partial = { enableMultiPassRenderer: true, enablePicking: true, active: false, - activeColor: 'red', + activeColor: '#2f54eb', enableHighlight: false, enableSelect: false, - highlightColor: 'red', + highlightColor: '#2f54eb', selectColor: 'blue', enableTAA: false, jitterScale: 1, diff --git a/packages/core/src/services/layer/ILayerService.ts b/packages/core/src/services/layer/ILayerService.ts index ad4df416b6..a2ac525aa6 100644 --- a/packages/core/src/services/layer/ILayerService.ts +++ b/packages/core/src/services/layer/ILayerService.ts @@ -127,7 +127,7 @@ export interface ILayer { id: number | { x: number; y: number }, option?: IActiveOption, ): void; - select(option: IActiveOption | false): ILayer; + select(option: IActiveOption | boolean): ILayer; setSelect( id: number | { x: number; y: number }, option?: IActiveOption, diff --git a/packages/core/src/services/layer/LayerService.ts b/packages/core/src/services/layer/LayerService.ts index 0e88b8a9ad..784465ff0c 100644 --- a/packages/core/src/services/layer/LayerService.ts +++ b/packages/core/src/services/layer/LayerService.ts @@ -16,6 +16,8 @@ export default class LayerService implements ILayerService { private animateInstanceCount: number = 0; + private alreadyInRendering: boolean = false; + @inject(TYPES.IRendererService) private readonly renderService: IRendererService; @@ -58,7 +60,11 @@ export default class LayerService implements ILayerService { public renderLayers() { // TODO:脏检查,只渲染发生改变的 Layer + if (this.alreadyInRendering) { + return; + } // + this.alreadyInRendering = true; this.clear(); this.layers .filter((layer) => layer.isVisible()) @@ -69,6 +75,7 @@ export default class LayerService implements ILayerService { layer.render(); layer.hooks.afterRender.call(); }); + this.alreadyInRendering = false; } public updateRenderOrder() { diff --git a/packages/core/src/services/renderer/passes/PixelPickingPass.ts b/packages/core/src/services/renderer/passes/PixelPickingPass.ts index 83419a005a..0de4211beb 100644 --- a/packages/core/src/services/renderer/passes/PixelPickingPass.ts +++ b/packages/core/src/services/renderer/passes/PixelPickingPass.ts @@ -237,59 +237,14 @@ 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() - .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.beforeHighlight.call([r, g, b]); - this.layer.render(); - this.layer.hooks.afterHighlight.call(); - this.layer.hooks.afterRender.call(); - this.layer.multiPassRenderer.setRenderFlag(originRenderFlag); - }); - this.layer.multiPassRenderer.getPostProcessor().render(this.layer); + this.layer.hooks.beforeHighlight.call([r, g, b]); + this.layerService.renderLayers(); } 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); + this.layer.hooks.beforeSelect.call([r, g, b]); + this.layerService.renderLayers(); } private selectFeatureHander({ featureId }: Partial) { diff --git a/packages/core/src/shaders/picking.frag.glsl b/packages/core/src/shaders/picking.frag.glsl index 66e78052ac..0e58d7eb15 100644 --- a/packages/core/src/shaders/picking.frag.glsl +++ b/packages/core/src/shaders/picking.frag.glsl @@ -43,4 +43,4 @@ vec4 filterPickingColor(vec4 color) { */ vec4 filterColor(vec4 color) { return filterPickingColor(filterHighlightColor(color)); -} \ No newline at end of file +} diff --git a/packages/layers/src/core/BaseLayer.ts b/packages/layers/src/core/BaseLayer.ts index b856a4fdbd..f4cd34ac7c 100644 --- a/packages/layers/src/core/BaseLayer.ts +++ b/packages/layers/src/core/BaseLayer.ts @@ -38,6 +38,7 @@ import { TYPES, } from '@antv/l7-core'; import Source from '@antv/l7-source'; +import { encodePickingColor } from '@antv/l7-utils'; import { EventEmitter } from 'eventemitter3'; import { Container } from 'inversify'; import { isFunction, isObject } from 'lodash'; @@ -509,7 +510,7 @@ export default class BaseLayer extends EventEmitter } } - public select(option: IActiveOption | false): ILayer { + public select(option: IActiveOption | boolean): ILayer { const activeOption: Partial = {}; activeOption.enableSelect = isObject(option) ? true : option; if (isObject(option)) { @@ -518,7 +519,7 @@ export default class BaseLayer extends EventEmitter activeOption.selectColor = option.color; } } else { - activeOption.enableHighlight = !!option; + activeOption.enableSelect = !!option; } this.updateLayerConfig(activeOption); return this; @@ -543,7 +544,11 @@ export default class BaseLayer extends EventEmitter ? options.color : this.getLayerConfig().selectColor, }); - this.interactionService.triggerSelect(id); + this.hooks.beforeHighlight.call( + encodePickingColor(id as number) as number[], + ); + // this.interactionService.triggerSelect(id); + // this.reRender(); } } public setBlend(type: keyof typeof BlendType): void { diff --git a/packages/layers/src/plugins/LayerStylePlugin.ts b/packages/layers/src/plugins/LayerStylePlugin.ts index 4a3e426d75..2df6c7a27f 100644 --- a/packages/layers/src/plugins/LayerStylePlugin.ts +++ b/packages/layers/src/plugins/LayerStylePlugin.ts @@ -15,19 +15,5 @@ export default class LayerStylePlugin implements ILayerPlugin { layer.fitBounds(); } }); - - layer.hooks.beforeRender.tap('LayerStylePlugin', () => { - const { - highlightColor = 'red', - pickedFeatureID = -1, - } = layer.getLayerConfig(); - layer.models.forEach((model) => - model.addUniforms({ - u_PickingStage: 2.0, - u_PickingColor: encodePickingColor(pickedFeatureID), - u_HighlightColor: rgb2arr(highlightColor as string), - }), - ); - }); } } diff --git a/packages/layers/src/plugins/PixelPickingPlugin.ts b/packages/layers/src/plugins/PixelPickingPlugin.ts index 6e51cdd563..8a610782b0 100644 --- a/packages/layers/src/plugins/PixelPickingPlugin.ts +++ b/packages/layers/src/plugins/PixelPickingPlugin.ts @@ -7,7 +7,11 @@ import { IRendererService, IStyleAttributeService, } from '@antv/l7-core'; -import { encodePickingColor, rgb2arr } from '@antv/l7-utils'; +import { + decodePickingColor, + encodePickingColor, + rgb2arr, +} from '@antv/l7-utils'; import { injectable } from 'inversify'; const PickingStage = { @@ -67,12 +71,11 @@ export default class PixelPickingPlugin implements ILayerPlugin { layer.hooks.afterPickingEncode.tap('PixelPickingPlugin', () => { const { enablePicking } = layer.getLayerConfig(); + // 区分选中高亮 和滑过高亮 if (enablePicking && layer.isVisible()) { layer.models.forEach((model) => model.addUniforms({ - u_PickingStage: PickingStage.NONE, - u_PickingColor: [0, 0, 0], - u_HighlightColor: [0, 0, 0, 0], + u_PickingStage: PickingStage.HIGHLIGHT, }), ); } @@ -86,6 +89,9 @@ export default class PixelPickingPlugin implements ILayerPlugin { typeof highlightColor === 'string' ? rgb2arr(highlightColor) : highlightColor || [1, 0, 0, 1]; + layer.updateLayerConfig({ + pickedFeatureID: decodePickingColor(new Uint8Array(pickedColor)), + }); layer.models.forEach((model) => model.addUniforms({ u_PickingStage: PickingStage.HIGHLIGHT, diff --git a/packages/renderer/src/regl/ReglModel.ts b/packages/renderer/src/regl/ReglModel.ts index dc039b9f0c..abbe3d1d51 100644 --- a/packages/renderer/src/regl/ReglModel.ts +++ b/packages/renderer/src/regl/ReglModel.ts @@ -103,7 +103,6 @@ export default class ReglModel implements IModel { ...this.uniforms, ...this.extractUniforms(options.uniforms || {}), }; - const reglDrawProps: { [key: string]: | regl.Framebuffer diff --git a/stories/Components/components/Scale.tsx b/stories/Components/components/Scale.tsx index b5e218a875..50a0ef5d40 100644 --- a/stories/Components/components/Scale.tsx +++ b/stories/Components/components/Scale.tsx @@ -1,5 +1,5 @@ // @ts-ignore -import { PolygonLayer, Scale, Scene, PointLayer } from '@antv/l7'; +import { PointLayer, PolygonLayer, Scale, Scene } from '@antv/l7'; import { Mapbox } from '@antv/l7-maps'; import * as React from 'react'; @@ -43,6 +43,7 @@ export default class ScaleComponent extends React.Component { '#CF1D49', ]) .shape('fill') + .select(true) .style({ opacity: 1.0, }); @@ -57,14 +58,18 @@ export default class ScaleComponent extends React.Component { type: 'quantile', }) .size('point_count', [5, 10, 15, 20, 25]) - .animate(false) - .active(true) + .animate(true) + .select(true) .color('yellow') .style({ opacity: 0.5, strokeWidth: 1, }); scene.addLayer(pointLayer); + pointLayer.on('click', (e) => { + // console.log(e); + // pointLayer.setSelect(e.featureId); + }); const scaleControl = new Scale(); scene.addControl(scaleControl); diff --git a/stories/Layers/components/Arcline.tsx b/stories/Layers/components/Arcline.tsx index 9994416150..5a350fd5eb 100644 --- a/stories/Layers/components/Arcline.tsx +++ b/stories/Layers/components/Arcline.tsx @@ -38,9 +38,12 @@ export default class ArcLineDemo extends React.Component { }) .size(1) .shape('arc3d') - .active(true) + .select({ + color: 'red', + }) .color('rgb(13,64,140)') .animate({ + enable: true, interval: 0.1, duration: 2, trailLength: 1.0,