From fd9a2a05829f84dd3925da8fabec901498ebb9e0 Mon Sep 17 00:00:00 2001
From: ZhangXianQiang <1135831638@qq.com>
Date: 星期五, 29 三月 2024 16:44:44 +0800
Subject: [PATCH] chore:重构场景
---
src/views/screen/components/screen-map-three/experience/camera.js | 44 +++++
src/views/screen/components/screen-map-three/experience/index.js | 39 ++++
/dev/null | 29 ---
src/views/screen/components/screen-map-three/experience/utils/sizes.js | 33 ++++
src/views/screen/components/screen-map-three/experience/world/test.js | 24 +++
src/views/screen/components/screen-map-three/experience/world/world.js | 16 ++
src/views/screen/components/screen-wrapper/index.vue | 6
src/views/screen/components/screen-map-three/experience/utils/eventEmitter.js | 197 ++++++++++++++++++++++++
src/views/screen/components/screen-map-three/index.vue | 14 +
src/views/screen/index.vue | 4
src/views/screen/components/screen-map-three/experience/renderer.js | 32 ++++
src/views/screen/components/screen-map-three/experience/utils/time.js | 25 +++
12 files changed, 425 insertions(+), 38 deletions(-)
diff --git a/src/views/screen/components/screen-map-three/experience/camera.js b/src/views/screen/components/screen-map-three/experience/camera.js
new file mode 100644
index 0000000..70f33ff
--- /dev/null
+++ b/src/views/screen/components/screen-map-three/experience/camera.js
@@ -0,0 +1,44 @@
+import { PerspectiveCamera, CameraHelper } from 'three';
+import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
+
+
+export default class Camera {
+ constructor(experience) {
+ this.experience = experience;
+ this.scene = this.experience.scene;
+ this.canvas = this.experience.canvas;
+ this.sizes = this.experience.sizes;
+ this.setInstance();
+ this.setOrbitControls();
+
+ }
+
+ // 璁剧疆閫忚鐩告満
+ setInstance() {
+ this.instance = new PerspectiveCamera(75,this.sizes.width / this.sizes.height, 0.1, 1000);
+ this.instance.position.set(0, 5, 2);
+ this.scene.add(this.instance);
+ const help = new CameraHelper(this.instance);
+ this.scene.add(help);
+ }
+
+ setOrbitControls() {
+ this.controls = new OrbitControls(this.instance, this.canvas);
+ this.controls.target.set(0, 0, 0);
+ }
+
+ resize() {
+ // 閲嶆柊璁$畻姣斾緥
+ this.cameraAspect = (this.sizes.width / this.sizes.height) * this.frustrum;
+ this.instance.left = -this.cameraAspect / 2;
+ this.instance.right = this.cameraAspect / 2;
+ this.instance.top = this.frustrum / 2;
+ this.instance.bottom = -this.frustrum / 2;
+ this.instance.updateProjectionMatrix();
+ }
+
+
+ update() {
+ this.controls.update();
+ }
+}
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/experience/index.js b/src/views/screen/components/screen-map-three/experience/index.js
new file mode 100644
index 0000000..85dc8ca
--- /dev/null
+++ b/src/views/screen/components/screen-map-three/experience/index.js
@@ -0,0 +1,39 @@
+import { Scene,GridHelper } from 'three';
+
+
+import World from "./world/world";
+import Camera from "./camera";
+import Renderer from "./renderer";
+
+// 宸ュ叿绫�
+import Sizes from "./utils/sizes";
+import Time from "./utils/time";
+
+export default class Experience {
+ constructor(canvas) {
+ this.canvas = canvas;
+ this.sizes = new Sizes();
+ this.time = new Time();
+ this.scene = new Scene();
+ this.camera = new Camera(this);
+ this.renderer = new Renderer(this);
+ this.world = new World(this);
+
+ const size = 10;
+ const divisions = 10;
+
+ const gridHelper = new GridHelper(size, divisions);
+ this.scene.add(gridHelper);
+
+ // 甯�
+ this.time.on('tick', () => {
+ this.update();
+ });
+ }
+
+ update() {
+ this.camera.update();
+ this.world.update();
+ this.renderer.update();
+ }
+}
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/experience/renderer.js b/src/views/screen/components/screen-map-three/experience/renderer.js
new file mode 100644
index 0000000..3e7893c
--- /dev/null
+++ b/src/views/screen/components/screen-map-three/experience/renderer.js
@@ -0,0 +1,32 @@
+import * as THREE from 'three';
+export default class Renderer {
+ constructor(experience) {
+ this.experience = experience;
+ this.canvas = this.experience.canvas;
+ this.sizes = this.experience.sizes;
+ this.scene = this.experience.scene;
+ this.camera = this.experience.camera;
+
+ this.setInstance();
+ }
+ setInstance() {
+ this.instance = new THREE.WebGLRenderer({
+ canvas: this.canvas,
+ antialias: true,
+ alpha: true
+ });
+ this.instance.toneMapping = THREE.CineonToneMapping;
+ this.instance.toneMappingExposure = 1.75;
+ this.instance.shadowMap.enabled = true;
+ this.instance.shadowMap.type = THREE.PCFSoftShadowMap;
+ this.instance.setSize(this.sizes.width, this.sizes.height);
+ this.instance.setPixelRatio(this.sizes.pixelRatio);
+ }
+ resize() {
+ this.instance.setSize(this.sizes.width, this.sizes.height);
+ this.instance.setPixelRatio(this.sizes.pixelRatio);
+ }
+ update() {
+ this.instance.render(this.scene, this.camera.instance);
+ }
+}
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/experience/utils/eventEmitter.js b/src/views/screen/components/screen-map-three/experience/utils/eventEmitter.js
new file mode 100644
index 0000000..216b423
--- /dev/null
+++ b/src/views/screen/components/screen-map-three/experience/utils/eventEmitter.js
@@ -0,0 +1,197 @@
+export default class EventEmitter
+{
+ constructor()
+ {
+ this.callbacks = {}
+ this.callbacks.base = {}
+ }
+
+ on(_names, callback)
+ {
+ // Errors
+ if(typeof _names === 'undefined' || _names === '')
+ {
+ console.warn('wrong names')
+ return false
+ }
+
+ if(typeof callback === 'undefined')
+ {
+ console.warn('wrong callback')
+ return false
+ }
+
+ // Resolve names
+ const names = this.resolveNames(_names)
+
+ // Each name
+ names.forEach((_name) =>
+ {
+ // Resolve name
+ const name = this.resolveName(_name)
+
+ // Create namespace if not exist
+ if(!(this.callbacks[ name.namespace ] instanceof Object))
+ this.callbacks[ name.namespace ] = {}
+
+ // Create callback if not exist
+ if(!(this.callbacks[ name.namespace ][ name.value ] instanceof Array))
+ this.callbacks[ name.namespace ][ name.value ] = []
+
+ // Add callback
+ this.callbacks[ name.namespace ][ name.value ].push(callback)
+ })
+
+ return this
+ }
+
+ off(_names)
+ {
+ // Errors
+ if(typeof _names === 'undefined' || _names === '')
+ {
+ console.warn('wrong name')
+ return false
+ }
+
+ // Resolve names
+ const names = this.resolveNames(_names)
+
+ // Each name
+ names.forEach((_name) =>
+ {
+ // Resolve name
+ const name = this.resolveName(_name)
+
+ // Remove namespace
+ if(name.namespace !== 'base' && name.value === '')
+ {
+ delete this.callbacks[ name.namespace ]
+ }
+
+ // Remove specific callback in namespace
+ else
+ {
+ // Default
+ if(name.namespace === 'base')
+ {
+ // Try to remove from each namespace
+ for(const namespace in this.callbacks)
+ {
+ if(this.callbacks[ namespace ] instanceof Object && this.callbacks[ namespace ][ name.value ] instanceof Array)
+ {
+ delete this.callbacks[ namespace ][ name.value ]
+
+ // Remove namespace if empty
+ if(Object.keys(this.callbacks[ namespace ]).length === 0)
+ delete this.callbacks[ namespace ]
+ }
+ }
+ }
+
+ // Specified namespace
+ else if(this.callbacks[ name.namespace ] instanceof Object && this.callbacks[ name.namespace ][ name.value ] instanceof Array)
+ {
+ delete this.callbacks[ name.namespace ][ name.value ]
+
+ // Remove namespace if empty
+ if(Object.keys(this.callbacks[ name.namespace ]).length === 0)
+ delete this.callbacks[ name.namespace ]
+ }
+ }
+ })
+
+ return this
+ }
+
+ trigger(_name, _args)
+ {
+ // Errors
+ if(typeof _name === 'undefined' || _name === '')
+ {
+ console.warn('wrong name')
+ return false
+ }
+
+ let finalResult = null
+ let result = null
+
+ // Default args
+ const args = !(_args instanceof Array) ? [] : _args
+
+ // Resolve names (should on have one event)
+ let name = this.resolveNames(_name)
+
+ // Resolve name
+ name = this.resolveName(name[ 0 ])
+
+ // Default namespace
+ if(name.namespace === 'base')
+ {
+ // Try to find callback in each namespace
+ for(const namespace in this.callbacks)
+ {
+ if(this.callbacks[ namespace ] instanceof Object && this.callbacks[ namespace ][ name.value ] instanceof Array)
+ {
+ this.callbacks[ namespace ][ name.value ].forEach(function(callback)
+ {
+ result = callback.apply(this, args)
+
+ if(typeof finalResult === 'undefined')
+ {
+ finalResult = result
+ }
+ })
+ }
+ }
+ }
+
+ // Specified namespace
+ else if(this.callbacks[ name.namespace ] instanceof Object)
+ {
+ if(name.value === '')
+ {
+ console.warn('wrong name')
+ return this
+ }
+
+ this.callbacks[ name.namespace ][ name.value ].forEach(function(callback)
+ {
+ result = callback.apply(this, args)
+
+ if(typeof finalResult === 'undefined')
+ finalResult = result
+ })
+ }
+
+ return finalResult
+ }
+
+ resolveNames(_names)
+ {
+ let names = _names
+ names = names.replace(/[^a-zA-Z0-9 ,/.]/g, '')
+ names = names.replace(/[,/]+/g, ' ')
+ names = names.split(' ')
+
+ return names
+ }
+
+ resolveName(name)
+ {
+ const newName = {}
+ const parts = name.split('.')
+
+ newName.original = name
+ newName.value = parts[ 0 ]
+ newName.namespace = 'base' // Base namespace
+
+ // Specified namespace
+ if(parts.length > 1 && parts[ 1 ] !== '')
+ {
+ newName.namespace = parts[ 1 ]
+ }
+
+ return newName
+ }
+}
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/experience/utils/sizes.js b/src/views/screen/components/screen-map-three/experience/utils/sizes.js
new file mode 100644
index 0000000..af7c98d
--- /dev/null
+++ b/src/views/screen/components/screen-map-three/experience/utils/sizes.js
@@ -0,0 +1,33 @@
+/**
+ * 璁$畻澶у皬
+ */
+import EventEmitter from './eventEmitter';
+export default class Sizes extends EventEmitter {
+ constructor() {
+ super();
+ this.width = document.body.clientWidth;
+ this.height = document.body.clientHeight;
+ this.device = document.body.clientWidth <= 968 ? 'mobile' : 'pc';
+ // 璁惧鍍忕礌
+ this.pixelRatio = Math.min(window.devicePixelRatio, 2);
+
+ // 瀹介珮鍙樺寲
+ window.addEventListener('resize', () => {
+ // this.width = window.innerWidth;
+ // this.height = window.innerHeight;
+
+ this.width = document.body.clientWidth;
+ this.height = document.body.clientHeight;
+ this.pixelRatio = Math.min(window.devicePixelRatio, 2);
+ this.trigger('resize');
+
+ if(this.width < 968 && this.device !== 'mobile') {
+ this.device = 'mobile';
+ this.trigger('devicechange');
+ } else if(this.width >= 968 && this.device !== 'pc') {
+ this.device = 'pc';
+ this.trigger('devicechange');
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/experience/utils/time.js b/src/views/screen/components/screen-map-three/experience/utils/time.js
new file mode 100644
index 0000000..680b19d
--- /dev/null
+++ b/src/views/screen/components/screen-map-three/experience/utils/time.js
@@ -0,0 +1,25 @@
+import EventEmitter from "./eventEmitter";
+export default class Time extends EventEmitter {
+ constructor() {
+ super();
+ this.start = Date.now();
+ this.current = this.start;
+ this.elapsed = 0;
+ this.delta = 16;
+ window.requestAnimationFrame(() => {
+ this.tick();
+ });
+ }
+
+ tick() {
+ const currentTime = Date.now();
+ this.delta = currentTime - this.current;
+ this.current = currentTime;
+ this.elapsed = this.current - this.start;
+ this.trigger('tick');
+
+ window.requestAnimationFrame(() => {
+ this.tick();
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/experience/world/test.js b/src/views/screen/components/screen-map-three/experience/world/test.js
new file mode 100644
index 0000000..599d3df
--- /dev/null
+++ b/src/views/screen/components/screen-map-three/experience/world/test.js
@@ -0,0 +1,24 @@
+import * as THREE from 'three';
+
+export default class Test {
+ constructor(experience) {
+ this.experience = experience;
+ this.scene = this.experience.scene;
+
+ this.setGeometry();
+ this.setMaterial();
+ this.setMesh();
+ }
+ setGeometry() {
+ this.geometry = new THREE.BoxGeometry(2,2,2);
+ }
+ setMaterial() {
+ this.geometryMaterial = new THREE.MeshStandardMaterial({
+ color: '#db929d'
+ });
+ }
+ setMesh() {
+ this.geometrytMesh = new THREE.Mesh(this.geometry, this.geometryMaterial);
+ this.scene.add(this.geometrytMesh);
+ }
+}
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/experience/world/world.js b/src/views/screen/components/screen-map-three/experience/world/world.js
new file mode 100644
index 0000000..3a2bbe0
--- /dev/null
+++ b/src/views/screen/components/screen-map-three/experience/world/world.js
@@ -0,0 +1,16 @@
+import EventEmitter from '../utils/eventEmitter';
+
+import Test from "./test";
+
+export default class World extends EventEmitter {
+ constructor(experience) {
+ super();
+ this.experience = experience;
+ this.scene = this.experience.scene;
+ this.Test = new Test(this.experience);
+ }
+
+ update() {
+
+ }
+}
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/index.vue b/src/views/screen/components/screen-map-three/index.vue
index 9d6eedf..1d010f4 100644
--- a/src/views/screen/components/screen-map-three/index.vue
+++ b/src/views/screen/components/screen-map-three/index.vue
@@ -1,16 +1,16 @@
<template>
- <div class="map-container" ref="mapContainer">
-
+ <div class="map-container" >
+ <canvas class="world" ref="worldContainer"></canvas>
</div>
</template>
<script>
-import World from './world/world';
+import Experience from './experience/index';
let world = null;
export default {
name: 'ScreenMapThree',
mounted() {
- world = new World(this.$refs.mapContainer);
+ world = new Experience(this.$refs.worldContainer);
}
}
</script>
@@ -19,5 +19,11 @@
.map-container {
width: 100%;
height: 100%;
+ position: absolute;
+ z-index: 0;
+ .world {
+ width: 100%;
+ height: 100%;
+ }
}
</style>
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/world/camera.js b/src/views/screen/components/screen-map-three/world/camera.js
deleted file mode 100644
index 2605ae8..0000000
--- a/src/views/screen/components/screen-map-three/world/camera.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { PerspectiveCamera } from 'three';
-
-function createCamera() {
- const camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
- return camera;
-}
-
-export { createCamera };
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/world/renderer.js b/src/views/screen/components/screen-map-three/world/renderer.js
deleted file mode 100644
index 3105c95..0000000
--- a/src/views/screen/components/screen-map-three/world/renderer.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import {WebGLRenderer} from 'three';
-
-function createRenderer() {
- const renderer = new WebGLRenderer();
- renderer.setPixelRatio(Math.min(2,window.devicePixelRatio));
- renderer.setSize(window.innerWidth, window.innerHeight);
- renderer.setClearAlpha(0);
- return renderer;
-}
-
-export {createRenderer};
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/world/scene.js b/src/views/screen/components/screen-map-three/world/scene.js
deleted file mode 100644
index 3c47871..0000000
--- a/src/views/screen/components/screen-map-three/world/scene.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import {Scene} from 'three';
-
-function createScene() {
- const scene = new Scene();
-
- return scene;
-}
-
-export { createScene}
\ No newline at end of file
diff --git a/src/views/screen/components/screen-map-three/world/world.js b/src/views/screen/components/screen-map-three/world/world.js
deleted file mode 100644
index aa1718b..0000000
--- a/src/views/screen/components/screen-map-three/world/world.js
+++ /dev/null
@@ -1,29 +0,0 @@
-
-import { createScene } from "./scene";
-import { createRenderer } from "./renderer";
-import { createCamera } from "./camera";
-export default class World {
- /**
- * 鐢熸垚3d鍦烘櫙鏋勯�犲嚱鏁�
- * @param {*} container 3d鍦烘櫙html瀹瑰櫒
- */
- constructor(container) {
- this.container = container;
- this.init();
- this.render();
- }
- init() {
- this.scene = createScene();
- this.renderer = createRenderer();
- this.camera = createCamera();
- this.scene.add(this.camera);
- this.container.appendChild(this.renderer.domElement);
- }
-
- render() {
- this.renderer.render(this.scene, this.camera);
- window.requestAnimationFrame(() => {
- this.render();
- })
- }
-}
\ No newline at end of file
diff --git a/src/views/screen/components/screen-wrapper/index.vue b/src/views/screen/components/screen-wrapper/index.vue
index fdfd4cf..b9d9235 100644
--- a/src/views/screen/components/screen-wrapper/index.vue
+++ b/src/views/screen/components/screen-wrapper/index.vue
@@ -5,6 +5,7 @@
<el-button type="primary" @click="returnPath">绠$悊绯荤粺</el-button>
</div>
<div class="wrapper-content">
+ <screen-map-three></screen-map-three>
<div class="left-container wrapper">
<screen-face class="animate-enter-x enter-left"></screen-face>
<screen-car class="animate-enter-x enter-left animate-delay-1"></screen-car>
@@ -33,6 +34,8 @@
import ScreenMap from '../screen-map/index';
import ScreenMapCover from '../screen-map-cover/index';
import ScreenTable from '../screen-table/index';
+import ScreenMapThree from '../screen-map-three/index.vue';
+
export default {
name: 'ScreenWrapper',
components: {
@@ -43,7 +46,8 @@
ScreenCar,
ScreenMap,
ScreenTable,
- ScreenMapCover
+ ScreenMapCover,
+ ScreenMapThree
},
methods: {
returnPath() {
diff --git a/src/views/screen/index.vue b/src/views/screen/index.vue
index 4e8c6fc..4e8cf80 100644
--- a/src/views/screen/index.vue
+++ b/src/views/screen/index.vue
@@ -1,9 +1,7 @@
<template>
<div class="screen-container">
-
<screen-title></screen-title>
<v-scale-screen width="1920" height="1080" :autoScale="true" :delay="0" class="screen">
- <screen-map-three></screen-map-three>
<screen-wrapper></screen-wrapper>
</v-scale-screen>
</div>
@@ -13,7 +11,6 @@
<script>
import ScreenTitle from './components/screen-title/index.vue';
import ScreenWrapper from './components/screen-wrapper/index.vue';
-import ScreenMapThree from './components/screen-map-three/index.vue';
export default {
@@ -21,7 +18,6 @@
components: {
ScreenTitle,
ScreenWrapper,
- ScreenMapThree
},
data() {
return {
--
Gitblit v1.8.0