src/views/screen/components/screen-map-three/experience/camera.js
New file @@ -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(); } } src/views/screen/components/screen-map-three/experience/index.js
New file @@ -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(); } } src/views/screen/components/screen-map-three/experience/renderer.js
New file @@ -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); } } src/views/screen/components/screen-map-three/experience/utils/eventEmitter.js
New file @@ -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 } } src/views/screen/components/screen-map-three/experience/utils/sizes.js
New file @@ -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'); } }); } } src/views/screen/components/screen-map-three/experience/utils/time.js
New file @@ -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(); }); } } src/views/screen/components/screen-map-three/experience/world/test.js
New file @@ -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); } } src/views/screen/components/screen-map-three/experience/world/world.js
New file @@ -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() { } } 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> src/views/screen/components/screen-map-three/world/camera.js
File was deleted src/views/screen/components/screen-map-three/world/renderer.js
File was deleted src/views/screen/components/screen-map-three/world/scene.js
File was deleted src/views/screen/components/screen-map-three/world/world.js
File was deleted 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() { 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 {