From 963213c9fa230900ade86888c4a5d138c74711c2 Mon Sep 17 00:00:00 2001 From: Smiley <448158628@qq.com> Date: Mon, 3 Jun 2024 11:01:08 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat:gltf=E5=BC=B9=E7=AA=97=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=B8=89=E7=BB=B4=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../packages/ThreeGltf/ThreeGltf.vue | 48 ++- .../packages/ThreeLayer/CSS3DRenderer.js | 322 ++++++++++++++++++ .../packages/ThreeLayer/CustomThreeLayer.ts | 27 +- .../packages/ThreeLayer/ThreeLayer.vue | 6 +- test/views/three/Gltf.vue | 6 +- 5 files changed, 382 insertions(+), 27 deletions(-) create mode 100644 src/vue-amap-extra/packages/ThreeLayer/CSS3DRenderer.js diff --git a/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue b/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue index 16c76af..9c8a5af 100644 --- a/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue +++ b/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue @@ -1,7 +1,12 @@ @@ -12,6 +17,7 @@ import CustomThreeGltf from "./CustomThreeGltf"; import type { MoveAnimation, Vec, ConfigLoader } from "./Type"; import type { PropType, ComponentInternalInstance } from "vue"; import { CSS2DObject } from "../ThreeLayer/CSS2DRenderer"; +import { CSS3DObject } from "../ThreeLayer/CSS3DRenderer"; const popupRef = ref(); defineOptions({ @@ -61,6 +67,11 @@ const props = defineProps( type: Number, default: 0, }, + popupScale: { + //三维弹窗的缩放比例 + type: [Number, Array], + default: 1, + }, }) ); const emits = defineEmits([ @@ -73,7 +84,7 @@ const emits = defineEmits([ let $amapComponent: CustomThreeGltf; -let popup: CSS2DObject; +let popup: CSS2DObject | CSS3DObject; const currentInstance = getCurrentInstance(); @@ -115,15 +126,30 @@ const { $$getInstance, parentInstance } = useRegister( ); const addPopup = (instance: CustomThreeGltf) => { - const cssRender = instance.layer?.cssRenderer; - if (cssRender == undefined) return; + const cssRenderType = instance?.layer?.cssRenderType; + if (cssRenderType === undefined) return; + const cssRender = instance?.layer?.cssRenderer; + if (cssRender === undefined) return; const element = popupRef.value as HTMLDivElement; - const css2dObject = new CSS2DObject(element); - css2dObject.center.set(0.5, 1); - css2dObject.translateY(props.popupHeight || 0); - popup = css2dObject; - popup.visible = props.showPopup; - instance.object.add(popup); + if (cssRenderType === "2D") { + const css2dObject = new CSS2DObject(element); + css2dObject.center.set(0.5, 1); + css2dObject.translateY(props.popupHeight || 0); + popup = css2dObject; + popup.visible = props.showPopup; + instance.object.add(popup); + } else if (cssRenderType === "3D") { + const scales = + typeof props.popupScale === "number" + ? [props.popupScale, props.popupScale, props.popupScale] + : props.popupScale; + const css3DObject = new CSS3DObject(element); + css3DObject.translateY(props.popupHeight || 0); + css3DObject.scale.set(scales[0], scales[1], scales[2]); + popup = css3DObject; + popup.visible = props.showPopup; + instance.object.add(popup); + } }; const $$startAnimations = () => { diff --git a/src/vue-amap-extra/packages/ThreeLayer/CSS3DRenderer.js b/src/vue-amap-extra/packages/ThreeLayer/CSS3DRenderer.js new file mode 100644 index 0000000..28ad64e --- /dev/null +++ b/src/vue-amap-extra/packages/ThreeLayer/CSS3DRenderer.js @@ -0,0 +1,322 @@ +import { Matrix4, Object3D, Quaternion, Vector3 } from 'three'; + +/** + * Based on http://www.emagix.net/academic/mscs-project/item/camera-sync-with-css3-and-webgl-threejs + */ + +const _position = new Vector3(); +const _quaternion = new Quaternion(); +const _scale = new Vector3(); + +class CSS3DObject extends Object3D { + constructor(element = document.createElement('div')) { + super(); + + this.isCSS3DObject = true; + + this.element = element; + this.element.style.position = 'absolute'; + this.element.style.pointerEvents = 'auto'; + this.element.style.userSelect = 'none'; + + this.element.setAttribute('draggable', false); + + this.addEventListener('removed', function () { + this.traverse(function (object) { + if (object.element instanceof Element && object.element.parentNode !== null) { + object.element.parentNode.removeChild(object.element); + } + }); + }); + } + + copy(source, recursive) { + super.copy(source, recursive); + + this.element = source.element.cloneNode(true); + + return this; + } +} + +class CSS3DSprite extends CSS3DObject { + constructor(element) { + super(element); + + this.isCSS3DSprite = true; + + this.rotation2D = 0; + } + + copy(source, recursive) { + super.copy(source, recursive); + + const self = this; + + self.rotation2D = source.rotation2D; + + return this; + } +} + +// + +const _matrix = new Matrix4(); +const _matrix2 = new Matrix4(); + +class CSS3DRenderer { + constructor(parameters = {}) { + const _this = this; + + let _width, _height; + let _widthHalf, _heightHalf; + + const cache = { + camera: { style: '' }, + objects: new WeakMap(), + }; + + const domElement = + parameters.element !== undefined ? parameters.element : document.createElement('div'); + + domElement.style.overflow = 'hidden'; + + this.domElement = domElement; + + const viewElement = document.createElement('div'); + viewElement.style.transformOrigin = '0 0'; + viewElement.style.pointerEvents = 'none'; + domElement.appendChild(viewElement); + + const cameraElement = document.createElement('div'); + + cameraElement.style.transformStyle = 'preserve-3d'; + + viewElement.appendChild(cameraElement); + + this.getSize = function () { + return { + width: _width, + height: _height, + }; + }; + + this.render = function (scene, camera) { + const fov = camera.projectionMatrix.elements[5] * _heightHalf; + + if (camera.view && camera.view.enabled) { + // view offset + viewElement.style.transform = `translate( ${ + -camera.view.offsetX * (_width / camera.view.width) + }px, ${-camera.view.offsetY * (_height / camera.view.height)}px )`; + + // view fullWidth and fullHeight, view width and height + viewElement.style.transform += `scale( ${camera.view.fullWidth / camera.view.width}, ${ + camera.view.fullHeight / camera.view.height + } )`; + } else { + viewElement.style.transform = ''; + } + + if (scene.matrixWorldAutoUpdate === true) scene.updateMatrixWorld(); + if (camera.parent === null && camera.matrixWorldAutoUpdate === true) + camera.updateMatrixWorld(); + + let tx, ty; + + if (camera.isOrthographicCamera) { + tx = -(camera.right + camera.left) / 2; + ty = (camera.top + camera.bottom) / 2; + } + + const scaleByViewOffset = + camera.view && camera.view.enabled ? camera.view.height / camera.view.fullHeight : 1; + const cameraCSSMatrix = camera.isOrthographicCamera + ? `scale( ${scaleByViewOffset} )` + + 'scale(' + + fov + + ')' + + 'translate(' + + epsilon(tx) + + 'px,' + + epsilon(ty) + + 'px)' + + getCameraCSSMatrix(camera.matrixWorldInverse) + : `scale( ${scaleByViewOffset} )` + + 'translateZ(' + + fov + + 'px)' + + getCameraCSSMatrix(camera.matrixWorldInverse); + const perspective = camera.isPerspectiveCamera ? 'perspective(' + fov + 'px) ' : ''; + + const style = + perspective + cameraCSSMatrix + 'translate(' + _widthHalf + 'px,' + _heightHalf + 'px)'; + + if (cache.camera.style !== style) { + cameraElement.style.transform = style; + + cache.camera.style = style; + } + + renderObject(scene, scene, camera, cameraCSSMatrix); + }; + + this.setSize = function (width, height) { + _width = width; + _height = height; + _widthHalf = _width / 2; + _heightHalf = _height / 2; + + domElement.style.width = width + 'px'; + domElement.style.height = height + 'px'; + + viewElement.style.width = width + 'px'; + viewElement.style.height = height + 'px'; + + cameraElement.style.width = width + 'px'; + cameraElement.style.height = height + 'px'; + }; + + function epsilon(value) { + return Math.abs(value) < 1e-10 ? 0 : value; + } + + function getCameraCSSMatrix(matrix) { + const elements = matrix.elements; + + return ( + 'matrix3d(' + + epsilon(elements[0]) + + ',' + + epsilon(-elements[1]) + + ',' + + epsilon(elements[2]) + + ',' + + epsilon(elements[3]) + + ',' + + epsilon(elements[4]) + + ',' + + epsilon(-elements[5]) + + ',' + + epsilon(elements[6]) + + ',' + + epsilon(elements[7]) + + ',' + + epsilon(elements[8]) + + ',' + + epsilon(-elements[9]) + + ',' + + epsilon(elements[10]) + + ',' + + epsilon(elements[11]) + + ',' + + epsilon(elements[12]) + + ',' + + epsilon(-elements[13]) + + ',' + + epsilon(elements[14]) + + ',' + + epsilon(elements[15]) + + ')' + ); + } + + function getObjectCSSMatrix(matrix) { + const elements = matrix.elements; + const matrix3d = + 'matrix3d(' + + epsilon(elements[0]) + + ',' + + epsilon(elements[1]) + + ',' + + epsilon(elements[2]) + + ',' + + epsilon(elements[3]) + + ',' + + epsilon(-elements[4]) + + ',' + + epsilon(-elements[5]) + + ',' + + epsilon(-elements[6]) + + ',' + + epsilon(-elements[7]) + + ',' + + epsilon(elements[8]) + + ',' + + epsilon(elements[9]) + + ',' + + epsilon(elements[10]) + + ',' + + epsilon(elements[11]) + + ',' + + epsilon(elements[12]) + + ',' + + epsilon(elements[13]) + + ',' + + epsilon(elements[14]) + + ',' + + epsilon(elements[15]) + + ')'; + + return 'translate(-50%,-50%)' + matrix3d; + } + + function renderObject(object, scene, camera, cameraCSSMatrix) { + if (object.isCSS3DObject) { + const visible = object.visible === true && object.layers.test(camera.layers) === true; + object.element.style.display = visible === true ? '' : 'none'; + + if (visible === true) { + object.onBeforeRender(_this, scene, camera); + + let style; + + if (object.isCSS3DSprite) { + // http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/ + + _matrix.copy(camera.matrixWorldInverse); + _matrix.transpose(); + + if (object.rotation2D !== 0) + _matrix.multiply(_matrix2.makeRotationZ(object.rotation2D)); + + object.matrixWorld.decompose(_position, _quaternion, _scale); + _matrix.setPosition(_position); + _matrix.scale(_scale); + + _matrix.elements[3] = 0; + _matrix.elements[7] = 0; + _matrix.elements[11] = 0; + _matrix.elements[15] = 1; + + style = getObjectCSSMatrix(_matrix); + } else { + style = getObjectCSSMatrix(object.matrixWorld); + } + + const element = object.element; + const cachedObject = cache.objects.get(object); + + if (cachedObject === undefined || cachedObject.style !== style) { + element.style.transform = style; + + const objectData = { style: style }; + cache.objects.set(object, objectData); + } + + if (element.parentNode !== cameraElement) { + cameraElement.appendChild(element); + } + + object.onAfterRender(_this, scene, camera); + } + } + + for (let i = 0, l = object.children.length; i < l; i++) { + renderObject(object.children[i], scene, camera, cameraCSSMatrix); + } + } + } +} + +export { CSS3DObject, CSS3DSprite, CSS3DRenderer }; diff --git a/src/vue-amap-extra/packages/ThreeLayer/CustomThreeLayer.ts b/src/vue-amap-extra/packages/ThreeLayer/CustomThreeLayer.ts index ca87abc..5205f1e 100644 --- a/src/vue-amap-extra/packages/ThreeLayer/CustomThreeLayer.ts +++ b/src/vue-amap-extra/packages/ThreeLayer/CustomThreeLayer.ts @@ -21,12 +21,13 @@ import type { Texture, Camera, WebGLRenderer, Scene, Object3D } from "three"; import type { HDROptions, LightOption } from "./Type"; import type { ThreeLayerOptions } from "@vuemap/three-layer"; import { CSS2DRenderer } from "./CSS2DRenderer"; +import { CSS3DRenderer } from "./CSS3DRenderer"; interface Options extends ThreeLayerOptions { lights?: LightOption[]; // 灯光数组 hdr?: HDROptions; // 开启HDR配置 axesHelper: boolean; // 是否开启箭头,用于debug,默认不开启 - createCssRender?: boolean; //是否创建CssRender + cssRenderType?: "2D" | "3D"; //CSSRender类型,未赋值时不创建 } class CustomThreeLayer extends ThreeLayer { @@ -50,7 +51,8 @@ class CustomThreeLayer extends ThreeLayer { passList = [] as any[]; clock = new Clock(); preHoverGroup = null as Object3D | null; - cssRenderer = null as CSS2DRenderer | null; + cssRenderer = null as CSS2DRenderer | CSS3DRenderer | null; + cssRenderType = undefined as "2D" | "3D" | undefined; constructor(map: any, options: Options, callback: () => void) { options.onInit = (render, scene) => { @@ -60,7 +62,8 @@ class CustomThreeLayer extends ThreeLayer { scene.add(axesHelper); } this.renderer?.setPixelRatio(window.devicePixelRatio); - if (options.createCssRender) this.creatCssRender(map); + if (options.cssRenderType) + this.creatCssRender(map, options.cssRenderType); this.createEffect(); this.createLights(options.lights || []); this.createHDR(options.hdr); @@ -99,13 +102,17 @@ class CustomThreeLayer extends ThreeLayer { // this.effectComposer.addPass(renderPass); } - creatCssRender(map: any) { - const element = map.getContainer().querySelector(".amap-markers"); - this.cssRenderer = new CSS2DRenderer(); - this.cssRenderer.domElement.style.position = "absolute"; - this.cssRenderer.domElement.style.left = "0"; - this.cssRenderer.domElement.style.top = "0"; - element.appendChild(this.cssRenderer.domElement); + creatCssRender(map: any, type: "2D" | "3D") { + this.cssRenderType = type; + if (type == "2D") this.cssRenderer = new CSS2DRenderer(); + else if (type == "3D") this.cssRenderer = new CSS3DRenderer(); + if (this.cssRenderer) { + this.cssRenderer.domElement.style.position = "absolute"; + this.cssRenderer.domElement.style.left = "0"; + this.cssRenderer.domElement.style.top = "0"; + const element = map.getContainer().querySelector(".amap-markers"); + element.appendChild(this.cssRenderer.domElement); + } } addPass(pass: any) { diff --git a/src/vue-amap-extra/packages/ThreeLayer/ThreeLayer.vue b/src/vue-amap-extra/packages/ThreeLayer/ThreeLayer.vue index 025496c..b610e89 100644 --- a/src/vue-amap-extra/packages/ThreeLayer/ThreeLayer.vue +++ b/src/vue-amap-extra/packages/ThreeLayer/ThreeLayer.vue @@ -74,9 +74,9 @@ defineProps( return undefined; }, }, - createCssRender: { - type: Boolean, - default: false, + cssRenderType: { + type: String as PropType<"2D" | "3D" | undefined>, + default: undefined, }, }) ); diff --git a/test/views/three/Gltf.vue b/test/views/three/Gltf.vue index 7240b63..eb874c9 100644 --- a/test/views/three/Gltf.vue +++ b/test/views/three/Gltf.vue @@ -20,7 +20,7 @@ :alpha="true" :antialias="true" :create-canvas="false" - :create-css-render="true" + css-render-type="3D" @init="initLayer" @click="clickLayer" @mouseover="mouseoverLayer" @@ -71,7 +71,8 @@ :rotation="rotation" :move-animation="moveAnimation" :show-popup="true" - :popup-height="1" + :popup-height="2" + :popupScale="0.1" @init="initCar" >
Date: Mon, 3 Jun 2024 11:25:38 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feat:gltf=E5=BC=B9=E7=AA=97=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B=E4=BB=A3=E7=A0=81=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../packages/ThreeGltf/ThreeGltf.vue | 12 +- test/router/index.ts | 1 + test/views/three/Gltf.vue | 64 ++-- test/views/three/Gltf_Popup.vue | 283 ++++++++++++++++++ 4 files changed, 319 insertions(+), 41 deletions(-) create mode 100644 test/views/three/Gltf_Popup.vue diff --git a/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue b/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue index 9c8a5af..7e68455 100644 --- a/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue +++ b/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue @@ -68,7 +68,7 @@ const props = defineProps( default: 0, }, popupScale: { - //三维弹窗的缩放比例 + //三维弹窗的缩放比例(只有在threelayer的cssRenderType为3D时生效) type: [Number, Array], default: 1, }, @@ -181,4 +181,14 @@ watch( } } ); + +watch( + () => props.popupScale, + (val) => { + if (popup && val) { + const scales = typeof val === "number" ? [val, val, val] : val; + popup.scale.set(scales[0], scales[1], scales[2]); + } + } +); diff --git a/test/router/index.ts b/test/router/index.ts index 18464d3..1d004ac 100644 --- a/test/router/index.ts +++ b/test/router/index.ts @@ -43,6 +43,7 @@ export const routes = [ {path: '/vector/rectangle',name: 'vector矩形', component: () => import('../views/vector/Rectangle.vue')}, {path: '/layer/tiles3D',name: '3DTiles图层', component: () => import('../views/layer/Tiles3D.vue')}, {path: '/three/gltf',name: 'ThreeJS Gltf示例', component: () => import('../views/three/Gltf.vue')}, + {path: '/three/gltf_popup',name: 'ThreeJS Gltf示例(Popup)', component: () => import('../views/three/Gltf_Popup.vue')}, {path: '/three/threeVideo',name: 'ThreeJS 视频', component: () => import('../views/three/ThreeVideo.vue')}, {path: '/three/polygon',name: 'ThreeJS面图层', component: () => import('../views/three/Polygon.vue')}, {path: '/three/3dtiles',name: 'ThreeJS 3Dtiles图层', component: () => import('../views/three/Tiles3d.vue')}, diff --git a/test/views/three/Gltf.vue b/test/views/three/Gltf.vue index eb874c9..7a0bbf0 100644 --- a/test/views/three/Gltf.vue +++ b/test/views/three/Gltf.vue @@ -20,7 +20,6 @@ :alpha="true" :antialias="true" :create-canvas="false" - css-render-type="3D" @init="initLayer" @click="clickLayer" @mouseover="mouseoverLayer" @@ -70,23 +69,8 @@ :angle="carAngle" :rotation="rotation" :move-animation="moveAnimation" - :show-popup="true" - :popup-height="2" - :popupScale="0.1" @init="initCar" > -
- 测试三维信息弹窗 -
+
+ + + + + + + + + +
+ 测试GLTF信息弹窗(CSS3DRenderer) +
+
+
+ + + + + + + + +
+ 测试GLTF信息弹窗(CSS2DRenderer) +
+
+
+
+
+ + {{ visible ? "隐藏" : "显示" }} + + 停止动画 + 开始动画 + 停止车辆 + 移动车辆 +
+
+ + + + + -- Gitee From ad75dd63acfd529663cef9a0808d22471fe668fe Mon Sep 17 00:00:00 2001 From: Smiley <448158628@qq.com> Date: Tue, 4 Jun 2024 09:22:07 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat:threeLayer=E5=90=8C=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81css2dRenderer=E5=92=8Ccss3dRenderer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../packages/ThreeGltf/ThreeGltf.vue | 14 +++--- .../packages/ThreeLayer/CustomThreeLayer.ts | 45 ++++++++++--------- .../packages/ThreeLayer/ThreeLayer.vue | 6 +-- test/views/three/Gltf_Popup.vue | 26 +---------- 4 files changed, 38 insertions(+), 53 deletions(-) diff --git a/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue b/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue index 7e68455..840edab 100644 --- a/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue +++ b/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue @@ -72,6 +72,10 @@ const props = defineProps( type: [Number, Array], default: 1, }, + popupType:{//信息弹窗类型 + type:String as PropType<'2D'|'3D'>, + default:'2D' + } }) ); const emits = defineEmits([ @@ -126,19 +130,17 @@ const { $$getInstance, parentInstance } = useRegister( ); const addPopup = (instance: CustomThreeGltf) => { - const cssRenderType = instance?.layer?.cssRenderType; - if (cssRenderType === undefined) return; - const cssRender = instance?.layer?.cssRenderer; - if (cssRender === undefined) return; const element = popupRef.value as HTMLDivElement; - if (cssRenderType === "2D") { + const content = element.querySelector('.content-container'); + debugger; + if (props.popupType === "2D") { const css2dObject = new CSS2DObject(element); css2dObject.center.set(0.5, 1); css2dObject.translateY(props.popupHeight || 0); popup = css2dObject; popup.visible = props.showPopup; instance.object.add(popup); - } else if (cssRenderType === "3D") { + } else if (props.popupType === "3D") { const scales = typeof props.popupScale === "number" ? [props.popupScale, props.popupScale, props.popupScale] diff --git a/src/vue-amap-extra/packages/ThreeLayer/CustomThreeLayer.ts b/src/vue-amap-extra/packages/ThreeLayer/CustomThreeLayer.ts index 5205f1e..b8c349c 100644 --- a/src/vue-amap-extra/packages/ThreeLayer/CustomThreeLayer.ts +++ b/src/vue-amap-extra/packages/ThreeLayer/CustomThreeLayer.ts @@ -27,7 +27,7 @@ interface Options extends ThreeLayerOptions { lights?: LightOption[]; // 灯光数组 hdr?: HDROptions; // 开启HDR配置 axesHelper: boolean; // 是否开启箭头,用于debug,默认不开启 - cssRenderType?: "2D" | "3D"; //CSSRender类型,未赋值时不创建 + createCssRender: boolean; //是否创建CSSRender } class CustomThreeLayer extends ThreeLayer { @@ -51,8 +51,8 @@ class CustomThreeLayer extends ThreeLayer { passList = [] as any[]; clock = new Clock(); preHoverGroup = null as Object3D | null; - cssRenderer = null as CSS2DRenderer | CSS3DRenderer | null; - cssRenderType = undefined as "2D" | "3D" | undefined; + css2DRenderer = null as CSS2DRenderer | null; + css3DRenderer = null as CSS3DRenderer | null; constructor(map: any, options: Options, callback: () => void) { options.onInit = (render, scene) => { @@ -62,8 +62,7 @@ class CustomThreeLayer extends ThreeLayer { scene.add(axesHelper); } this.renderer?.setPixelRatio(window.devicePixelRatio); - if (options.cssRenderType) - this.creatCssRender(map, options.cssRenderType); + if (options.createCssRender) this.creatCssRenders(map); this.createEffect(); this.createLights(options.lights || []); this.createHDR(options.hdr); @@ -77,7 +76,8 @@ class CustomThreeLayer extends ThreeLayer { this.effectComposer?.render(this.clock.getDelta()); } else { this.renderer?.render(this.scene as Scene, camera as Camera); - this.cssRenderer?.render(this.scene as Scene, camera as Camera); + this.css2DRenderer?.render(this.scene as Scene, camera as Camera); + this.css3DRenderer?.render(this.scene as Scene, camera as Camera); } }; super(map, options); @@ -88,7 +88,8 @@ class CustomThreeLayer extends ThreeLayer { if (this.effectComposer && this.renderer) { const size = this.renderer.getSize(new Vector2()); this.effectComposer.setSize(size.x, size.y); - this.cssRenderer?.setSize(size.x, size.y); + this.css2DRenderer?.setSize(size.x, size.y); + this.css3DRenderer?.setSize(size.x, size.y); } } @@ -96,23 +97,26 @@ class CustomThreeLayer extends ThreeLayer { const size = this.renderer?.getSize(new Vector2()); this.effectComposer = new EffectComposer(this.renderer as WebGLRenderer); this.effectComposer.setSize(size?.x as number, size?.y as number); - this.cssRenderer?.setSize(size?.x as number, size?.y as number); + this.css2DRenderer?.setSize(size?.x as number, size?.y as number); + this.css3DRenderer?.setSize(size?.x as number, size?.y as number); // const renderPass = new ThreeRenderPass( this.scene, this.camera ); // this.renderPass = renderPass; // this.effectComposer.addPass(renderPass); } - creatCssRender(map: any, type: "2D" | "3D") { - this.cssRenderType = type; - if (type == "2D") this.cssRenderer = new CSS2DRenderer(); - else if (type == "3D") this.cssRenderer = new CSS3DRenderer(); - if (this.cssRenderer) { - this.cssRenderer.domElement.style.position = "absolute"; - this.cssRenderer.domElement.style.left = "0"; - this.cssRenderer.domElement.style.top = "0"; - const element = map.getContainer().querySelector(".amap-markers"); - element.appendChild(this.cssRenderer.domElement); - } + creatCssRenders(map: any) { + this.css2DRenderer = new CSS2DRenderer(); + this.css2DRenderer.domElement.style.position = "absolute"; + this.css2DRenderer.domElement.style.left = "0"; + this.css2DRenderer.domElement.style.top = "0"; + + this.css3DRenderer = new CSS3DRenderer(); + this.css3DRenderer.domElement.style.position = "absolute"; + this.css3DRenderer.domElement.style.left = "0"; + this.css3DRenderer.domElement.style.top = "0"; + const element = map.getContainer().querySelector(".amap-markers"); + element.appendChild(this.css2DRenderer.domElement); + element.appendChild(this.css3DRenderer.domElement); } addPass(pass: any) { @@ -338,7 +342,8 @@ class CustomThreeLayer extends ThreeLayer { this.envMap.dispose(); this.envMap = null; } - this.cssRenderer?.domElement?.remove(); + this.css2DRenderer?.domElement?.remove(); + this.css3DRenderer?.domElement?.remove(); super.destroy(); this.lightTypes = null as any; this.raycaster = undefined; diff --git a/src/vue-amap-extra/packages/ThreeLayer/ThreeLayer.vue b/src/vue-amap-extra/packages/ThreeLayer/ThreeLayer.vue index b610e89..025496c 100644 --- a/src/vue-amap-extra/packages/ThreeLayer/ThreeLayer.vue +++ b/src/vue-amap-extra/packages/ThreeLayer/ThreeLayer.vue @@ -74,9 +74,9 @@ defineProps( return undefined; }, }, - cssRenderType: { - type: String as PropType<"2D" | "3D" | undefined>, - default: undefined, + createCssRender: { + type: Boolean, + default: false, }, }) ); diff --git a/test/views/three/Gltf_Popup.vue b/test/views/three/Gltf_Popup.vue index a830f31..2257b3f 100644 --- a/test/views/three/Gltf_Popup.vue +++ b/test/views/three/Gltf_Popup.vue @@ -21,7 +21,7 @@ @click="clickLayer" @mouseover="mouseoverLayer" @mouseout="mouseoutLayer" - css-render-type="3D" + :create-css-render="true" >
- - - - - - - Date: Tue, 4 Jun 2024 09:43:49 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat:=E5=AE=8C=E5=96=84=E7=A4=BA=E4=BE=8B?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../packages/ThreeGltf/ThreeGltf.vue | 5 +- test/views/three/Gltf_Popup.vue | 48 +++++++++---------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue b/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue index a8228cd..989f5e4 100644 --- a/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue +++ b/src/vue-amap-extra/packages/ThreeGltf/ThreeGltf.vue @@ -13,7 +13,6 @@