ZhangXianQiang
2024-03-29 fd9a2a05829f84dd3925da8fabec901498ebb9e0
chore:重构场景
3个文件已修改
8个文件已添加
4个文件已删除
491 ■■■■ 已修改文件
src/views/screen/components/screen-map-three/experience/camera.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/index.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/renderer.js 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/utils/eventEmitter.js 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/utils/sizes.js 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/utils/time.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/world/test.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/experience/world/world.js 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/index.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/world/camera.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/world/renderer.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/world/scene.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-map-three/world/world.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/components/screen-wrapper/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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 {