three.js详细注释
最近学习WEB 3D技术,
因为之前米有接触过,
所以需要学习同时理解其中的含义,
就自己一行一行
仔细查资料注释,
费了好大劲呢~~~
<template> <div style="100%; height:800px" class="my_div"> <p>3D太陽系</p> <canvas ref="main" /> <div id="canvas-frame" ref="myBody" style="1000px; height:800px" /> </div> </template> <script> import * as THREE from 'three' import { OBJLoader, MTLLoader } from 'three-obj-mtl-loader' // import MTLLoader from 'three-mtl-loader'; // import OBJLoader from 'three-obj-loader'; import { CSS2DRenderer, CSS2DObject } from 'three-css2drender' // import { Geometry, Line } from 'three' // import { Geometry, Material, Scene, WebGLBufferRenderer } from 'three'; const OrbitControls = require('three-orbit-controls')(THREE) export default { data() { return { canvas: Element, loader: THREE.TextureLoader, sunSystem: THREE.Object3D, sun: THREE.Mesh, orbitcontrols: OrbitControls, planets: [], labelRenderer: new CSS2DRenderer(), scene: new THREE.Scene(), // 場景 camera: new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 ), // 透視相機 renderer: new THREE.WebGLRenderer(), // 渲染器 geometry: new THREE.Geometry(), // 設置物體 material: new THREE.LineBasicMaterial({ vertexColors: true }), // 設置材料 cube: {}, // 合起來 // 開始設置線條 light: new THREE.DirectionalLight(0xff0000, 1.0, 0) } }, mounted() { this.threeStart() console.log() }, methods: { initThree() { this.canvas = this.$refs.main this.canvas.width = window.innerWidth // 只读的Window 属性 innerWidth 返回以像素为单位的窗口的内部宽度。如果垂直滚动条存在,则这个属性将包括它的宽度。 this.canvas.height = window.innerHeight const canvas = this.canvas // 創建渲染器 // new WebGLRenderer会在body里面生成一个canvas标签,当然如果你想在某个位置插入canvas可以在指定的dom元素appendChild(renderer.domElement) this.renderer = new THREE.WebGLRenderer({ canvas, alpha: true, // alpha:true/false是否可以设置背景色透明 antialias: true // antialias:true/false是否开启反锯齿 }) this.renderer.setPixelRatio(window.devicePixelRatio) // setPixelRatio是为了兼容高清屏幕,Window 接口的devicePixelRatio返回当前显示设备的物理像素分辨率与CSS像素分辨率之比 this.renderer.shadowMap.enabled = true // 輔助線 this.renderer.shadowMap.type = THREE.PCFSoftShadowMap // 柔化边缘的软阴影映射 this.renderer.setClearColor(0xffffff, 0) // 设置canvas背景色(clearColor)和背景色透明度(clearAlpha) }, initScene() { this.scene = new THREE.Scene() // 創建場景 }, initCamera() { // 創建透視相機, this.camera = new THREE.PerspectiveCamera( 45, // 视野角fov window.innerWidth / window.innerHeight, // 纵横比:aspect 1, // 相机离视体积最近的距离:near 3000 // 相机离视体积最远的距离:far ) this.camera.position.set(-200, 50, 0) // 设置相机的位置坐标xyz this.camera.lookAt(0, 0, 0) // 设置视野的中心坐标 this.scene.add(this.camera) // 添加相機到場景裡 }, initAxesHelper() { const axesHelper = new THREE.AxesHelper(500) this.scene.add(axesHelper) }, initLabelRender() { console.log('canvas.clientWidth, canvas.clientHeight') console.log(this.canvas.clientWidth, this.canvas.clientHeight) this.labelRenderer.setSize( this.canvas.clientWidth, this.canvas.clientHeight ) this.labelRenderer.domElement.style.position = 'absolute' this.labelRenderer.domElement.style.top = '0px' this.$refs.myBody.appendChild(this.labelRenderer.domElement) // 追加 【canvas】 元素到 【myBody】 元素中。 }, initLight() { this.light = new THREE.DirectionalLight(0xff0000, 1.0, 0) // 设置平行光源 this.light.position.set(200, 200, 200) // 设置光源向量 this.scene.add(this.light) // 追加光源到场景 }, initObject() { // Orbit controls(轨道控制器)可以使得相机围绕目标进行轨道运动 this.orbitcontrols = new OrbitControls( this.camera, this.labelRenderer.domElement ) console.log('軌道控制器') this.orbitcontrols.update() // false 更新控件,在手动改变了摄像机的钻换后必须调用。在设置了autoRotate或enableDamping时也要在循环中调用 this.loader = new THREE.TextureLoader() // 纹理加载器 // Object3D似乎是Three.js框架中最重要的类,相当一部分其他的类都是继承自Object3D类,比如场景类、几何形体类、相机类、光照类等等:他们都是3D空间中的对象,所以称为Object3D类 this.sunSystem = new THREE.Object3D() this.scene.add(this.sunSystem) // 向场景中添加对象 // sun // 网格基础材质 const sunMaterial = new THREE.MeshBasicMaterial({ map: this.loader.load(require('./webgl-assets/img/sun_bg.jpg')) }) // 网孔对象的基类,MESH就是一系列的多边形组成的,三角形或者四边形,网格一般由顶点来描绘,我们看见的三维开发的模型就是由一系列的点组成的。Mesh( geometry几何模型, material材料 ) this.sun = new THREE.Mesh( new THREE.SphereGeometry(14, 30, 30), // 一个 几何模型(Geometry) 实例,用来定义对象的结构。可以创建一个半径为14,经度划分成30份,纬度划分成30份的球体 sunMaterial // 一个 材料(Material) 实例,用来定义对象的外观 ) this.sun.name = 'SUN' this.sunSystem.add(this.sun) // 将对象添加为该对象的子对象。可以添加任意数量的对象 }, initPlanet() { const planetDiv = document.createElement('div') planetDiv.className = 'label' planetDiv.textContent = '太陽' planetDiv.style.color = 'white' planetDiv.style.marginTop = '-0.3em' const planetaLabel = new CSS2DObject(planetDiv) // 把上述div对象转化为一个CSS2DObject对象 planetaLabel.position.set(0, 14, 0) this.sun.add(planetaLabel) // 在球體模型中加入该CSS2DObject对象 }, addPlanets() { // 添加水星 const Mercury = this.loadPlanet('mercury', 2, 20, 0.02) this.planets.push(Mercury) // 添加金星 const Venus = this.loadPlanet('venus', 4, 30, 0.012) this.planets.push(Venus) // 添加地球 const Earth = this.loadPlanet('earth', 5, 40, 0.01) this.planets.push(Earth) // 添加火星 const Mars = this.loadPlanet('mars', 4, 50, 0.008) this.planets.push(Mars) // 添加木星 const Jupiter = this.loadPlanet('jupiter', 9, 70, 0.006) this.planets.push(Jupiter) // 添加土星 const Saturn = this.loadPlanet('saturn', 7, 100, 0.005) this.planets.push(Saturn) // 添加天王星 const Uranus = this.loadPlanet('uranus', 4, 120, 0.003) this.planets.push(Uranus) // 添加海王星 const Neptune = this.loadPlanet('neptune', 3, 150, 0.002) this.planets.push(Neptune) // 添加冥王星 const Pluto = this.loadPlanet('pluto', 4, 160, 0.0016) this.planets.push(Pluto) const particleSystem = this.initParticle() this.scene.add(particleSystem) }, initParticle() { // /*背景星星*/ const particles = 20000 // 星星数量 // /*buffer做星星*/ const bufferGeometry = new THREE.BufferGeometry() const positions = new Float32Array(particles * 3) const colors = new Float32Array(particles * 3) const color = new THREE.Color() const gap = 900 // 定义星星的最近出现位置 for (let i = 0; i < positions.length; i += 3) { // positions // /*-2gap < x < 2gap */ let x = Math.random() * gap * 2 * (Math.random() < 0.5 ? -1 : 1) let y = Math.random() * gap * 2 * (Math.random() < 0.5 ? -1 : 1) let z = Math.random() * gap * 2 * (Math.random() < 0.5 ? -1 : 1) // /*找出x,y,z中绝对值最大的一个数*/ const biggest = Math.abs(x) > Math.abs(y) ? Math.abs(x) > Math.abs(z) ? 'x' : 'z' : Math.abs(y) > Math.abs(z) ? 'y' : 'z' const pos = { x, y, z } // /*如果最大值比n要小(因为要在一个距离之外才出现星星)则赋值为n(-n)*/ if (Math.abs(pos[biggest]) < gap) { pos[biggest] = pos[biggest] < 0 ? -gap : gap } x = pos['x'] y = pos['y'] z = pos['z'] positions[i] = x positions[i + 1] = y positions[i + 2] = z // colors // /*70%星星有颜色*/ const hasColor = Math.random() > 0.3 let vx, vy, vz if (hasColor) { vx = (Math.random() + 1) / 2 vy = (Math.random() + 1) / 2 vz = (Math.random() + 1) / 2 } else { vx = 1 vy = 1 vz = 1 } color.setRGB(vx, vy, vz) colors[i] = color.r colors[i + 1] = color.g colors[i + 2] = color.b } bufferGeometry.setAttribute( 'position', new THREE.BufferAttribute(positions, 3) ) bufferGeometry.setAttribute('color', new THREE.BufferAttribute(colors, 3)) bufferGeometry.computeBoundingSphere() // /*星星的material*/ const material = new THREE.PointsMaterial({ size: 6, vertexColors: THREE.VertexColors }) const particleSystem = new THREE.Points(bufferGeometry, material) return particleSystem }, loadPlanet(name, radius, position, speed) { const planetSystem = new THREE.Mesh( new THREE.SphereGeometry(1, 1, 1), // 一个 几何模型(Geometry) 实例,用来定义对象的结构。可以创建一个半径为1,经度划分成1份,纬度划分成1份的球体 new THREE.MeshLambertMaterial() // 材料實例,用來定義對象外觀 ) // 材质设定 planetSystem.speed = speed // 動態設置材質 const material = new THREE.MeshBasicMaterial({ map: this.loader.load(require(`./webgl-assets/img/${name}_bg.jpg`)) }) const planet = new THREE.Mesh( new THREE.SphereGeometry(radius, 30, 30), // 動態創建球體 material // 使用動態貼圖渲染 ) planet.position.z = -position // 設置z坐標位置 // planet.rotateOnAxis(new THREE.Vector3(1, 0, 0).normalize(), -23.36 * Math.PI / 180) planetSystem.add(planet) if (name === 'saturn') { const ringMaterial = new THREE.MeshBasicMaterial({ map: this.loader.load(`./webgl-assets/img/${name}_ring.jpg`), // 皮膚貼圖 side: THREE.DoubleSide // 雙面材質 }) const ring = new THREE.Mesh( new THREE.RingGeometry(radius * 1.2, radius * 1.5, 64, 1),// RingGeometry用来在三维空间内创建一个二维圆环面对象. ringMaterial ) ring.rotation.x = -Math.PI / 2 planet.add(ring) } const track = new THREE.Mesh( new THREE.RingGeometry(position, position + 0.05, 64, 1), // 二维圆环面对象(內徑,外徑,分段數,面細分) new THREE.MeshBasicMaterial({ side: THREE.DoubleSide // 雙面材質 }) ) track.rotation.x = -Math.PI / 2 this.scene.add(track) // Three.js中的div标签跟随(模型弹框) const planetDiv = document.createElement('div') // 把div存为变量 planetDiv.className = 'label' planetDiv.style.color = 'white' planetDiv.textContent = name planetDiv.style.marginTop = '-0.3em' const planetLabel = new CSS2DObject(planetDiv) // 把上述div对象转化为一个CSS2DObject对象 planetLabel.position.set(0, radius, 0) // 前两个参数是对于屏幕xy坐标,可以取负数 第三个不清楚,按道理应该是z轴坐标,不知道怎么体现 planet.add(planetLabel) // 在模型中加入该CSS2DObject对象 this.sunSystem.add(planetSystem) // 注意事项:上面的代码放在camera / OrbitControls之后, 否则相机控制不能用 return planetSystem }, resizeRendererToDisplaySize(renderer) { const canvas = renderer.domElement const width = canvas.clientWidth const height = canvas.clientHeight const needResize = canvas.width !== width || canvas.height !== height if (needResize) { renderer.setSize(width, height, false) // 指定渲染器的高宽 } return needResize }, render(time) { time *= 0.0005 if (this.resizeRendererToDisplaySize(this.renderer)) { const canvas = this.renderer.domElement this.camera.aspect = canvas.clientWidth / canvas.clientHeight // aspect属性:设置摄像机视口比例,实际窗口的纵横比,即宽度除以高度,这个值越大,说明你宽度越大,那么你可能看的是宽银幕电影了,如果这个值小于1,则为竖屏。 this.camera.updateProjectionMatrix() // 如果相机对象与投影矩阵相关的属性发生了变化,就需要手动更新相机的投影矩阵,更新相机对象的投影矩阵属性 } this.sunSystem.rotation.y = -time // 在three.js你可以使用rotation来设置object3D的旋转。 for (var i = 0; i < this.planets.length; i++) { this.planets[i].rotation.y -= this.planets[i].speed const planet = this.planets[i].children[0] planet.rotation.y -= 0.1 } this.orbitcontrols.update() // Orbit controls(轨道控制器)可以使得相机围绕目标进行轨道运动 this.renderer.render(this.scene, this.camera) this.labelRenderer.render(this.scene, this.camera) requestAnimationFrame(this.render) }, animation() {}, threeStart() { this.initThree() this.initScene() this.initCamera() this.initAxesHelper() this.initLabelRender() this.initObject() this.initPlanet() this.addPlanets() requestAnimationFrame(this.render) }, consoleObj() { console.log(THREE.REVISION) console.log(OBJLoader) console.log(MTLLoader) console.log(CSS2DRenderer) console.log(CSS2DObject) } } } </script> <style lang="less" scoped> .my_div { background: #000 url('./webgl-assets/img/starry_sky_bg.jpg') no-repeat center center; margin: 0; padding: 0; overflow: hidden; .label { color: #fff; font-family: sans-serif; font-size: xx-small; padding: 2px; } .label:hover { color: red; } } #main { position: relative; /* makes this the origin of its children */ 100%; height: 100%; overflow: hidden; } </style>
<template> <div style="1000px; height:800px"> <p>網格佈局</p> <div ref="myBody" id="canvas-frame" style="1000px; height:800px" /> </div> </template> <script> import * as THREE from 'three' import { OBJLoader, MTLLoader } from 'three-obj-mtl-loader' // import MTLLoader from 'three-mtl-loader'; // import OBJLoader from 'three-obj-loader'; import { CSS2DRenderer, CSS2DObject } from 'three-css2drender' // import { Geometry, Line } from 'three' // import { Geometry, Material, Scene, WebGLBufferRenderer } from 'three'; // const OrbitControls = require('three-orbit-controls')(THREE); export default { data() { return { scene: new THREE.Scene(), // 場景 camera: new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 ), // 透視相機 renderer: new THREE.WebGLRenderer(), // 渲染器 geometry: new THREE.Geometry(), // 設置物體 material: new THREE.LineBasicMaterial({ vertexColors: true }), // 設置材料 cube: {}, // 合起來 // 開始設置線條 light: new THREE.DirectionalLight(0xff0000, 1.0, 0) } }, mounted() { this.threeStart() }, methods: { initThree() { const width = this.$refs.myBody.clientWidth const height = this.$refs.myBody.clientHeight this.renderer = new THREE.WebGLRenderer({ antialias: true }) this.renderer.setSize(width, height) this.$refs.myBody.appendChild(this.renderer.domElement) this.renderer.setClearColor(0xffffff, 1.0) }, initCamera() { this.camera = new THREE.PerspectiveCamera(130, 1.5, 1, 10000) this.camera.position.x = 0 this.camera.position.y = 0 this.camera.position.z = 600 this.camera.up.x = 0 this.camera.up.y = 1 this.camera.up.z = 0 this.camera.lookAt(0, 0, 0) }, initScene() { this.scene = new THREE.Scene() }, initLight() { var light = new THREE.AmbientLight(0xffffff) light.position.set(100, 100, 200) this.scene.add(light) var light1 = new THREE.PointLight(0x00ff00) light1.position.set(0, 0, 300) this.scene.add(light1) }, initObject() { var geometry = new THREE.CylinderGeometry(80, 100, 400) var material = new THREE.MeshLambertMaterial({ color: 0xffff00 }) var mesh = new THREE.Mesh(geometry, material) this.scene.add(mesh) }, animation() { this.camera.position.x = this.camera.position.x += 3 this.camera.position.y = this.camera.position.y += 3 this.renderer.render(this.scene, this.camera) requestAnimationFrame(this.animation) }, threeStart() { this.initThree() this.initCamera() this.initScene() this.initLight() this.initObject() this.animation() }, consoleObj() { console.log(THREE.REVISION) console.log(OBJLoader) console.log(MTLLoader) console.log(CSS2DRenderer) console.log(CSS2DObject) } } } </script> <style lang="less" scoped> #canvas_frame { border: none; cursor: pointer; 100%; height: 600px; background-color: #eeeeee; } </style>
<!--suppress ALL --> <template> <div id="container"> </div> </template> <script> import * as THREE from "three"; import {OBJLoader, MTLLoader} from 'three-obj-mtl-loader'; // import MTLLoader from 'three-mtl-loader'; // import OBJLoader from 'three-obj-loader'; import {CSS2DRenderer, CSS2DObject} from 'three-css2drender'; const OrbitControls = require('three-orbit-controls')(THREE); export default { name: "threeMap", data() { return { scene: '', labelRenderer: '', light: '', camera: '', controls: '', renderer: '', geometry: '', material: '', cube: '', fov: 60, biaozhudiv: '', img: '', biaozhuLabel: '' } }, mounted() { this.init(); this.addObj(); this.animate(); }, // destroyed(){ // console.log("实例已经被销毁"); // }, methods: { init() { this.scene = new THREE.Scene(); this.scene.add(new THREE.AmbientLight(0x999999));//环境光 this.light = new THREE.DirectionalLight(0xdfebff, 0.45);//从正上方(不是位置)照射过来的平行光,0.45的强度 this.light.position.set(50, 200, 100); this.light.position.multiplyScalar(0.3); this.scene.add(this.light); //初始化相机 this.camera = new THREE.PerspectiveCamera(this.fov, window.innerWidth / window.innerHeight, 1, 1000); this.camera.position.set(10, 90, 65); this.camera.lookAt(this.scene.position); //初始化控制器 this.controls = new OrbitControls(this.camera); this.controls.target.set(0, 0, 0); this.controls.minDistance = 80; this.controls.maxDistance = 400; this.controls.maxPolarAngle = Math.PI / 3; this.controls.update(); //渲染 this.renderer = new THREE.WebGLRenderer({ alpha: true, });//会在body里面生成一个canvas标签, this.renderer.setPixelRatio(window.devicePixelRatio);//为了兼容高清屏幕 this.renderer.setSize(window.innerWidth, window.innerHeight); const container = document.getElementById('container'); container.appendChild(this.renderer.domElement); //标注渲染 this.labelRenderer = new CSS2DRenderer(); this.labelRenderer.setSize(window.innerWidth, window.innerHeight); this.labelRenderer.domElement.style.position = 'absolute'; this.labelRenderer.domElement.style.top = 0; container.appendChild(this.labelRenderer.domElement); window.addEventListener('resize', this.onWindowResize, false);//添加窗口监听事件(resize-onresize即窗口或框架被重新调整大小) }, onWindowResize() { this.camera.aspect = window.innerWidth / window.innerHeight; this.camera.updateProjectionMatrix(); // 如果通过 perspectiveCamera.xxx的方式修改要调用updateProjectionMatrix,否则一定不会生效。 this.renderer.setSize(window.innerWidth, window.innerHeight); this.labelRenderer.setSize(window.innerWidth, window.innerHeight); }, animate() { requestAnimationFrame(this.animate); this.render(); }, render() { this.renderer.render(this.scene, this.camera); this.labelRenderer.render(this.scene, this.camera); }, addObj() { // MTLLoader 负责加载 OBJLoader 的纹理, 里面描述了哪个几何模型对应哪个图片. 它采用相对路径来 引用纹理图片, 所以 load() 之前要调用 setPath(). //包含材质 // load( url加載路徑, onLoad加載完成函數, onProgress加載進程函數, onError加載錯誤函數 ) : null new MTLLoader().setPath('/static/model/modelFirst/').load('modelFirst.mtl', materials => { console.log("materials", materials); materials.preload(); // OBJLoader 用来加载 OBJ 格式模型. 加载完后 onload() 中用 traverse() 对每个子对象进行遍历, 设置 material 属性. 就是說可以遍歷孩子進行設置東西。 // OBJLoader() // .setMaterials(materials材质数组)设置 MTLLoader 加载的材质或其他材质数组. // .setPath( value路径 ) 设置原始文件的基本路径. // .parse( text待解析的 text 数据 )解析 text 数据. // .load( url加載路徑, onLoad加載完成函數, onProgress, onError ) : null new OBJLoader().setMaterials(materials).setPath('/static/model/modelFirst/').load('modelFirst.obj', obj => { obj.scale.set(0.8, 0.8, 0.8); obj.position.set(-40, -50, 10); this.addSprite(-95, -55, -110, '/static/image/shoop.png', -70, 'SKECH', obj, function () { }); this.addSprite(-80, -65, -90, '/static/image/cloth.png', -52, 'FILA', obj, function () { }); this.addSprite(-100, -45, -80, '/static/image/apple.png', -63, 'APPLE', obj, function () { }); this.scene.add(obj); }); }); new MTLLoader().setPath('/static/model/VANS/').load('VANS.mtl', materials => { materials.preload(); new OBJLoader().setMaterials(materials).setPath('/static/model/VANS/').load('VANS.obj', obj => { obj.scale.set(0.8, 0.8, 0.8); obj.position.set(-40, -50, 10); this.addSprite(-165, -55, -170, '/static/image/vans.png', -58, 'VANS', obj, () => { this.viewDetailModel(); }); this.scene.add(obj) }) }); new MTLLoader().setPath('/static/model/LEVIS/').load('LEVIS.mtl', materials => { materials.preload(); new OBJLoader().setMaterials(materials).setPath('/static/model/LEVIS/').load('LEVIS.obj', obj => { obj.scale.set(0.8, 0.8, 0.8); obj.position.set(-40, -50, 10); this.addSprite(-170, -40, -100, '/static/image/television.png', -64, 'LEVIS', obj, function () { }); this.addSprite(-170, -35, -120, '/static/image/jac.png', -100, 'KORADIOP', obj, function () { }); this.addSprite(-170, -40, -140, '/static/image/clo.png', -47, '天意', obj, function () { }); this.scene.add(obj) }) }); new MTLLoader().setPath('/static/model/sanxing/').load('sanxing.mtl', materials => { materials.preload(); new OBJLoader().setMaterials(materials).setPath('/static/model/sanxing/').load('sanxing.obj', obj => { obj.scale.set(0.8, 0.8, 0.8); obj.position.set(-40, -50, 10); this.addSprite(-125, -40, -98, '/static/image/phone.png', -50, '三星', obj, function () { }); this.scene.add(obj) }) }); new MTLLoader().setPath('/static/model/CA/').load('CA.mtl', materials => { materials.preload(); new OBJLoader().setMaterials(materials).setPath('/static/model/CA/').load('CA.obj', obj => { obj.scale.set(0.8, 0.8, 0.8); obj.position.set(-40, -50, 10); this.addSprite(-130, -35, -60, '/static/image/car.png', -37, 'CA', obj, function () { }); this.scene.add(obj) }) }); new MTLLoader().setPath('/static/model/SHOES/').load('SHOES.mtl', materials => { materials.preload(); new OBJLoader().setMaterials(materials).setPath('/static/model/SHOES/').load('SHOES.obj', obj => { obj.scale.set(0.8, 0.8, 0.8); obj.position.set(-40, -50, 10); this.addSprite(-90, -50, -155, '/static/image/shoes.png', -70, 'SHOES', obj, function () { }); this.scene.add(obj) }) }); new MTLLoader().setPath('/static/model/square/').load('zhengfangxing.mtl', materials => { materials.preload(); new OBJLoader().setMaterials(materials).setPath('/static/model/square/').load('zhengfangxing.obj', obj => { obj.scale.set(0.8, 0.8, 0.8); obj.position.set(-40, -50, 10); this.addSprite(-90, -50, -55, '/static/image/sensor.png', -95, '传感器节点', obj, () => { this.alarmDetail(); }); this.scene.add(obj) }) }); new MTLLoader().setPath('/static/model/LOHO/').load('LOHO.mtl', materials => { materials.preload(); new OBJLoader().setMaterials(materials).setPath('/static/model/LOHO/').load('LOHO.obj', obj => { obj.scale.set(0.8, 0.8, 0.8); obj.position.set(-40, -50, 10); this.addSprite(-30, -55, -180, '/static/image/lv.png', -67, 'LOHO', obj, () => { }); this.addSprite(-30, -55, -160, '/static/image/card.png', -68, '卡连劳', obj, () => { }); this.addSprite(50, -55, -160, '/static/image/liangshi.png', -79, '无印良品', obj, () => { }); this.scene.add(obj) }) }); new MTLLoader().setPath('/static/model/TWICE/').load('TWICE.mtl', materials => { materials.preload(); new OBJLoader().setMaterials(materials).setPath('/static/model/TWICE/').load('TWICE.obj', obj => { obj.scale.set(0.8, 0.8, 0.8); obj.position.set(-40, -50, 10); this.addSprite(-20, -55, -110, '/static/image/demand.png', -71, 'TWICE', obj, () => { }); this.addSprite(-20, -55, -90, '/static/image/lifang.png', -64, '3D-JP', obj, () => { }); this.addSprite(-20, -55, -70, '/static/image/dance.png', -69, 'CASIO', obj, () => { }); this.addSprite(30, -55, -120, '/static/image/sleep.png', -80, 'HAZZYS', obj, () => { }); this.scene.add(obj) }) }); new MTLLoader().setPath('/static/model/manji/').load('manji.mtl', materials => { materials.preload(); new OBJLoader().setMaterials(materials).setPath('/static/model/manji/').load('manji.obj', obj => { obj.scale.set(0.8, 0.8, 0.8); obj.position.set(-40, -50, 10); this.addSprite(30, -55, -70, '/static/image/candy.png', -79, '满记甜食', obj, () => { }); this.scene.add(obj) }) }); new MTLLoader().setPath('/static/model/REPUBLIC/').load('REPUBLIC.mtl', materials => { materials.preload(); new OBJLoader().setMaterials(materials).setPath('/static/model/REPUBLIC/').load('REPUBLIC.obj', obj => { obj.scale.set(0.8, 0.8, 0.8); obj.position.set(-40, -50, 10); this.addSprite(90, -45, -70, '/static/image/puhblic.png', -126, 'REPUBLIC&CO', obj, () => { }); this.addSprite(70, -70, -70, '/static/image/humbar.png', -66, '汉堡王', obj, () => { }); this.scene.add(obj) }) }); new MTLLoader().setPath('/static/model/JUSTCAVALLI/').load('JUSTCAVALLI.mtl', materials => { materials.preload(); new OBJLoader().setMaterials(materials).setPath('/static/model/JUSTCAVALLI/').load('JUSTCAVALLI.obj', obj => { obj.scale.set(0.8, 0.8, 0.8); obj.position.set(-40, -50, 10); this.addSprite(140, -45, -80, '/static/image/juice.png', -126, 'JUST CAVALLI', obj, () => { }); this.scene.add(obj) }) }); new MTLLoader().setPath('/static/model/taizhuolong/').load('taizhuolong.mtl', materials => { materials.preload(); new OBJLoader().setMaterials(materials).setPath('/static/model/taizhuolong/').load('taizhuolong.obj', obj => { obj.scale.set(0.8, 0.8, 0.8); obj.position.set(-40, -50, 10); this.addSprite(120, -45, -120, '/static/image/long.png', -73, '泰卓龙', obj, () => { }); this.scene.add(obj) }) }); }, addSprite(x, y, z, image, loc, text, Mash, callback) { //添加div标签 this.biaozhudiv = document.createElement('div'); //添加图标标签 this.img = document.createElement('img'); this.img.src = image; this.img.style.marginLeft = loc + 'px'; this.biaozhudiv.className = 'lable'; //两者的执行顺序 this.biaozhudiv.textContent = text; this.biaozhudiv.appendChild(this.img); //标注的样式 this.biaozhudiv.id = 'biaozhu'; this.biaozhudiv.style.color = 'rgb(' + 0 + ',' + 0 + ',' + 0 + ')'; this.biaozhudiv.style.fontSize = 15 + 'px'; this.biaozhudiv.style.fontFamily = 'Georgia,serif'; this.biaozhudiv.style.cursor = 'pointer'; this.biaozhudiv.onclick = function () { callback(Mash); }; this.biaozhuLabel = new CSS2DObject(this.biaozhudiv); this.biaozhuLabel.position.set(x, y, z); Mash.add(this.biaozhuLabel); }, //传感器详情界面 alarmDetail() { this.$router.push('alarmPage'); console.log("跳转到传感器详情界面"); }, //点击模块查看信息的3D界面 viewDetailModel() { // this.fov = 80; // //改变相机 // this.camera = new THREE.PerspectiveCamera(this.fov, window.innerWidth / window.innerHeight, 1, 1000); // this.camera.position.set(-20, 20, 35); // this.camera.lookAt(this.scene.position); // //控制器 // this.controls = new OrbitControls(this.camera); // this.controls.target.set(0, 0, 0); // this.controls.minDistance = 80; // this.controls.maxDistance = 400; // this.controls.maxPolarAngle = Math.PI / 3; // this.controls.update(); console.log("清除场景"); } } } </script> <style scoped> </style>