|
@@ -1,44 +1,51 @@
|
|
|
import * as THREE from 'three';
|
|
|
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
|
|
|
// 导入轨道控制器
|
|
|
-import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
|
|
|
-import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer'
|
|
|
+import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
|
|
|
+import { CSS3DRenderer } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
|
|
|
// import gsap from 'gsap';
|
|
|
-import ResourceTracker from '/@/utils/threejs/ResourceTracker';
|
|
|
-import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
|
|
|
-import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
|
|
|
-
|
|
|
-
|
|
|
+import ResourceTracker from '/@/utils/threejs/ResourceTracker.js';
|
|
|
+import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
|
+import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
|
+import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
|
|
|
+import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js';
|
|
|
+import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
|
|
|
+import { setModalCenter } from '/@/utils/threejs/util';
|
|
|
+import Stats from 'three/examples/jsm/libs/stats.module.js';
|
|
|
+import { useModelStore } from '/@/store/modules/threejs';
|
|
|
|
|
|
class UseThree {
|
|
|
- canvasContainer: HTMLCanvasElement;
|
|
|
- CSSCanvasContainer: HTMLCanvasElement | null = null;
|
|
|
- camera: THREE.PerspectiveCamera | null = null;
|
|
|
+ stats: Stats | null = null; // 帧
|
|
|
+ canvasContainer: HTMLCanvasElement | null; //canvas 容器
|
|
|
+ CSSCanvasContainer: HTMLCanvasElement | null = null; // css canvas 容器
|
|
|
+ camera: THREE.PerspectiveCamera | null = null; // 相机
|
|
|
scene: THREE.Scene | null = null;
|
|
|
renderer: THREE.WebGLRenderer | null = null;
|
|
|
css3dRender: CSS3DRenderer | null = null;
|
|
|
orbitControls: OrbitControls | null = null;
|
|
|
- giftLoader: THREE.Object3D | null = null;
|
|
|
- animationMixer: THREE.AnimationMixer | null = null;
|
|
|
animationAction: THREE.AnimationAction | null = null;
|
|
|
- clock: THREE.Clock = new THREE.Clock(); // 计时器
|
|
|
+ clock: THREE.Clock | null = new THREE.Clock(); // 计时器
|
|
|
timeoutId: NodeJS.Timeout | null = null;
|
|
|
- animationId: number = 0
|
|
|
- resourceTracker:ResourceTracker | null = null
|
|
|
- track: any = null
|
|
|
- spriteText: THREE.Sprite | null = null
|
|
|
+ animationId = 0;
|
|
|
+ spriteText: THREE.Sprite | null = null;
|
|
|
+ mouse = new THREE.Vector2();
|
|
|
+ rayCaster: THREE.Raycaster | null = null;
|
|
|
+ animations: THREE.AnimationClip[] = [];
|
|
|
+ mixers: THREE.AnimationMixer[] = [];
|
|
|
+ FPS = 40;
|
|
|
+ timeS = 0;
|
|
|
+ resourceTracker: ResourceTracker | null = null;
|
|
|
+ track: any = null;
|
|
|
+ composer; //后期
|
|
|
|
|
|
constructor(canvasSelector, cssCanvas?) {
|
|
|
-
|
|
|
-
|
|
|
- this.resourceTracker = new ResourceTracker()
|
|
|
- this.track = this.resourceTracker.track.bind(this.resourceTracker)
|
|
|
- this.animationId = 0
|
|
|
+ this.resourceTracker = new ResourceTracker();
|
|
|
+ this.track = this.resourceTracker.track.bind(this.resourceTracker);
|
|
|
+ this.animationId = 0;
|
|
|
this.canvasContainer = document.querySelector(canvasSelector);
|
|
|
-
|
|
|
//初始化
|
|
|
this.init(cssCanvas);
|
|
|
- this.animate();
|
|
|
+ // this.animate();
|
|
|
window.addEventListener('resize', this.resizeRenderer.bind(this));
|
|
|
// 添加滚动事件,鼠标滚动模型执行动画
|
|
|
// window.addEventListener('wheel', this.wheelRenderer.bind(this));
|
|
@@ -47,31 +54,39 @@ class UseThree {
|
|
|
// 初始化场景
|
|
|
this.initScene();
|
|
|
// 初始化环境光
|
|
|
- this.initLight();
|
|
|
+ // this.initLight();
|
|
|
// 初始化相机
|
|
|
this.initCamera();
|
|
|
//初始化渲染器
|
|
|
this.initRenderer();
|
|
|
-
|
|
|
// 初始化控制器
|
|
|
this.initControles();
|
|
|
-
|
|
|
- if(cssCanvas){
|
|
|
- this.initCSSRenderer(cssCanvas)
|
|
|
- // this.addTextSprite()
|
|
|
+ if (cssCanvas) {
|
|
|
+ this.initCSSRenderer(cssCanvas);
|
|
|
}
|
|
|
- // this.setTestPlane()
|
|
|
+ // this.setTestPlane();
|
|
|
+ this.rayCaster = this.track(new THREE.Raycaster());
|
|
|
+ this.createStats();
|
|
|
+ // this.removeSawtooth();
|
|
|
+ }
|
|
|
+
|
|
|
+ createStats() {
|
|
|
+ this.stats = Stats();
|
|
|
+ this.stats?.setMode(0);
|
|
|
+ this.stats.domElement.style.position = 'absolute';
|
|
|
+ this.stats.domElement.style.left = '200px';
|
|
|
+ this.stats.domElement.style.top = '100px';
|
|
|
+ document.body.appendChild(this.stats.domElement);
|
|
|
}
|
|
|
|
|
|
initScene() {
|
|
|
this.scene = this.track(new THREE.Scene());
|
|
|
// const axesHelper = new THREE.AxesHelper(100);
|
|
|
// this.scene?.add(axesHelper);
|
|
|
-
|
|
|
// const size = 1000;
|
|
|
// const divisions = 10;
|
|
|
- // const gridHelper = new THREE.GridHelper( size, divisions );
|
|
|
- // this.scene?.add( gridHelper )
|
|
|
+ // const gridHelper = new THREE.GridHelper(size, divisions);
|
|
|
+ // this.scene?.add(gridHelper);
|
|
|
}
|
|
|
|
|
|
initLight() {
|
|
@@ -81,192 +96,192 @@ class UseThree {
|
|
|
}
|
|
|
|
|
|
initCamera() {
|
|
|
- this.camera = this.track(new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.01, 1000));
|
|
|
- this.camera?.position.set(0, 0.2, 0.3);
|
|
|
- // const helper = new THREE.CameraHelper( this.camera);
|
|
|
- // this.scene?.add( helper );
|
|
|
-
|
|
|
+ this.camera = this.track(new THREE.PerspectiveCamera(50, this.canvasContainer.clientWidth / this.canvasContainer.clientHeight, 0.000001, 10000));
|
|
|
+
|
|
|
+ // const helper = new THREE.CameraHelper(this.camera);
|
|
|
+ // this.scene?.add(helper);
|
|
|
}
|
|
|
|
|
|
initRenderer() {
|
|
|
-
|
|
|
- this.renderer = this.track(new THREE.WebGLRenderer({ antialias: true, alpha:true })) as THREE.WebGLRenderer;
|
|
|
+ this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: true }) as THREE.WebGLRenderer;
|
|
|
// 设置屏幕像素比
|
|
|
this.renderer?.setPixelRatio(window.devicePixelRatio);
|
|
|
// 设置渲染的尺寸
|
|
|
- this.renderer?.setSize(window.innerWidth, window.innerHeight);
|
|
|
+ this.renderer?.setSize(this.canvasContainer.clientWidth, this.canvasContainer.clientHeight);
|
|
|
// 色调映射
|
|
|
this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
|
|
|
|
|
this.renderer.outputEncoding = THREE.sRGBEncoding;
|
|
|
|
|
|
- this.renderer.shadowMap.enabled = true
|
|
|
+ this.renderer.shadowMap.enabled = true;
|
|
|
|
|
|
- this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
|
|
|
+ this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
|
|
|
|
|
// 曝光程度
|
|
|
this.renderer.toneMappingExposure = 1;
|
|
|
|
|
|
- this.canvasContainer.appendChild(this.renderer.domElement);
|
|
|
-
|
|
|
+ this.canvasContainer?.appendChild(this.renderer.domElement);
|
|
|
}
|
|
|
|
|
|
initCSSRenderer(cssCanvas) {
|
|
|
this.CSSCanvasContainer = document.querySelector(cssCanvas);
|
|
|
- this.css3dRender = this.track(new CSS3DRenderer()) as CSS3DRenderer
|
|
|
- this.css3dRender.setSize((window.innerWidth), (window.innerHeight))
|
|
|
- this.CSSCanvasContainer?.appendChild(this.css3dRender.domElement)
|
|
|
- this.css3dRender.render(this.scene as THREE.Scene, this.camera as THREE.PerspectiveCamera)
|
|
|
+ this.css3dRender = this.track(new CSS3DRenderer()) as CSS3DRenderer;
|
|
|
+ this.css3dRender.setSize(this.canvasContainer.clientWidth, this.canvasContainer.clientHeight);
|
|
|
+ this.CSSCanvasContainer?.appendChild(this.css3dRender.domElement);
|
|
|
+ this.css3dRender.render(this.scene as THREE.Scene, this.camera as THREE.PerspectiveCamera);
|
|
|
this.orbitControls = this.track(new OrbitControls(this.camera as THREE.Camera, this.css3dRender?.domElement)) as OrbitControls;
|
|
|
- this.orbitControls.update()
|
|
|
- // this.orbitControls.enableZoom = false;
|
|
|
- // // to disable rotation
|
|
|
- // this.orbitControls.enableRotate = false;
|
|
|
- // // to disable pan
|
|
|
- // this.orbitControls.enablePan = false;
|
|
|
+ this.orbitControls.update();
|
|
|
}
|
|
|
|
|
|
initControles() {
|
|
|
this.orbitControls = this.track(new OrbitControls(this.camera as THREE.Camera, this.renderer?.domElement)) as OrbitControls;
|
|
|
- this.orbitControls.update()
|
|
|
- // this.orbitControls.enableZoom = false;
|
|
|
- // // to disable rotation
|
|
|
- // this.orbitControls.enableRotate = false;
|
|
|
- // // to disable pan
|
|
|
- // this.orbitControls.enablePan = false;
|
|
|
+ this.orbitControls.update();
|
|
|
+ // this.orbitControls.enableDamping = true;
|
|
|
}
|
|
|
|
|
|
- setModalCenter(group) {
|
|
|
- var box3 = new THREE.Box3()
|
|
|
-
|
|
|
- // 计算层级模型group的包围盒
|
|
|
- // 模型group是加载一个三维模型返回的对象,包含多个网格模型
|
|
|
- box3.expandByObject(group)
|
|
|
- // 计算一个层级模型对应包围盒的几何体中心在世界坐标中的位置
|
|
|
- var center = new THREE.Vector3()
|
|
|
- box3.getCenter(center)
|
|
|
- // console.log('查看几何体中心坐标', center);
|
|
|
- // 重新设置模型的位置,使之居中。
|
|
|
- group.position.x = group.position.x - center.x
|
|
|
- group.position.y = group.position.y - center.y
|
|
|
- group.position.z = group.position.z - center.z
|
|
|
- };
|
|
|
-
|
|
|
setModel(modalName) {
|
|
|
- const a = new Date().getTime() / 1000
|
|
|
+ const modelStore = useModelStore();
|
|
|
return new Promise(async (resolve, reject) => {
|
|
|
try {
|
|
|
- const db = window['CustomDB']
|
|
|
- const modalArr = await db.modal.where('modalName').equals(modalName).toArray()
|
|
|
- // debugger
|
|
|
- if(modalArr.length > 0) {
|
|
|
- const modalValue = modalArr[0].modalVal
|
|
|
+ const a = new Date().getTime();
|
|
|
+ let modalValue = modelStore.modelArr.get(modalName);
|
|
|
+ if (!modalValue) {
|
|
|
+ const db = window['CustomDB'];
|
|
|
+ const modalArr = await db.modal.where('modalName').equals(modalName).toArray();
|
|
|
+ modalValue = modalArr[0].modalVal;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (modalValue) {
|
|
|
+ console.log('模型下载速度', new Date().getTime() - a);
|
|
|
+ const b = new Date().getTime();
|
|
|
try {
|
|
|
- const gltfLoader = new GLTFLoader()
|
|
|
- const dracoLoader = new DRACOLoader();
|
|
|
- dracoLoader.setDecoderPath( '/3D/draco/gltf/' );
|
|
|
- dracoLoader.setDecoderConfig({ type: "js" }); //使用兼容性强的draco_decoder.js解码器
|
|
|
+ const gltfLoader = this.track(new GLTFLoader());
|
|
|
+ const dracoLoader = this.track(new DRACOLoader());
|
|
|
+ dracoLoader.setDecoderPath('/model/draco/gltf/');
|
|
|
+ dracoLoader.setDecoderConfig({ type: 'js' }); //使用兼容性强的draco_decoder.js解码器
|
|
|
dracoLoader.preload();
|
|
|
gltfLoader.setDRACOLoader(dracoLoader);
|
|
|
|
|
|
- gltfLoader.setPath('/3d/glft/')
|
|
|
- gltfLoader.parse(modalValue, '/3d/glft/', (gltf) => {
|
|
|
- const object = this.track(gltf.scene.children[0])
|
|
|
- this.setModalCenter(object)
|
|
|
- object.traverse((obj) => {
|
|
|
- if (obj instanceof THREE.Mesh) {
|
|
|
- obj.material.emissiveIntensity = 1
|
|
|
- obj.material.emissiveMap = obj.material.map
|
|
|
- if(obj.name !== "buxiugangse") {
|
|
|
- obj.receiveShadow = true
|
|
|
+ gltfLoader.setPath('/model/glft/');
|
|
|
+ gltfLoader.parse(
|
|
|
+ modalValue,
|
|
|
+ '/model/glft/',
|
|
|
+ (gltf) => {
|
|
|
+ const object = this.track(gltf.scene);
|
|
|
+ setModalCenter(object);
|
|
|
+ object.traverse((obj) => {
|
|
|
+ if (obj instanceof THREE.Mesh) {
|
|
|
+ obj.material.emissiveIntensity = 1;
|
|
|
+ obj.material.emissiveMap = obj.material.map;
|
|
|
+ obj.material.blending = THREE.CustomBlending;
|
|
|
+ if (obj.name !== 'buxiugangse') {
|
|
|
+ obj.receiveShadow = true;
|
|
|
+ }
|
|
|
+ obj.castShadow = true;
|
|
|
}
|
|
|
- obj.castShadow = true
|
|
|
-
|
|
|
-
|
|
|
- } else if (obj.type === 'Object3D') {
|
|
|
- // const text3D = this.addYFText(obj)
|
|
|
- // const textCQ3D = this.addCQText(obj)
|
|
|
- // gltf.scene.add(text3D)
|
|
|
- // gltf.scene.add(textCQ3D)
|
|
|
- }
|
|
|
- })
|
|
|
- this.scene?.add(object);
|
|
|
- console.log(object);
|
|
|
- resolve(object)
|
|
|
- }, (err)=> {
|
|
|
- console.log(err);
|
|
|
-
|
|
|
- })
|
|
|
-
|
|
|
+ });
|
|
|
+ object.name = modalName;
|
|
|
+ this.scene?.add(object);
|
|
|
+ console.log('模型渲染时间', object, new Date().getTime() - b);
|
|
|
+
|
|
|
+ resolve(gltf);
|
|
|
+ dracoLoader.dispose();
|
|
|
+ },
|
|
|
+ (err) => {
|
|
|
+ console.log(err);
|
|
|
+ }
|
|
|
+ );
|
|
|
} catch (error) {
|
|
|
console.log(error);
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
} catch (error) {
|
|
|
- reject('加载模型出错')
|
|
|
+ reject('加载模型出错');
|
|
|
}
|
|
|
- })
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
setTestPlane() {
|
|
|
- const plane = new THREE.Mesh(
|
|
|
- new THREE.PlaneGeometry( 100, 100 ),
|
|
|
- new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } )
|
|
|
- );
|
|
|
- plane.rotation.x = - Math.PI / 2;
|
|
|
- plane.position.y = 0.03;
|
|
|
- plane.receiveShadow = true;
|
|
|
- // this.scene?.add( plane );
|
|
|
+ const plane = this.track(new THREE.Mesh(new THREE.PlaneGeometry(100, 100), new THREE.MeshPhongMaterial({ color: 0x999999, specular: 0x101010 })));
|
|
|
+ plane.rotation.x = -Math.PI / 2;
|
|
|
+ plane.position.y = 0.03;
|
|
|
+ plane.receiveShadow = true;
|
|
|
+ this.scene?.add(plane);
|
|
|
+ }
|
|
|
+
|
|
|
+ removeSawtooth() {
|
|
|
+ this.composer = this.track(new EffectComposer(this.renderer as THREE.WebGLRenderer));
|
|
|
+ const FXAAShaderPass = this.track(new ShaderPass(FXAAShader));
|
|
|
+ FXAAShaderPass.uniforms['resolution'].value.set(1 / this.canvasContainer.clientWidth, 1 / this.canvasContainer.clientHeight);
|
|
|
+ FXAAShaderPass.renderToScreen = true;
|
|
|
+ this.composer.addPass(FXAAShaderPass);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/* 自定义材质 */
|
|
|
- setCustomMaterial(group){}
|
|
|
+ setCustomMaterial(group) {}
|
|
|
|
|
|
/* 场景环境背景 */
|
|
|
setEnvMap(hdr) {
|
|
|
- // new RGBELoader().setPath('/public/3D/hdr/').load(hdr + '.jpeg', (texture) => {
|
|
|
+ // new RGBELoader().setPath('/public/model/hdr/').load(hdr + '.jpeg', (texture) => {
|
|
|
// debugger
|
|
|
// texture.mapping = THREE.EquirectangularReflectionMapping;
|
|
|
// (this.scene as THREE.Scene).background = texture;
|
|
|
// (this.scene as THREE.Scene).environment = texture;
|
|
|
// });
|
|
|
- new THREE.TextureLoader().setPath('/3D/hdr/').load(hdr + '.jpeg', (texture) => {
|
|
|
- texture.mapping = THREE.EquirectangularReflectionMapping;
|
|
|
- // (this.scene as THREE.Scene).background = new THREE.Color('#00000000');
|
|
|
- (this.scene as THREE.Scene).environment = texture;
|
|
|
- });
|
|
|
+ this.track(new THREE.TextureLoader())
|
|
|
+ .setPath('/model/hdr/')
|
|
|
+ .load(hdr + '.jpeg', (texture) => {
|
|
|
+ this.track(texture);
|
|
|
+ texture.mapping = THREE.EquirectangularReflectionMapping;
|
|
|
+ // (this.scene as THREE.Scene).background = texture;
|
|
|
+ (this.scene as THREE.Scene).environment = texture;
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
render() {
|
|
|
- const delta = this.clock.getElapsedTime();
|
|
|
- this.resetLookAt()
|
|
|
- this.startMY()
|
|
|
- this.renderer?.render(this.scene as THREE.Object3D, this.camera as THREE.Camera);
|
|
|
- this.css3dRender?.render(this.scene as THREE.Scene, this.camera as THREE.PerspectiveCamera)
|
|
|
- this.animationMixer?.update(delta);
|
|
|
+ this.camera?.updateMatrixWorld();
|
|
|
+ this.stats?.update();
|
|
|
+ this.resetLookAt();
|
|
|
+ this.startMY();
|
|
|
+ this.startAnimation();
|
|
|
+ this.orbitControls?.update();
|
|
|
+ this.composer?.render();
|
|
|
+
|
|
|
+ // this.css3dRender?.render(this.scene as THREE.Scene, this.camera as THREE.PerspectiveCamera)
|
|
|
}
|
|
|
|
|
|
/* 实时物体刷新朝向 */
|
|
|
- resetLookAt() {
|
|
|
- }
|
|
|
+ resetLookAt() {}
|
|
|
/* 漫游 */
|
|
|
startMY() {}
|
|
|
+ /* 初始动画 */
|
|
|
+ startAnimation() {}
|
|
|
|
|
|
animate() {
|
|
|
- // this.renderer?.setAnimationLoop(this.render.bind(this));
|
|
|
- if(this.animationId != -1) {
|
|
|
- this.render()
|
|
|
- this.animationId = requestAnimationFrame(this.animate.bind(this))
|
|
|
+ if (this.animationId != -1) {
|
|
|
+ setTimeout(() => {
|
|
|
+ this.animationId = requestAnimationFrame(this.animate.bind(this));
|
|
|
+ }, 1000 / 30);
|
|
|
+ this.renderer?.render(this.scene as THREE.Object3D, this.camera as THREE.Camera);
|
|
|
+ this.render();
|
|
|
+ // this.animationId = requestAnimationFrame(this.animate.bind(this));
|
|
|
+ // const T = this.clock.getDelta();
|
|
|
+ // this.timeS += T;
|
|
|
+ // if (this.timeS > 1 / this.FPS) {
|
|
|
+ // this.render();
|
|
|
+ // this.timeS = 0;
|
|
|
+ // }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
resizeRenderer() {
|
|
|
// 更新相机比例
|
|
|
- (this.camera as THREE.PerspectiveCamera).aspect = window.innerWidth / window.innerHeight;
|
|
|
+ (this.camera as THREE.PerspectiveCamera).aspect = this.canvasContainer.clientWidth / this.canvasContainer.clientHeight;
|
|
|
// 刷新相机矩阵
|
|
|
this.camera?.updateProjectionMatrix();
|
|
|
// 设置场景尺寸
|
|
|
- this.renderer?.setSize(window.innerWidth, window.innerHeight);
|
|
|
- this.css3dRender?.setSize(window.innerWidth, window.innerHeight);
|
|
|
+ this.renderer?.setSize(this.canvasContainer.clientWidth, this.canvasContainer.clientHeight);
|
|
|
+ // this.css3dRender?.setSize(this.canvasContainer.clientWidth, this.canvasContainer.clientHeight);
|
|
|
}
|
|
|
wheelRenderer(e: WheelEvent) {
|
|
|
const timeScale = e.deltaY > 0 ? 1 : -1;
|
|
@@ -280,162 +295,86 @@ class UseThree {
|
|
|
this.animationAction?.halt(0.5);
|
|
|
}, 500);
|
|
|
}
|
|
|
+
|
|
|
deleteModal() {
|
|
|
try {
|
|
|
-
|
|
|
- this.resourceTracker && this.resourceTracker.dispose()
|
|
|
- this.renderer?.dispose()
|
|
|
- this.renderer?.forceContextLoss()
|
|
|
- // this.renderer?.domElement = null
|
|
|
- this.renderer = null
|
|
|
-
|
|
|
- // this.css3dRender?.domElement = null
|
|
|
+ const gl = this.renderer?.domElement?.getContext('webgl');
|
|
|
+ gl && gl.getExtension('WEBGL_lose_context')?.loseContext();
|
|
|
+
|
|
|
+ const gl1 = this.css3dRender?.domElement?.getContext('webgl');
|
|
|
+ gl1 && gl1.getExtension('WEBGL_lose_context')?.loseContext();
|
|
|
+ this.renderer?.forceContextLoss();
|
|
|
+ this.renderer?.dispose();
|
|
|
+ if (this.renderer) this.renderer.domElement = null;
|
|
|
+ this.renderer = null;
|
|
|
+
|
|
|
+ this.resourceTracker && this.resourceTracker.dispose();
|
|
|
+
|
|
|
+ if (this.canvasContainer) this.canvasContainer.innerHTML = '';
|
|
|
+ this.canvasContainer = null;
|
|
|
+ this.orbitControls = null;
|
|
|
+
|
|
|
this.css3dRender = null;
|
|
|
+ this.camera = null;
|
|
|
+ this.clock = null;
|
|
|
|
|
|
cancelAnimationFrame(this.animationId);
|
|
|
|
|
|
- const gl = this.renderer?.domElement.getContext("webgl");
|
|
|
- gl && gl?.getExtension("WEBGL_lose_context")?.loseContext();
|
|
|
+ this.animationId = -1;
|
|
|
|
|
|
- const gl1 = this.css3dRender?.domElement.getContext("webgl");
|
|
|
- gl1 && gl1?.getExtension("WEBGL_lose_context")?.loseContext();
|
|
|
+ this.scene = null;
|
|
|
+ this.mixers = [];
|
|
|
|
|
|
- this.animationId = -1
|
|
|
-
|
|
|
- this.resourceTracker?.untrack(this.resourceTracker.resources)
|
|
|
- // this.scene = null
|
|
|
- console.log('销毁场景',this.scene);
|
|
|
-
|
|
|
+ console.log('销毁场景', this.scene);
|
|
|
} catch (error) {
|
|
|
console.log(error);
|
|
|
}
|
|
|
- // this.scene?.children.forEach((obj:any) => {
|
|
|
- // if(obj.type === 'Group'){
|
|
|
- // obj.traverse(function(item:any) {
|
|
|
- // if (item.type === 'Mesh') {
|
|
|
- // item.geometry.dispose();
|
|
|
- // item.material.dispose();
|
|
|
- // !!item.clear&&item.clear();
|
|
|
- // }
|
|
|
- // })
|
|
|
- // }else if (obj.material) {
|
|
|
- // obj.material.dispose();
|
|
|
- // }else if (obj.geometry) {
|
|
|
- // obj.geometry.dispose();
|
|
|
- // }
|
|
|
- // this.scene?.remove(obj)
|
|
|
- // !!obj.clear??obj.clear()
|
|
|
- // obj = null;
|
|
|
- // })
|
|
|
- // let gl = this.renderer?.domElement.getContext("webgl");
|
|
|
- // gl && gl?.getExtension("WEBGL_lose_context")?.loseContext();
|
|
|
-
|
|
|
- // this.renderer?.forceContextLoss();
|
|
|
- // this.renderer?.dispose();
|
|
|
- // this.camera = null;
|
|
|
- // this.orbitControls = null;
|
|
|
- // this.renderer.domElement = null;
|
|
|
- // this.renderer = null;
|
|
|
-
|
|
|
- // css3dRender.domElement = null;
|
|
|
- // css3dRender = null;
|
|
|
- // model3D.innerHTML = '';
|
|
|
- // css3D.innerHTML = '';
|
|
|
- // model3D = null
|
|
|
- // css3D = null
|
|
|
-
|
|
|
- // this.stats = null
|
|
|
- // scene = null
|
|
|
-
|
|
|
- THREE.Cache.clear();
|
|
|
+ THREE.Cache.clear();
|
|
|
console.log('3D环境已清理干净');
|
|
|
}
|
|
|
|
|
|
+ deleteModal1() {
|
|
|
+ this.scene?.children.forEach((obj) => {
|
|
|
+ if (obj.type === 'Group') {
|
|
|
+ obj.traverse(function (item) {
|
|
|
+ if (item.type === 'Mesh') {
|
|
|
+ item.geometry.dispose();
|
|
|
+ item.material.dispose();
|
|
|
+ !!item.clear && item.clear();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else if (obj.material) {
|
|
|
+ obj.material.dispose();
|
|
|
+ } else if (obj.geometry) {
|
|
|
+ obj.geometry.dispose();
|
|
|
+ }
|
|
|
+ this.scene?.remove(obj);
|
|
|
+ !!obj.clear ?? obj.clear();
|
|
|
+ obj = null;
|
|
|
+ });
|
|
|
|
|
|
- /* 创建字体精灵 */
|
|
|
- addTextSprite(message, parameters) {
|
|
|
- if (parameters === undefined) parameters = {};
|
|
|
-
|
|
|
- var fontface = parameters.hasOwnProperty("fontface") ?
|
|
|
- parameters["fontface"] : "Arial";
|
|
|
-
|
|
|
- /* 字体大小 */
|
|
|
- var fontsize = parameters.hasOwnProperty("fontsize") ?
|
|
|
- parameters["fontsize"] : 18;
|
|
|
-
|
|
|
- /* 边框厚度 */
|
|
|
- var borderThickness = parameters.hasOwnProperty("borderThickness") ?
|
|
|
- parameters["borderThickness"] : 4;
|
|
|
-
|
|
|
- /* 边框颜色 */
|
|
|
- var borderColor = parameters.hasOwnProperty("borderColor") ?
|
|
|
- parameters["borderColor"] : { r: 0, g: 0, b: 0, a: 1.0 };
|
|
|
-
|
|
|
- /* 背景颜色 */
|
|
|
- var backgroundColor = parameters.hasOwnProperty("backgroundColor") ?
|
|
|
- parameters["backgroundColor"] : { r: 255, g: 255, b: 255, a: 1.0 };
|
|
|
-
|
|
|
- /* 创建画布 */
|
|
|
- var canvas = document.createElement('canvas');
|
|
|
- var context = canvas.getContext('2d') as CanvasRenderingContext2D;
|
|
|
- // canvas.width = 0
|
|
|
- // canvas.height = 200
|
|
|
-
|
|
|
- /* 字体加粗 */
|
|
|
- context.font = "Bold " + fontsize + "px " + fontface;
|
|
|
-
|
|
|
- /* 获取文字的大小数据,高度取决于文字的大小 */
|
|
|
- var metrics = context.measureText(message);
|
|
|
- var textWidth = metrics.width;
|
|
|
-
|
|
|
- /* 背景颜色 */
|
|
|
- context.fillStyle = "rgba(" + backgroundColor.r + "," + backgroundColor.g + ","
|
|
|
- + backgroundColor.b + "," + backgroundColor.a + ")";
|
|
|
-
|
|
|
- /* 边框的颜色 */
|
|
|
- context.strokeStyle = "rgba(" + borderColor.r + "," + borderColor.g + ","
|
|
|
- + borderColor.b + "," + borderColor.a + ")";
|
|
|
- context.lineWidth = borderThickness;
|
|
|
-
|
|
|
- /* 绘制圆角矩形 */
|
|
|
- this.roundRect(context, borderThickness / 2, borderThickness / 2, textWidth + borderThickness, fontsize * 1.4 + borderThickness, 6);
|
|
|
- // this.roundRect(context, borderThickness / 2, borderThickness / 2, 10000, 10000, 6);
|
|
|
- /* 字体颜色 */
|
|
|
- context.fillStyle = "rgba(0, 0, 0, 1.0)";
|
|
|
- context.fillText(message, borderThickness, fontsize + borderThickness);
|
|
|
- // context.fillRect(borderThickness / 2, borderThickness / 2, 10000, 10000)
|
|
|
- /* 画布内容用于纹理贴图 */
|
|
|
- var texture = new THREE.Texture(canvas);
|
|
|
- texture.needsUpdate = true;
|
|
|
-
|
|
|
- var spriteMaterial = new THREE.SpriteMaterial({ map: texture, transparent:false });
|
|
|
- var sprite = new THREE.Sprite(spriteMaterial);
|
|
|
-
|
|
|
- /* 缩放比例 */
|
|
|
- sprite.scale.set(10, 5, 1);
|
|
|
-
|
|
|
- return sprite;
|
|
|
- }
|
|
|
-
|
|
|
- /* 绘制圆角矩形 */
|
|
|
- roundRect(ctx, x, y, w, h, r) {
|
|
|
-
|
|
|
- ctx.beginPath();
|
|
|
- ctx.moveTo(x + r, y);
|
|
|
- ctx.lineTo(x + w - r, y);
|
|
|
- ctx.quadraticCurveTo(x + w, y, x + w, y + r);
|
|
|
- ctx.lineTo(x + w, y + h - r);
|
|
|
- ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
|
|
|
- ctx.lineTo(x + r, y + h);
|
|
|
- ctx.quadraticCurveTo(x, y + h, x, y + h - r);
|
|
|
- ctx.lineTo(x, y + r);
|
|
|
- ctx.quadraticCurveTo(x, y, x + r, y);
|
|
|
- ctx.closePath();
|
|
|
- ctx.fill();
|
|
|
- ctx.stroke();
|
|
|
-
|
|
|
+ const gl = this.renderer?.domElement.getContext('webgl');
|
|
|
+ gl && gl.getExtension('WEBGL_lose_context')?.loseContext();
|
|
|
+
|
|
|
+ this.renderer?.forceContextLoss();
|
|
|
+ this.renderer?.dispose();
|
|
|
+ this.camera = null;
|
|
|
+ this.orbitControls = null;
|
|
|
+ if (this.renderer) this.renderer.domElement = null;
|
|
|
+ this.renderer = null;
|
|
|
+ if (this.css3dRender) this.css3dRender.domElement = null;
|
|
|
+ this.css3dRender = null;
|
|
|
+ if (this.canvasContainer) this.canvasContainer.innerHTML = '';
|
|
|
+ if (this.CSSCanvasContainer) this.CSSCanvasContainer.innerHTML = '';
|
|
|
+
|
|
|
+ !!this.scene?.clear ?? this.scene?.clear();
|
|
|
+ cancelAnimationFrame(this.animationId);
|
|
|
+ this.animationId = -1;
|
|
|
+ this.stats = null;
|
|
|
+ this.scene = null;
|
|
|
+ THREE.Cache.clear();
|
|
|
+ console.log('3D环境已清理干净');
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
export default UseThree;
|