diff --git a/demos/heatmap.html b/demos/heatmap.html index 23a2d6464a..62a929564f 100644 --- a/demos/heatmap.html +++ b/demos/heatmap.html @@ -25,6 +25,7 @@ const scene = new L7.Scene({ pitch: 0, zoom: 4.5 }); + window.scene = scene; scene.on('loaded', () => { $.get('https://gw.alipayobjects.com/os/basement_prod/08c6ea00-dc5f-4bb0-b0b5-52bde5edf0a3.json', data => { @@ -34,8 +35,8 @@ scene.on('loaded', () => { .source(data) .size('mag', [ 0, 1 ]) // weight映射通道 .style({ - intensity: 3, - radius: 20, + intensity: 2, + radius: 30, rampColors: { colors: [ 'rgba(33,102,172,0.0)', 'rgb(103,169,207)', 'rgb(209,229,240)', 'rgb(253,219,199)', 'rgb(239,138,98)', 'rgb(178,24,43,1.0)' ], positions: [ 0, 0.2, 0.4, 0.6, 0.8, 1.0 ] diff --git a/src/core/layer.js b/src/core/layer.js index a3ea07a668..9d7e3fea00 100644 --- a/src/core/layer.js +++ b/src/core/layer.js @@ -89,8 +89,11 @@ export default class Layer extends Base { const zoom = this.scene.getZoom(); object.material.setUniformsValue('u_time', this.scene._engine.clock.getElapsedTime()); object.material.setUniformsValue('u_zoom', zoom); - this._preRender(); + this.preRender(); + }; + object.onAfterRender = () => { // 每次渲染后改变状态 + this.afterRender(); }; // 更新 if (this._needUpdateFilter) { // 动态更新数据过滤 @@ -121,7 +124,6 @@ export default class Layer extends Base { // }).then(data => { // console.log(data); // }); - return this; } color(field, values) { @@ -632,5 +634,9 @@ export default class Layer extends Base { preRender() { } + + afterRender() { + + } } diff --git a/src/layer/heatmapLayer.js b/src/layer/heatmapLayer.js index e6e1bf5724..203814e5b6 100644 --- a/src/layer/heatmapLayer.js +++ b/src/layer/heatmapLayer.js @@ -2,7 +2,7 @@ import Layer from '../core/layer'; import gridBuffer from '../geom/buffer/heatmap/grid'; import DrawGrid from './render/heatmap/gird'; import DrawHexagon from './render/heatmap/hexagon'; -import drawHeatmap from './render/heatmap/heatmap'; +import { drawHeatmap, updateIntensityPass } from './render/heatmap/heatmap'; import hexagonBuffer from '../geom/buffer/heatmap/hexagon'; export default class HeatMapLayer extends Layer { @@ -56,4 +56,10 @@ export default class HeatMapLayer extends Layer { this.add(girdMesh); } + afterRender() { + if (this.shapeType !== 'grid' || this.shapeType !== 'hexagon') { + updateIntensityPass(this); + } + } + } diff --git a/src/layer/render/heatmap/heatmap.js b/src/layer/render/heatmap/heatmap.js index 07b7bb4cd4..87a5322b7e 100644 --- a/src/layer/render/heatmap/heatmap.js +++ b/src/layer/render/heatmap/heatmap.js @@ -4,8 +4,9 @@ import { HeatmapIntensityMaterial, HeatmapColorizeMaterial } from '../../../geom import Renderpass from '../../../core/engine/renderpass'; import * as THREE from '../../../core/three'; -export default function drawHeatmap(layer) { +export function drawHeatmap(layer) { const bbox = calBoundingBox(layer.layerData); + layer.dataBbox = bbox; const colors = layer.get('styleOptions').rampColors; layer.colorRamp = createColorRamp(colors); createIntensityPass(layer, bbox); @@ -33,15 +34,15 @@ function createIntensityPass(layer, bbox) { zoom: layer.scene.getZoom() }); const mesh = new THREE.Mesh(geometry, material); - // set camera + // set camera const passOrth = new THREE.OrthographicCamera(bbox.width / -2, bbox.width / 2, bbox.height / 2, bbox.height / -2, 1, 10000); passOrth.position.set(bbox.minX + bbox.width / 2, bbox.minY + bbox.height / 2, 1000); - // renderpass + // renderpass const renderer = layer.scene._engine._renderer; // get extension for bilinear texture interpolation:https://threejs.org/docs/#api/en/textures/DataTexture - const gl = renderer.domElement.getContext('webgl') || + /* const gl = renderer.domElement.getContext('webgl') || renderer.domElement.getContext('experimental-webgl'); - gl.getExtension('OES_texture_float_linear'); + gl.getExtension('OES_texture_float_linear');*/ const renderpass = new Renderpass({ renderer, camera: passOrth, @@ -66,18 +67,21 @@ function createIntensityPass(layer, bbox) { renderpass.add(mesh); renderpass.render(); layer.intensityPass = renderpass; - const scene = layer.scene; - render(); - function render() { - requestAnimationFrame(render); - const zoom = scene.getZoom(); - mesh.material.uniforms.u_zoom.value = zoom; - const passWidth = Math.min(10000, Math.pow(zoom, 2.0) * 300); - const passHeight = passWidth * (bbox.height / bbox.width); - renderpass.pass.setSize(passWidth, passHeight); - renderpass.render(); - } + layer.intensityMesh = mesh; + updateIntensityPass(layer); } + +export function updateIntensityPass(layer) { + const mesh = layer.intensityMesh; + const zoom = layer.scene.getZoom(); + const bbox = layer.dataBbox; + mesh.material.uniforms.u_zoom.value = zoom; + const passWidth = Math.min(8000, Math.pow(zoom, 2.0) * 250); + const passHeight = passWidth * (bbox.height / bbox.width); + layer.intensityPass.pass.setSize(passWidth, passHeight); + layer.intensityPass.render(); +} + function createColorizePass(layer, bbox) { // create plane geometry const geometery = new THREE.PlaneBufferGeometry(bbox.width, bbox.height); @@ -108,9 +112,16 @@ function calBoundingBox(data) { maxY = p[1]; } } + + minX -= ((maxX - minX) * 0.5); + maxX += ((maxX - minX) * 0.5); + minY -= ((maxY - minY) * 0.5); + maxY += ((maxY - minY) * 0.5); + const width = maxX - minX; const height = maxY - minY; + return { minX, maxX, @@ -120,4 +131,3 @@ function calBoundingBox(data) { height }; } -