From 7f6f07462c564c73c2ddb2c5e352efe80f9a9db4 Mon Sep 17 00:00:00 2001 From: YiQianYao <42212176+2912401452@users.noreply.github.com> Date: Mon, 25 Oct 2021 16:44:37 +0800 Subject: [PATCH] Shihui dev (#807) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add getModelMatrix into viewport * feat: 新增地球模式 (初步构建) * feat: 完善地球交互 * style: lint style * feat: 调整地球图层缩放的方向 * style: lint style * feat: 增加地球模式的 pointLayer/fill 图层 * style: lint style * feat: 增加地球、太阳的简单运动系统,优化部分代码结构 * fix: 修复时间点击出错 * style: lint style * fix: 修复地图 panBy 方法参数错误 * style: lint style * feat: pointLayer/cylinder 圆柱兼容地球模式 * style: lint style * feat: 修复 pointLayer/fill 在拾取是破面严重的情况 * style: lint style * feat: 增加 arc 弧度调节 * feat: 增加 lineLayer/arc3d 兼容地球模式 * style: lint style * feat: 增加地球图层 - 大气层 * style: lint style * feat: 增加设置可视化层背景色的能力 * style: lint style * feat: 增加地球外发光效果 * style: lint style * feat: 允许用户不使用 layer 的 source 方法 - 地球模式下光晕图层不需要传数据 * style: lint style * feat: 调整光晕的 shader 计算 * feat: 调整地球大气层的渲染层级 * style: lint style * feat: 调整案例 * style: lint style * feat: 增加地球图层的默认参数、调整部分代码 * style: lint style * fix: 修复 amap2 新增样式导致的 marker 失效 * feat: 修复 amap2 的 amap-maps 新增 z-index=0; 引发的marker 显示层级失效 * feat: amap2 的 amap-maps 新增 z-index=0; 样式,让 marker 中 zIndex 失效 * style: lint style * chore: update version 2.5.36 -> 2.5.37 * feat: 增加 demo * style: lint style * feat: 修复 varying 传递 float 总数在部分终端设备 ios13 上突破限制的问题 * chore: update version 2.5.37 -> 2.5.38 * feat: add stoty demo * style: lint style * feat: 调整 aspace demo --- lerna.json | 2 +- packages/component/package.json | 6 +- packages/core/package.json | 4 +- .../core/src/services/layer/ILayerService.ts | 21 +- packages/l7/package.json | 14 +- packages/l7/src/version.ts | 2 +- packages/layers/package.json | 8 +- packages/map/package.json | 4 +- packages/maps/package.json | 8 +- packages/renderer/package.json | 4 +- packages/scene/package.json | 14 +- packages/source/package.json | 6 +- packages/three/package.json | 8 +- packages/three/src/core/baseLayer.ts | 6 +- packages/three/src/core/threeRender.ts | 2 +- packages/utils/package.json | 2 +- stories/3D_Model/Components/aspace.tsx | 446 ++++++++++++++++++ stories/3D_Model/model.stories.tsx | 5 +- 18 files changed, 510 insertions(+), 52 deletions(-) create mode 100644 stories/3D_Model/Components/aspace.tsx diff --git a/lerna.json b/lerna.json index 21b84e337b..61df34e506 100644 --- a/lerna.json +++ b/lerna.json @@ -14,7 +14,7 @@ "message": "chore: publish" } }, - "version": "2.5.37", + "version": "2.5.38", "npmClient": "yarn", "useWorkspaces": true, "publishConfig": { diff --git a/packages/component/package.json b/packages/component/package.json index 0a21dc8988..7fc3322ea3 100644 --- a/packages/component/package.json +++ b/packages/component/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-component", - "version": "2.5.37", + "version": "2.5.38", "description": "", "main": "lib/index.js", "module": "es/index.js", @@ -25,8 +25,8 @@ "author": "lzxue", "license": "ISC", "dependencies": { - "@antv/l7-core": "^2.5.37", - "@antv/l7-utils": "^2.5.37", + "@antv/l7-core": "^2.5.38", + "@antv/l7-utils": "^2.5.38", "@babel/runtime": "^7.7.7", "eventemitter3": "^4.0.0", "inversify": "^5.0.1", diff --git a/packages/core/package.json b/packages/core/package.json index 031b641207..b635599515 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-core", - "version": "2.5.37", + "version": "2.5.38", "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.37", + "@antv/l7-utils": "^2.5.38", "@babel/runtime": "^7.7.7", "@mapbox/tiny-sdf": "^1.1.1", "ajv": "^6.10.2", diff --git a/packages/core/src/services/layer/ILayerService.ts b/packages/core/src/services/layer/ILayerService.ts index 6afbafd9dc..ce6ebe5b02 100644 --- a/packages/core/src/services/layer/ILayerService.ts +++ b/packages/core/src/services/layer/ILayerService.ts @@ -124,6 +124,16 @@ export interface ILayer { options?: ISourceCFG; }; multiPassRenderer: IMultiPassRenderer; + + /** + * threejs 适配兼容相关的方法 + * @param lnglat + * @param altitude + * @param rotation + * @param scale + */ + + threeRenderService?: any; needPick(type: string): boolean; getLayerConfig(): Partial; getContainer(): Container; @@ -220,14 +230,6 @@ export interface ILayer { setAnimateStartTime(): void; getLayerAnimateTime(): number; - /** - * threejs 适配兼容相关的方法 - * @param lnglat - * @param altitude - * @param rotation - * @param scale - */ - // 获取对应地图的经纬度模型矩阵 getModelMatrix?( lnglat: ILngLat, @@ -260,6 +262,9 @@ export interface ILayer { // 增加加载模型的动画混合器 addAnimateMixer?(mixer: any): void; + // 返回当前的 threejs camera + getRenderCamera?(): any; + /** * 地球模式相关的方法 */ diff --git a/packages/l7/package.json b/packages/l7/package.json index e031cd3e58..9ab550fa34 100644 --- a/packages/l7/package.json +++ b/packages/l7/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7", - "version": "2.5.37", + "version": "2.5.38", "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.37", - "@antv/l7-core": "^2.5.37", - "@antv/l7-layers": "^2.5.37", - "@antv/l7-maps": "^2.5.37", - "@antv/l7-scene": "^2.5.37", - "@antv/l7-utils": "^2.5.37", + "@antv/l7-component": "^2.5.38", + "@antv/l7-core": "^2.5.38", + "@antv/l7-layers": "^2.5.38", + "@antv/l7-maps": "^2.5.38", + "@antv/l7-scene": "^2.5.38", + "@antv/l7-utils": "^2.5.38", "@babel/runtime": "^7.7.7" }, "gitHead": "684ba4eb806a798713496d3fc0b4d1e17517dc31", diff --git a/packages/l7/src/version.ts b/packages/l7/src/version.ts index 594cdf69fd..23a5c69f1b 100644 --- a/packages/l7/src/version.ts +++ b/packages/l7/src/version.ts @@ -1,2 +1,2 @@ -const version = '2.5.37'; +const version = '2.5.38'; export { version }; diff --git a/packages/layers/package.json b/packages/layers/package.json index 0ddf0fbf74..38f70ada7c 100644 --- a/packages/layers/package.json +++ b/packages/layers/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-layers", - "version": "2.5.37", + "version": "2.5.38", "description": "L7's collection of built-in layers", "main": "lib/index.js", "module": "es/index.js", @@ -24,9 +24,9 @@ "license": "ISC", "dependencies": { "@antv/async-hook": "^2.1.0", - "@antv/l7-core": "^2.5.37", - "@antv/l7-source": "^2.5.37", - "@antv/l7-utils": "^2.5.37", + "@antv/l7-core": "^2.5.38", + "@antv/l7-source": "^2.5.38", + "@antv/l7-utils": "^2.5.38", "@babel/runtime": "^7.7.7", "@mapbox/martini": "^0.2.0", "@turf/meta": "^6.0.2", diff --git a/packages/map/package.json b/packages/map/package.json index 72ce53a7c8..2f35a5627e 100644 --- a/packages/map/package.json +++ b/packages/map/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-map", - "version": "2.5.37", + "version": "2.5.38", "description": "l7 map", "keywords": [], "author": "thinkinggis ", @@ -37,7 +37,7 @@ }, "homepage": "https://github.com/antvis/L7#readme", "dependencies": { - "@antv/l7-utils": "^2.5.37", + "@antv/l7-utils": "^2.5.38", "@babel/runtime": "^7.7.7", "@mapbox/point-geometry": "^0.1.0", "@mapbox/unitbezier": "^0.0.0", diff --git a/packages/maps/package.json b/packages/maps/package.json index 9d0c3df89c..dc81308b54 100644 --- a/packages/maps/package.json +++ b/packages/maps/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-maps", - "version": "2.5.37", + "version": "2.5.38", "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.37", - "@antv/l7-map": "^2.5.37", - "@antv/l7-utils": "^2.5.37", + "@antv/l7-core": "^2.5.38", + "@antv/l7-map": "^2.5.38", + "@antv/l7-utils": "^2.5.38", "@babel/runtime": "^7.7.7", "@types/amap-js-api": "^1.4.6", "@types/mapbox-gl": "^1.11.2", diff --git a/packages/renderer/package.json b/packages/renderer/package.json index 27bf340f05..ba26836307 100644 --- a/packages/renderer/package.json +++ b/packages/renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-renderer", - "version": "2.5.37", + "version": "2.5.38", "description": "", "main": "lib/index.js", "module": "es/index.js", @@ -26,7 +26,7 @@ "gl": "^4.4.0" }, "dependencies": { - "@antv/l7-core": "^2.5.37", + "@antv/l7-core": "^2.5.38", "@babel/runtime": "^7.7.7", "inversify": "^5.0.1", "l7regl": "^0.0.14", diff --git a/packages/scene/package.json b/packages/scene/package.json index 814d4b378f..2ed702fed5 100644 --- a/packages/scene/package.json +++ b/packages/scene/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-scene", - "version": "2.5.37", + "version": "2.5.38", "description": "", "main": "lib/index.js", "module": "es/index.js", @@ -23,12 +23,12 @@ "author": "xiaoiver", "license": "ISC", "dependencies": { - "@antv/l7-component": "^2.5.37", - "@antv/l7-core": "^2.5.37", - "@antv/l7-layers": "^2.5.37", - "@antv/l7-maps": "^2.5.37", - "@antv/l7-renderer": "^2.5.37", - "@antv/l7-utils": "^2.5.37", + "@antv/l7-component": "^2.5.38", + "@antv/l7-core": "^2.5.38", + "@antv/l7-layers": "^2.5.38", + "@antv/l7-maps": "^2.5.38", + "@antv/l7-renderer": "^2.5.38", + "@antv/l7-utils": "^2.5.38", "@babel/runtime": "^7.7.7", "inversify": "^5.0.1", "mapbox-gl": "^1.2.1", diff --git a/packages/source/package.json b/packages/source/package.json index 62a5d93a20..6d78325e59 100644 --- a/packages/source/package.json +++ b/packages/source/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-source", - "version": "2.5.37", + "version": "2.5.38", "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.37", - "@antv/l7-utils": "^2.5.37", + "@antv/l7-core": "^2.5.38", + "@antv/l7-utils": "^2.5.38", "@babel/runtime": "^7.7.7", "@mapbox/geojson-rewind": "^0.4.0", "@turf/helpers": "^6.1.4", diff --git a/packages/three/package.json b/packages/three/package.json index 57f32c73b7..76910257e7 100644 --- a/packages/three/package.json +++ b/packages/three/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-three", - "version": "2.5.37", + "version": "2.5.38", "description": "three for L7 ", "keywords": [ "3D", @@ -44,9 +44,9 @@ }, "homepage": "https://github.com/antvis/L7#readme", "dependencies": { - "@antv/l7-core": "^2.5.37", - "@antv/l7-layers": "^2.5.37", - "@antv/l7-scene": "^2.5.37", + "@antv/l7-core": "^2.5.38", + "@antv/l7-layers": "^2.5.38", + "@antv/l7-scene": "^2.5.38", "@babel/runtime": "^7.7.7", "inversify": "^5.0.1", "reflect-metadata": "^0.1.13", diff --git a/packages/three/src/core/baseLayer.ts b/packages/three/src/core/baseLayer.ts index 08261e39f2..e6a2cad022 100644 --- a/packages/three/src/core/baseLayer.ts +++ b/packages/three/src/core/baseLayer.ts @@ -23,7 +23,7 @@ export default class ThreeJSLayer }> implements ILayer { public type: string = 'custom'; - protected threeRenderService: IThreeRenderService; + public threeRenderService: IThreeRenderService; // 构建 threejs 的 scene private scene: Scene = new Scene(); private renderer: WebGLRenderer; @@ -198,6 +198,10 @@ export default class ThreeJSLayer return this; } + public getRenderCamera() { + return this.threeRenderService.getRenderCamera(); + } + public addAnimateMixer(mixer: AnimationMixer) { this.animateMixer.push(mixer); } diff --git a/packages/three/src/core/threeRender.ts b/packages/three/src/core/threeRender.ts index 97ebc6f33d..a2f679ee09 100644 --- a/packages/three/src/core/threeRender.ts +++ b/packages/three/src/core/threeRender.ts @@ -6,7 +6,7 @@ import { } from './threeRenderService'; export default class ThreeRender { - private threeRenderService: IThreeRenderService; + public threeRenderService: IThreeRenderService; constructor(scene: Scene) { const sceneContainer = scene.getServiceContainer(); sceneContainer diff --git a/packages/utils/package.json b/packages/utils/package.json index 6f7b35f5bb..522c178a29 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-utils", - "version": "2.5.37", + "version": "2.5.38", "description": "", "main": "lib/index.js", "module": "es/index.js", diff --git a/stories/3D_Model/Components/aspace.tsx b/stories/3D_Model/Components/aspace.tsx new file mode 100644 index 0000000000..8cd07ea3fb --- /dev/null +++ b/stories/3D_Model/Components/aspace.tsx @@ -0,0 +1,446 @@ +// @ts-ignore +import { Scene, AMap } 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'; +// tslint:disable-next-line:no-submodule-imports +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; +import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'; +import { animate, easeInOut } from 'popmotion'; +interface IView { + lng: number; + lat: number; + pitch: number; + rotation: number; + zoom: number; +} +function changeValue( + startValue: number | IView, + endValue: number | IView, + duration: number = 500, + callback: any, + complete?: any, +) { + if (typeof startValue === 'number') { + animate({ + from: { + v: startValue, + }, + to: { + v: endValue, + }, + ease: easeInOut, + duration, + onUpdate: (o) => { + callback(o.v); + }, + onComplete: () => { + complete && complete(); + }, + }); + } else { + animate({ + from: { + lng: startValue.lng, + lat: startValue.lat, + pitch: startValue.pitch, + rotation: startValue.rotation, + zoom: startValue.zoom, + }, + to: { + lng: (endValue as IView).lng, + lat: (endValue as IView).lat, + pitch: (endValue as IView).pitch, + rotation: (endValue as IView).rotation, + zoom: (endValue as IView).zoom, + }, + ease: easeInOut, + duration, + onUpdate: (o) => { + callback(o); + }, + onComplete: () => { + complete && complete(); + }, + }); + } +} +export default class Aspace extends React.Component { + // @ts-ignore + private scene: Scene; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + const raycaster = new THREE.Raycaster(); + let lng = 120.1; + let lat = 30.265; + + const scene = new Scene({ + id: 'map', + map: new GaodeMap({ + center: [lng, lat], + pitch: 70, + rotation: 220, + zoom: 16, + }), + }); + this.scene = scene; + scene.registerRenderService(ThreeRender); + + let mouse = new THREE.Vector2(); + let zspace: THREE.Object3D, + aspace: THREE.Object3D, + ASpaceTextMesh: THREE.Object3D, + ZSpaceTextMesh: THREE.Object3D; + scene.on('loaded', () => { + const center = scene.getCenter(); + + const threeJSLayer = new ThreeLayer({ + enableMultiPassRenderer: false, + // @ts-ignore + onAddMeshes: (threeScene: THREE.Scene, layer: ThreeLayer) => { + threeScene.add(new THREE.AmbientLight(0xffffff)); + const sunlight = new THREE.DirectionalLight(0xffffff, 0.25); + sunlight.position.set(0, 80000000, 100000000); + sunlight.matrixWorldNeedsUpdate = true; + threeScene.add(sunlight); + + // map + // https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*gA0NRbuOF5cAAAAAAAAAAAAAARQnAQ + + // height + // https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*eYFaRYlnnOUAAAAAAAAAAAAAARQnAQ + + let image = new Image(); + image.crossOrigin = ''; + image.src = + 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*eYFaRYlnnOUAAAAAAAAAAAAAARQnAQ'; + image.onload = () => { + let canvas: HTMLCanvasElement = document.createElement('canvas'); + canvas.width = image.width; + canvas.height = image.height; + let ctx = canvas.getContext('2d') as CanvasRenderingContext2D; + ctx.drawImage(image, 0, 0, image.width, image.height); + let heightData = ctx.getImageData(0, 0, image.width, image.height) + .data; + + let s = 53000; + + var geometry = new THREE.PlaneGeometry(s, s, 255, 255); + + geometry.vertices.map((v, i) => { + let r = heightData[i * 4]; + let g = heightData[i * 4 + 1]; + let b = heightData[i * 4 + 2]; + + let h = + -10000.0 + + (r * 255.0 * 256.0 * 256.0 + g * 255.0 * 256.0 + b * 255.0) * + 0.1; + h = h / 20 - 127600; + h = Math.max(0, h); + + v.z = h; + }); + var material = new THREE.MeshPhongMaterial({ + transparent: true, + // opacity: 0.6, + map: new THREE.TextureLoader().load( + 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*gA0NRbuOF5cAAAAAAAAAAAAAARQnAQ', + ), + }); + var plane = new THREE.Mesh(geometry, material); + layer.setObjectLngLat(plane, [120.1008, 30.2573], 0); + plane.position.z = 10; + threeScene.add(plane); + }; + + // 使用 Three.js glTFLoader 加载模型 + const loader = new GLTFLoader(); + loader.load( + 'https://gw.alipayobjects.com/os/bmw-prod/3ca0a546-92d8-4ba0-a89c-017c218d5bea.gltf', + (gltf) => { + const antModel = gltf.scene; + layer.adjustMeshToMap(antModel); + layer.setMeshScale(antModel, 20, 20, 20); + + layer.setObjectLngLat( + antModel, + [center.lng - 0.002, center.lat], + 0, + ); + + const animations = gltf.animations; + if (animations && animations.length) { + const mixer = new THREE.AnimationMixer(antModel); + + const animation = animations[1]; + + const action = mixer.clipAction(animation); + + action.play(); + + layer.addAnimateMixer(mixer); + } + antModel.rotation.y = Math.PI; + // 向场景中添加模型 + threeScene.add(antModel); + // 重绘图层 + layer.render(); + }, + ); + + let v = ` + varying vec2 vUv; + varying vec4 worldPosition; + void main() { + vUv = uv; + worldPosition = modelMatrix * vec4(position, 1.0); + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + }`; + let f = ` + varying vec2 vUv; + varying vec4 worldPosition; + uniform vec3 color; + void main() { + gl_FragColor = vec4(color, fract(worldPosition.z / 50.0)); + }`; + let shadermaterial = new THREE.ShaderMaterial({ + uniforms: { + color: { + value: new THREE.Vector3(0.21372549, 0.34705882, 0.56470588), + }, + }, + vertexShader: v, + fragmentShader: f, + }); + + let fbxLoaded = new FBXLoader(); + // load ZSpace + fbxLoaded.load( + 'https://gw.alipayobjects.com/os/bmw-prod/af1652c9-3c4f-4e73-ac4c-1f78fefbaf6a.fbx', + (gltf) => { + zspace = gltf; + layer.adjustMeshToMap(zspace); + // @ts-ignore + zspace.children[0].material = shadermaterial; + layer.setMeshScale(zspace, 10, 10, 10); + + layer.setObjectLngLat(zspace, [120.1015, 30.2661], 0); + zspace.rotation.x = Math.PI * 2; + zspace.rotation.z = -Math.PI * (-2 / 15); + threeScene.add(zspace); + }, + ); + + fbxLoaded.load( + 'https://gw.alipayobjects.com/os/bmw-prod/11d6e4c1-bd5b-4dc1-bae5-ac51c14e9056.fbx', + (model) => { + aspace = model; + layer.adjustMeshToMap(aspace); + // @ts-ignore + aspace.children[0].material = shadermaterial; + + layer.setMeshScale(aspace, 8, 8, 8); + layer.setObjectLngLat(aspace, [120.099, 30.261], 0); + aspace.rotation.x = Math.PI * 2; + aspace.rotation.z = -Math.PI * (3 / 15); + threeScene.add(aspace); + }, + ); + + let textLoader = new THREE.FontLoader(); + textLoader.load( + 'https://gw.alipayobjects.com/os/bmw-prod/0a3f46eb-294e-4d95-87f2-052c26ad4bf1.json', + (font) => { + let aspaceGeo = new THREE.TextGeometry('ASpace', { + size: 360, //字号大小,一般为大写字母的高度 + height: 50, //文字的厚度 + font: font, //字体,默认是'helvetiker',需对应引用的字体文件 + bevelThickness: 10, //倒角厚度 + bevelSize: 10, //倒角宽度 + curveSegments: 30, //弧线分段数,使得文字的曲线更加光滑 + bevelEnabled: true, //布尔值,是否使用倒角,意为在边缘处斜切 + }); + aspaceGeo.center(); + let zspaceGeo = new THREE.TextGeometry('ZSpace', { + size: 360, //字号大小,一般为大写字母的高度 + height: 50, //文字的厚度 + font: font, //字体,默认是'helvetiker',需对应引用的字体文件 + bevelThickness: 10, //倒角厚度 + bevelSize: 10, //倒角宽度 + curveSegments: 30, //弧线分段数,使得文字的曲线更加光滑 + bevelEnabled: true, //布尔值,是否使用倒角,意为在边缘处斜切 + }); + zspaceGeo.center(); + + let fontMat = new THREE.MeshPhongMaterial({ + color: 0xcccccc, + shininess: 60, + specular: 0xcccccc, + }); + + const testHeight = 900; + + ASpaceTextMesh = new THREE.Mesh(aspaceGeo, fontMat); + ASpaceTextMesh.rotation.x = Math.PI / 2; + ASpaceTextMesh.rotation.y = (-Math.PI * 3) / 4; + layer.setObjectLngLat( + ASpaceTextMesh, + [120.099, 30.261], + testHeight, + ); + threeScene.add(ASpaceTextMesh); + + ZSpaceTextMesh = new THREE.Mesh(zspaceGeo, fontMat); + ZSpaceTextMesh.rotation.x = Math.PI / 2; + ZSpaceTextMesh.rotation.y = (-Math.PI * 3) / 4; + layer.setObjectLngLat( + ZSpaceTextMesh, + [120.103, 30.2661], + testHeight, + ); + threeScene.add(ZSpaceTextMesh); + + getH(0, 200); + function getH(h1: number, h2: number) { + changeValue( + h1, + h2, + 1000, + (h: number) => { + ASpaceTextMesh.position.z = testHeight + h; + ZSpaceTextMesh.position.z = testHeight + h; + }, + () => { + setTimeout(() => getH(h2, h1), 10); + }, + ); + } + }, + ); + }, + }) + .source({ + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: {}, + geometry: { + type: 'Point', + coordinates: [111.4453125, 32.84267363195431], + }, + }, + ], + }) + .animate(true); + scene.addLayer(threeJSLayer); + // @ts-ignore + let currentCamera = threeJSLayer.threeRenderService.getRenderCamera(); + let currentView: IView = { + lng: center.lng, + lat: center.lat, + pitch: 70, + rotation: 220, + zoom: 16, + }; + + scene.on('zoom', () => { + let cen = scene.getCenter(); + currentView.lng = cen.lng; + currentView.lat = cen.lat; + currentView.pitch = scene.getPitch(); + currentView.zoom = scene.getZoom(); + }); + // @ts-ignore + scene?.map?.on('camerachange', (e: any) => { + // @ts-ignore + currentCamera = threeJSLayer.threeRenderService.getRenderCamera(); + currentView.pitch = scene.getPitch(); + }); + + let ASpaceView = { + lng: 120.108009, + lat: 30.251129, + pitch: 83, + rotation: 225, + zoom: 16, + }; + let ZSpaceView = { + lng: 120.110726, + lat: 30.256481, + pitch: 80, + rotation: 220, + zoom: 16, + }; + + scene.on('click', (ev) => { + // @ts-ignore + let size = scene?.map?.getSize(); + mouse.x = (ev.pixel.x / size.width) * 2 - 1; + mouse.y = -(ev.pixel.y / size.height) * 2 + 1; + raycaster.setFromCamera(mouse, currentCamera); + var intersects = raycaster.intersectObjects([zspace, aspace], true); + if (intersects.length > 0) { + let object = intersects[0].object; + if (object.name === 'Z空间') { + selectSpace(currentView, ZSpaceView, ZSpaceTextMesh); + } else { + selectSpace(currentView, ASpaceView, ASpaceTextMesh); + } + } + }); + + function selectSpace( + currentView: IView, + targetView: IView, + spaceText?: THREE.Object3D, + ) { + if (spaceText) { + changeValue( + spaceText.rotation.y, + spaceText.rotation.y + Math.PI * 2, + 500, + (r: number) => { + spaceText.rotation.y = r; + }, + ); + } + + changeValue(currentView, targetView, 500, (view: IView) => { + scene.setCenter([view.lng, view.lat]); + scene.setPitch(view.pitch); + scene.setRotation(view.rotation); + scene.setZoom(view.zoom); + + currentView.lng = view.lng; + currentView.lat = view.lat; + currentView.pitch = view.pitch; + currentView.rotation = view.rotation; + currentView.zoom = view.zoom; + }); + } + }); + } + + public render() { + return ( +
+ ); + } +} diff --git a/stories/3D_Model/model.stories.tsx b/stories/3D_Model/model.stories.tsx index 3a335f8e01..027b997adf 100644 --- a/stories/3D_Model/model.stories.tsx +++ b/stories/3D_Model/model.stories.tsx @@ -5,8 +5,11 @@ import AMap2Model from './Components/amap2_three'; import MapboxModel from './Components/mapbox_three'; import ThreeRender from './Components/threeRender'; +import Aspace from './Components/aspace'; + storiesOf('3D 模型', module) .add('ThreeJS Render', () => , {}) .add('高德模型1.x', () => , {}) .add('高德模型2.x', () => , {}) - .add('Mapbox模型', () => , {}); + .add('Mapbox模型', () => , {}) + .add('Aspace', () => , {});