Shihui dev (#848)

* feat: 增加 threejs 案例和方法

* style: lint style

* feat: 优化点图层,水波纹点的拾取
This commit is contained in:
YiQianYao 2021-11-23 19:58:30 +08:00 committed by GitHub
parent 86c5f97534
commit 49fba466c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 228 additions and 106 deletions

View File

@ -14,7 +14,7 @@
"message": "chore: publish"
}
},
"version": "2.5.56",
"version": "2.5.57",
"npmClient": "yarn",
"useWorkspaces": true,
"publishConfig": {

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-component",
"version": "2.5.56",
"version": "2.5.57",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -25,8 +25,8 @@
"author": "lzxue",
"license": "ISC",
"dependencies": {
"@antv/l7-core": "^2.5.56",
"@antv/l7-utils": "^2.5.56",
"@antv/l7-core": "^2.5.57",
"@antv/l7-utils": "^2.5.57",
"@babel/runtime": "^7.7.7",
"eventemitter3": "^4.0.0",
"inversify": "^5.0.1",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-core",
"version": "2.5.56",
"version": "2.5.57",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -24,7 +24,7 @@
"license": "ISC",
"dependencies": {
"@antv/async-hook": "^2.1.0",
"@antv/l7-utils": "^2.5.56",
"@antv/l7-utils": "^2.5.57",
"@babel/runtime": "^7.7.7",
"ajv": "^6.10.2",
"element-resize-event": "^3.0.3",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7",
"version": "2.5.56",
"version": "2.5.57",
"description": "A Large-scale WebGL-powered Geospatial Data Visualization",
"main": "lib/index.js",
"module": "es/index.js",
@ -25,12 +25,12 @@
"author": "antv",
"license": "MIT",
"dependencies": {
"@antv/l7-component": "^2.5.56",
"@antv/l7-core": "^2.5.56",
"@antv/l7-layers": "^2.5.56",
"@antv/l7-maps": "^2.5.56",
"@antv/l7-scene": "^2.5.56",
"@antv/l7-utils": "^2.5.56",
"@antv/l7-component": "^2.5.57",
"@antv/l7-core": "^2.5.57",
"@antv/l7-layers": "^2.5.57",
"@antv/l7-maps": "^2.5.57",
"@antv/l7-scene": "^2.5.57",
"@antv/l7-utils": "^2.5.57",
"@babel/runtime": "^7.7.7"
},
"gitHead": "684ba4eb806a798713496d3fc0b4d1e17517dc31",

View File

@ -1,2 +1,2 @@
const version = '2.5.56';
const version = '2.5.57';
export { version };

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-layers",
"version": "2.5.56",
"version": "2.5.57",
"description": "L7's collection of built-in layers",
"main": "lib/index.js",
"module": "es/index.js",
@ -24,9 +24,9 @@
"license": "ISC",
"dependencies": {
"@antv/geo-coord": "^1.0.8",
"@antv/l7-core": "^2.5.56",
"@antv/l7-source": "^2.5.56",
"@antv/l7-utils": "^2.5.56",
"@antv/l7-core": "^2.5.57",
"@antv/l7-source": "^2.5.57",
"@antv/l7-utils": "^2.5.57",
"@babel/runtime": "^7.7.7",
"@mapbox/martini": "^0.2.0",
"@turf/meta": "^6.0.2",

View File

@ -98,10 +98,12 @@ void main() {
float d = length(v_data.xy);
float intensity = clamp(cos(d * PI), 0.0, 1.0) * clamp(cos(2.0 * PI * (d * 2.0 * u_aimate.z - u_aimate.y * u_time)), 0.0, 1.0);
gl_FragColor = vec4(gl_FragColor.xyz, intensity);
// TODO: 优化在水波纹情况下的拾取a == 0 时无法拾取)
if(d < 0.7) {
gl_FragColor.a = max(gl_FragColor.a, 0.001);
}
}
gl_FragColor = filterColor(gl_FragColor);
gl_FragColor = filterColor(gl_FragColor);
}

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-map",
"version": "2.5.56",
"version": "2.5.57",
"description": "l7 map",
"keywords": [],
"author": "thinkinggis <lzx199065@gmail.com>",
@ -37,7 +37,7 @@
},
"homepage": "https://github.com/antvis/L7#readme",
"dependencies": {
"@antv/l7-utils": "^2.5.56",
"@antv/l7-utils": "^2.5.57",
"@babel/runtime": "^7.7.7",
"@mapbox/point-geometry": "^0.1.0",
"@mapbox/unitbezier": "^0.0.0",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-maps",
"version": "2.5.56",
"version": "2.5.57",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -27,9 +27,9 @@
"license": "ISC",
"dependencies": {
"@amap/amap-jsapi-loader": "^0.0.3",
"@antv/l7-core": "^2.5.56",
"@antv/l7-map": "^2.5.56",
"@antv/l7-utils": "^2.5.56",
"@antv/l7-core": "^2.5.57",
"@antv/l7-map": "^2.5.57",
"@antv/l7-utils": "^2.5.57",
"@babel/runtime": "^7.7.7",
"@types/amap-js-api": "^1.4.6",
"@types/mapbox-gl": "^1.11.2",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-mini",
"version": "2.5.56",
"version": "2.5.57",
"description": "A Large-scale WebGL-powered Geospatial Data Visualization",
"main": "lib/index.js",
"module": "es/index.js",
@ -25,11 +25,11 @@
"author": "antv",
"license": "MIT",
"dependencies": {
"@antv/l7-core": "^2.5.56",
"@antv/l7-layers": "^2.5.56",
"@antv/l7-maps": "^2.5.56",
"@antv/l7-scene": "^2.5.56",
"@antv/l7-utils": "^2.5.56",
"@antv/l7-core": "^2.5.57",
"@antv/l7-layers": "^2.5.57",
"@antv/l7-maps": "^2.5.57",
"@antv/l7-scene": "^2.5.57",
"@antv/l7-utils": "^2.5.57",
"@babel/runtime": "^7.7.7"
},
"gitHead": "684ba4eb806a798713496d3fc0b4d1e17517dc31",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-renderer",
"version": "2.5.56",
"version": "2.5.57",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -26,7 +26,7 @@
"gl": "^4.4.0"
},
"dependencies": {
"@antv/l7-core": "^2.5.56",
"@antv/l7-core": "^2.5.57",
"@babel/runtime": "^7.7.7",
"inversify": "^5.0.1",
"l7regl": "^0.0.16",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-scene",
"version": "2.5.56",
"version": "2.5.57",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -23,12 +23,12 @@
"author": "xiaoiver",
"license": "ISC",
"dependencies": {
"@antv/l7-component": "^2.5.56",
"@antv/l7-core": "^2.5.56",
"@antv/l7-layers": "^2.5.56",
"@antv/l7-maps": "^2.5.56",
"@antv/l7-renderer": "^2.5.56",
"@antv/l7-utils": "^2.5.56",
"@antv/l7-component": "^2.5.57",
"@antv/l7-core": "^2.5.57",
"@antv/l7-layers": "^2.5.57",
"@antv/l7-maps": "^2.5.57",
"@antv/l7-renderer": "^2.5.57",
"@antv/l7-utils": "^2.5.57",
"@babel/runtime": "^7.7.7",
"inversify": "^5.0.1",
"mapbox-gl": "^1.2.1",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-source",
"version": "2.5.56",
"version": "2.5.57",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -26,8 +26,8 @@
"license": "ISC",
"dependencies": {
"@antv/async-hook": "^2.1.0",
"@antv/l7-core": "^2.5.56",
"@antv/l7-utils": "^2.5.56",
"@antv/l7-core": "^2.5.57",
"@antv/l7-utils": "^2.5.57",
"@babel/runtime": "^7.7.7",
"@mapbox/geojson-rewind": "^0.4.0",
"@turf/helpers": "^6.1.4",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-three",
"version": "2.5.56",
"version": "2.5.57",
"description": "three for L7 ",
"keywords": [
"3D",
@ -44,9 +44,9 @@
},
"homepage": "https://github.com/antvis/L7#readme",
"dependencies": {
"@antv/l7-core": "^2.5.56",
"@antv/l7-layers": "^2.5.56",
"@antv/l7-scene": "^2.5.56",
"@antv/l7-core": "^2.5.57",
"@antv/l7-layers": "^2.5.57",
"@antv/l7-scene": "^2.5.57",
"@babel/runtime": "^7.7.7",
"inversify": "^5.0.1",
"reflect-metadata": "^0.1.13",

View File

@ -24,6 +24,8 @@ export default class ThreeJSLayer
implements ILayer {
public type: string = 'custom';
public threeRenderService: IThreeRenderService;
public isUpdate: boolean = false;
public update: (() => void) | null = null;
// 构建 threejs 的 scene
private scene: Scene = new Scene();
private renderer: WebGLRenderer;
@ -31,6 +33,11 @@ export default class ThreeJSLayer
// 地图中点墨卡托坐标
private center: IMercator;
public setUpdate(callback: () => void) {
this.update = callback;
this.isUpdate = true;
}
/**
*
*/
@ -154,6 +161,9 @@ export default class ThreeJSLayer
}
}
public renderModels() {
if (this.isUpdate && this.update) {
this.update();
}
// 获取到 L7 的 gl
const gl = this.rendererService.getGLContext();
this.rendererService.setCustomLayerDefaults();

View File

@ -26,6 +26,7 @@ export class ThreeRenderService implements IThreeRenderService {
public camera: Camera;
public center: IMercator;
public aspect: number;
public update: () => void;
private scene: ThreeScene;
// 初始状态相机变换矩阵

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-utils",
"version": "2.5.56",
"version": "2.5.57",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",

View File

@ -3,9 +3,124 @@ import { Scene } from '@antv/l7';
import { GaodeMap, Mapbox } from '@antv/l7-maps';
import { ThreeLayer, ThreeRender } from '@antv/l7-three';
import * as React from 'react';
// import { DirectionalLight, Scene as ThreeScene } from 'three';
import * as THREE from 'three';
const points = [
[120.44353624, 22.44126139],
[120.64050836, 22.24136664],
[120.70155111, 21.92708306],
[120.87288601, 21.89738661],
[120.91492974, 22.30271186],
[121.03327772, 22.65070394],
[121.32468397, 22.94568359],
[121.47954183, 23.3223055],
[121.64384793, 24.09772976],
[121.80915717, 24.33907227],
[121.89250353, 24.6179267],
[121.84504259, 24.83625488],
[122.01220106, 25.00145101],
[121.91709391, 25.13789361],
[121.62302734, 25.29467556],
[121.02468424, 25.04048774],
[120.82376736, 24.68830973],
[120.68867757, 24.60069417],
[120.24576172, 23.84053168],
[120.10276177, 23.70096951],
[120.10784668, 23.34126356],
[120.02320774, 23.10765544],
[120.13473334, 22.99400635],
[120.29720052, 22.53133111],
[120.44353624, 22.44126139],
];
function iniCylinder(size: number, height: number) {
const geometry = new THREE.CylinderGeometry(size, size, height, 32);
const material = new THREE.MeshBasicMaterial({
color: '#0ff',
transparent: true,
opacity: 0.5,
depthTest: false,
});
const cylinder = new THREE.Mesh(geometry, material);
return cylinder;
}
async function initPlane(text: string, src: string) {
return new Promise((resolve, reject) => {
const image = new Image();
image.src = src;
image.crossOrigin = 'none';
image.onload = function() {
const width = image.width;
const height = image.height;
const canvas = document.createElement('canvas');
canvas.width = width * 10;
canvas.height = height * 10;
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
ctx.globalAlpha = 0.4;
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
ctx.globalAlpha = 1;
ctx.fillStyle = 'rgb(30, 160, 30)';
ctx.font = `${canvas.height / 3}px bold PingFang-SC-Bold`;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(text, canvas.width / 2, canvas.height / 2);
const texture = new THREE.CanvasTexture(canvas);
const size = 320000;
const planeGeometry = new THREE.PlaneBufferGeometry(
size,
(size * height) / width,
1,
);
const material = new THREE.MeshBasicMaterial({
color: 0xffff00,
side: THREE.DoubleSide,
map: texture,
blending: THREE.AdditiveBlending,
});
const plane = new THREE.Mesh(planeGeometry, material);
plane.renderOrder = 10;
resolve(plane);
};
});
}
const taiwancity = [
{
// 台北
lng: 121.5,
lat: 25.05,
population: 2602418,
},
{
// 台中
lng: 120.5804443359,
lat: 24.2,
population: 2820787,
},
{
// 台南
lng: 120.193176269531,
lat: 22.9963233068,
population: 1874917,
},
{
// 高雄
lng: 120.30578613281,
lat: 22.62415215809,
population: 2765932,
},
{
// 桃园
lng: 121.15,
lat: 24.9,
population: 2268807,
},
];
export default class Threemap extends React.Component {
// @ts-ignore
private scene: Scene;
@ -18,14 +133,25 @@ export default class Threemap extends React.Component {
const scene = new Scene({
id: 'map',
map: new GaodeMap({
center: [120, 25],
pitch: 65,
rotation: 30,
zoom: 8,
center: [120.5, 24],
pitch: 60,
rotation: 0,
zoom: 8.2,
style: 'dark',
}),
});
this.scene = scene;
scene.registerRenderService(ThreeRender);
const img1 =
'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*zMw0T6gEIZYAAAAAAAAAAAAAARQnAQ';
let plane0 = (await initPlane('台北260.24万', img1)) as THREE.Object3D;
let plane1 = (await initPlane('台中282.07万', img1)) as THREE.Object3D;
let plane2 = (await initPlane('台南187.49万', img1)) as THREE.Object3D;
let plane3 = (await initPlane('高雄276.59万', img1)) as THREE.Object3D;
let plane4 = (await initPlane('桃园266.88万', img1)) as THREE.Object3D;
scene.on('loaded', () => {
const threeJSLayer = new ThreeLayer({
enableMultiPassRenderer: false,
@ -37,44 +163,10 @@ export default class Threemap extends React.Component {
sunlight.matrixWorldNeedsUpdate = true;
threeScene.add(sunlight);
let points = [
[120.44353624, 22.44126139],
[120.64050836, 22.24136664],
[120.70155111, 21.92708306],
[120.87288601, 21.89738661],
[120.91492974, 22.30271186],
[121.03327772, 22.65070394],
[121.32468397, 22.94568359],
[121.47954183, 23.3223055],
[121.64384793, 24.09772976],
[121.80915717, 24.33907227],
[121.89250353, 24.6179267],
[121.84504259, 24.83625488],
[122.01220106, 25.00145101],
[121.91709391, 25.13789361],
[121.62302734, 25.29467556],
[121.02468424, 25.04048774],
[120.82376736, 24.68830973],
[120.68867757, 24.60069417],
[120.24576172, 23.84053168],
[120.10276177, 23.70096951],
[120.10784668, 23.34126356],
[120.02320774, 23.10765544],
[120.13473334, 22.99400635],
[120.29720052, 22.53133111],
[120.44353624, 22.44126139],
];
// @ts-ignore
let lnglatPoints = points.map((p) => layer.lnglatToCoord(p));
// console.log(lnglatPoints)
const shape = new THREE.Shape();
// shape.moveTo( 0,0 );
// shape.lineTo( 0, 100000 );
// shape.lineTo( 100000, 10000 );
// shape.lineTo( 10000, 0 );
// shape.lineTo( 0, 0 );
shape.moveTo(lnglatPoints[0][0], lnglatPoints[0][1]);
for (let i = 1; i < lnglatPoints.length; i++) {
@ -93,9 +185,7 @@ export default class Threemap extends React.Component {
bevelSegments: 1,
};
const v0 = `
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}`;
@ -115,10 +205,9 @@ export default class Threemap extends React.Component {
const f = `
varying vec2 vUv;
// uniform vec3 color;
varying float h;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0 - h/${h}.0);
gl_FragColor = vec4(0.92549, 1.0, 0.91372549, 1.0 - h/${h}.0);
}`;
const material = new THREE.ShaderMaterial({
@ -129,17 +218,6 @@ export default class Threemap extends React.Component {
fragmentShader: f0,
});
const shader_material = new THREE.ShaderMaterial({
uniforms: {
// texture: {
// // 加载纹理贴图返回Texture对象作为texture的值
// // Texture对象对应着色器中sampler2D数据类型变量
// value: new THREE.TextureLoader().load('./Earth.png')
// },
},
depthTest: false,
// depthWrite: false,
// blending: '',
transparent: true,
vertexShader: v,
fragmentShader: f,
@ -148,8 +226,39 @@ export default class Threemap extends React.Component {
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
const mesh = new THREE.Mesh(geometry, [material, shader_material]);
mesh.renderOrder = -1;
threeScene.add(mesh);
let planes = [plane0, plane1, plane2, plane3, plane4];
taiwancity.map(
(item: { lng: number; lat: number; population: number }, index) => {
let cylinderSize = item.population / 50;
let cylinderHeight = item.population / 10;
planes[index].rotation.x = Math.PI / 2;
layer.setObjectLngLat(
planes[index],
[item.lng, item.lat],
cylinderHeight * 1.5,
);
threeScene.add(planes[index]);
let cylinder = iniCylinder(cylinderSize, cylinderHeight);
cylinder.rotation.x = Math.PI / 2;
layer.setObjectLngLat(
cylinder,
[item.lng, item.lat],
cylinderHeight / 2,
);
threeScene.add(cylinder);
},
);
layer.setUpdate(() => {
let z = layer.getRenderCamera().rotation.z;
planes.map((p) => (p.rotation.y = z));
});
},
})
.source({