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