From fb16d353a71dcab65efed8b8b311a932248d5b51 Mon Sep 17 00:00:00 2001 From: YiQianYao <42212176+2912401452@users.noreply.github.com> Date: Tue, 14 Dec 2021 18:52:31 +0800 Subject: [PATCH] Shihuidev (#881) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 增加着色器的拾取计算控制、完善 arcmini * feat: 完善 enableShaderPick/disableShaderPick 功能 * style: lint style * feat: 补充调用高德地图公交线路查询 demo * style: lint style * feat: 优化弧线的纹理动画 * style: lint style * feat: 去除greatCircle 的纹理动画优化 * feat: 扩展点图层圆柱效果 * feat: 增加几何体的径向渐变配置 * style: lint style * fix: 修复bug 图层触发的事件跟图层设置的zIndex无关,只跟插入图层先后顺序有关 * style: lint style * feat: 补全挤出几何体拾取颜色的光照配置 * style: lint style * fix: 修复圆柱 cull 问题 mapbox amap 不同 * feat: 图层销毁时的内存泄漏 * style: lint style * feat: 平面弧线新增弧线偏移量的数据映射能力 * style: lint style * fix: 修复重复销毁bug * style: lint style * feat: 修复 texture 重复销毁问题 * style: lint style * fix: 修复图层叠加模式下的拾取失效问题 * style: lint style * fix: 修复纹理贴图在 zoom 大于 12 时存在的问题 * fix: 修复水波点颜色偏暗 * feat: 优化点图层的渲染效果,叠加渲染效果 * style: lint style * fix: 修复 layer contextmenu 事件丢失 * fix: 修复 map 类型 resize 失效 * style: lint style * feat: 增加瓦片地图的请求节流 * style: lint style * feat: 优化热力图在 radius 数值比较大时热力点边缘发生裁剪的现象 * style: lint style * fix: 修复resize 后 picking shiqu 拾取失败的问题 --- .../services/interaction/PickingService.ts | 3 + packages/layers/src/heatmap/models/heatmap.ts | 8 +- .../shaders/heatmap_framebuffer_vert.glsl | 2 +- .../layers/src/imagetile/models/imagetile.ts | 25 ++- .../Map/components/amap2demo_markerlayer.tsx | 18 +-- stories/Map/components/slider.tsx | 145 ++++++++++++++++++ stories/Map/index.css | 3 + stories/Map/map.stories.tsx | 3 +- 8 files changed, 179 insertions(+), 28 deletions(-) create mode 100644 stories/Map/components/slider.tsx create mode 100644 stories/Map/index.css diff --git a/packages/core/src/services/interaction/PickingService.ts b/packages/core/src/services/interaction/PickingService.ts index 1321611df6..eb4ba979a3 100644 --- a/packages/core/src/services/interaction/PickingService.ts +++ b/packages/core/src/services/interaction/PickingService.ts @@ -189,6 +189,7 @@ export default class PickingService implements IPickingService { ); width *= DOM.DPR; height *= DOM.DPR; + if (this.width !== width || this.height !== height) { this.pickingFBO.resize({ width: Math.round(width / this.pickBufferScale), @@ -205,6 +206,7 @@ export default class PickingService implements IPickingService { clear, getContainer, } = this.rendererService; + this.resizePickingFBO(); useFramebuffer(this.pickingFBO, () => { const layers = this.layerService.getRenderList(); @@ -238,6 +240,7 @@ export default class PickingService implements IPickingService { ); width *= DOM.DPR; height *= DOM.DPR; + const { enableHighlight, enableSelect } = layer.getLayerConfig(); const xInDevicePixel = x * DOM.DPR; diff --git a/packages/layers/src/heatmap/models/heatmap.ts b/packages/layers/src/heatmap/models/heatmap.ts index 902809264c..0345de46ac 100644 --- a/packages/layers/src/heatmap/models/heatmap.ts +++ b/packages/layers/src/heatmap/models/heatmap.ts @@ -16,8 +16,8 @@ import { HeatmapTriangulation } from '../../core/triangulation'; import heatmap3DFrag from '../shaders/heatmap_3d_frag.glsl'; import heatmap3DVert from '../shaders/heatmap_3d_vert.glsl'; import heatmapColorFrag from '../shaders/heatmap_frag.glsl'; -import heatmapFrag from '../shaders/heatmap_framebuffer_frag.glsl'; -import heatmapVert from '../shaders/heatmap_framebuffer_vert.glsl'; +import heatmapFramebufferFrag from '../shaders/heatmap_framebuffer_frag.glsl'; +import heatmapFramebufferVert from '../shaders/heatmap_framebuffer_vert.glsl'; import heatmapColorVert from '../shaders/heatmap_vert.glsl'; import { heatMap3DTriangulation } from '../triangulation'; interface IHeatMapLayerStyleOptions { @@ -154,8 +154,8 @@ export default class HeatMapModel extends BaseModel { private buildHeatMapIntensity(): IModel { return this.layer.buildLayerModel({ moduleName: 'heatmapintensity', - vertexShader: heatmapVert, - fragmentShader: heatmapFrag, + vertexShader: heatmapFramebufferVert, + fragmentShader: heatmapFramebufferFrag, triangulation: HeatmapTriangulation, depth: { enable: false, diff --git a/packages/layers/src/heatmap/shaders/heatmap_framebuffer_vert.glsl b/packages/layers/src/heatmap/shaders/heatmap_framebuffer_vert.glsl index d91149ffce..17a395b93a 100644 --- a/packages/layers/src/heatmap/shaders/heatmap_framebuffer_vert.glsl +++ b/packages/layers/src/heatmap/shaders/heatmap_framebuffer_vert.glsl @@ -19,7 +19,7 @@ void main(){ float extrude_x = a_Dir.x * 2.0 -1.0; float extrude_y = a_Dir.y * 2.0 -1.0; vec2 extrude_dir = normalize(vec2(extrude_x,extrude_y)); - float S = sqrt(-2.0 * log(ZERO / a_Size / u_intensity / GAUSS_COEF)) / 3.0; + float S = sqrt(-2.0 * log(ZERO / a_Size / u_intensity / GAUSS_COEF)) / 2.5; v_extrude = extrude_dir * S; vec2 offset = project_pixel(v_extrude * u_radius); diff --git a/packages/layers/src/imagetile/models/imagetile.ts b/packages/layers/src/imagetile/models/imagetile.ts index bb8c6f3386..19218d2b48 100644 --- a/packages/layers/src/imagetile/models/imagetile.ts +++ b/packages/layers/src/imagetile/models/imagetile.ts @@ -13,6 +13,7 @@ interface IImageLayerStyleOptions { export default class ImageTileModel extends BaseModel { public tileLayer: any; + private timestamp: number | null; public getUninforms(): IModelUniform { return {}; } @@ -56,20 +57,18 @@ export default class ImageTileModel extends BaseModel { // TODO: 首次加载的时候请求瓦片 this.tile(); - let t = new Date().getTime(); - this.mapService.on('mapchange', () => { - const newT = new Date().getTime(); - const cutT = newT - t; - t = newT; - // TODO: 限制刷新频率 - if (cutT < 16) { - return; + this.mapService.on('mapchange', (e) => { + if (this.timestamp) { + clearTimeout(this.timestamp); + this.timestamp = null; } - // TODO: 瓦片地图最大层级为 2 - if (this.mapService.getZoom() < 2.0) { - return; - } - this.tile(); + // @ts-ignore 节流 + this.timestamp = setTimeout(() => { + // TODO: 瓦片地图最大层级为 2 + if (this.mapService.getZoom() >= 2.0) { + this.tile(); + } + }, 500); }); } diff --git a/stories/Map/components/amap2demo_markerlayer.tsx b/stories/Map/components/amap2demo_markerlayer.tsx index ee834558b9..b10dc5dcc0 100644 --- a/stories/Map/components/amap2demo_markerlayer.tsx +++ b/stories/Map/components/amap2demo_markerlayer.tsx @@ -62,15 +62,15 @@ export default class Amap2demo_markerlayer extends React.Component { // }) let f = 0; - setInterval(() => { - if (f === 0) { - markerLayer.hide(); - f = 1; - } else { - markerLayer.show(); - f = 0; - } - }, 800); + // setInterval(() => { + // if (f === 0) { + // markerLayer.hide(); + // f = 1; + // } else { + // markerLayer.show(); + // f = 0; + // } + // }, 800); this.scene = scene; } diff --git a/stories/Map/components/slider.tsx b/stories/Map/components/slider.tsx new file mode 100644 index 0000000000..cfb5a9e101 --- /dev/null +++ b/stories/Map/components/slider.tsx @@ -0,0 +1,145 @@ +// @ts-ignore +import { PointLayer, Scene, ILayer } from '@antv/l7'; +import { GaodeMap, GaodeMapV2 } from '@antv/l7-maps'; +import * as React from 'react'; +import '../index.css'; +import { animate, easeInOut } from 'popmotion'; + +const mapCenter = [121.107846, 30.267069] as [number, number]; + +export default class Slider extends React.Component { + // @ts-ignore + private scene: Scene; + public pointLayer: ILayer; + public isShow: boolean = false; + public slider: HTMLElement; + public sliderWidth: number; + public sliderRight: number = 20; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + this.slider = document.getElementById('sliderwrap') as HTMLElement; + + this.sliderWidth = this.slider.getBoundingClientRect().width; + + const scene = new Scene({ + id: 'map', + map: new GaodeMapV2({ + center: mapCenter, + pitch: 0, + style: 'normal', + zoom: 20, + animateEnable: false, + }), + }); + + this.pointLayer = new PointLayer() + .source( + [ + { + lng: 121.107846, + lat: 30.267069, + }, + { + lng: 121.107, + lat: 30.267069, + }, + ], + { + parser: { + type: 'json', + x: 'lng', + y: 'lat', + }, + }, + ) + .shape('circle') + .color('blue') + .size(10); + scene.on('loaded', () => { + scene.addLayer(this.pointLayer); + + scene.setCenter(mapCenter, { + padding: [0, this.sliderWidth + this.sliderRight, 0, 0], + }); + + scene.render(); + }); + + this.scene = scene; + } + + public triggle() { + const lastPaddingRight = this.sliderWidth + this.sliderRight; + this.isShow = !this.isShow; + if (this.slider) { + this.slider.style.right = this.isShow ? '20px' : `-${this.sliderWidth}px`; + this.sliderRight = this.isShow ? 20 : -this.sliderWidth; + + const currentPaddingRight = this.sliderWidth + this.sliderRight; + + animate({ + from: { + v: lastPaddingRight, + }, + to: { + v: currentPaddingRight, + }, + ease: easeInOut, + duration: 500, + onUpdate: (o) => { + this.scene.setCenter(mapCenter, { padding: [0, o.v, 0, 0] }); + }, + }); + } + } + + public render() { + return ( + <> +
+