<script> import * as Three from 'three' import { DoubleSide, TextureLoader } from 'three' import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
export default { data () { return { camera: null, scene: null, renderer: null, mesh: null, controls: null } },
mounted () { this.init() this.drawBox() this.drawSkyBox() this.drawLine() this.animate()
window.addEventListener("resize", this.onWindowResize, false); //添加窗口监听事件(resize-onresize即窗口或框架被重新调整大小) },
methods: {
//初始化 init() { let container = document.getElementById('container') // 获取页面元素 this.camera = new Three.PerspectiveCamera(70, container.clientWidth / container.clientHeight, 0.01, 100) // 创建像机(视野角度, 长宽比, 近截面, 远截面) this.camera.position.z = 2 // 相机移动 this.scene = new Three.Scene() // 创建场景 // let geometry = new Three.BoxGeometry(0.2, 0.2, 0.2) // 创建立方体 // let material = new Three.MeshNormalMaterial() // 创建材质 // this.mesh = new Three.Mesh(geometry, material) // 创建网格 // this.scene.add(this.mesh) // 将网格加入场景
this.renderer = new Three.WebGLRenderer({antialias: true}) // 创建渲染器 antialias: true消除锯齿 this.renderer.setSize(container.clientWidth, container.clientHeight) // 设置渲染器尺寸 container.appendChild(this.renderer.domElement) // 将渲染器的dom元素添加到页面中
//初始化控制器 this.controls = new OrbitControls(this.camera, this.renderer.domElement); this.controls.target.set(0, 0, 0); this.controls.update(); }, // 添加贴图 setLoader() { let textureLoader = new Three.TextureLoader
var boxImg = require('../assets/box.jpg') let boxTexture = textureLoader.load(boxImg) return boxTexture },
drawBox() { let boxTexture = this.setLoader() let geometry = new Three.BoxGeometry(0.2, 0.2, 0.2) // 创建立方体 let material = new Three.MeshBasicMaterial({ map: boxTexture, side: DoubleSide }) // 创建材质 map: boxTexture使用贴图boxTexture side: doubleSide双面渲染 this.mesh = new Three.Mesh(geometry, material) // 创建网格 this.mesh.name = 'box' // 网格命名,方便之后调用 this.scene.add(this.mesh) },
// 绘制天空盒子(四面材质不同并且双面渲染的巨型盒子, 暂时用随意的图片替代) drawSkyBox() { let skyBox = new Three.BoxGeometry(10, 10, 10) // 创建立方体
let textureLoader = new Three.TextureLoader var boxImg = require('../assets/box.jpg') let boxTexture = textureLoader.load(boxImg) var catImg = require('../assets/cat.jpg') let catTexture = textureLoader.load(catImg) let skyBoxMaterialList = [ new Three.MeshBasicMaterial({ map: boxTexture, side: DoubleSide }), new Three.MeshBasicMaterial({ map: boxTexture, side: DoubleSide }), new Three.MeshBasicMaterial({ map: boxTexture, side: DoubleSide }), new Three.MeshBasicMaterial({ map: boxTexture, side: DoubleSide }), new Three.MeshBasicMaterial({ map: boxTexture, side: DoubleSide }), new Three.MeshBasicMaterial({ map: catTexture, side: DoubleSide }) ] let sky = new Three.Mesh(skyBox, skyBoxMaterialList) // 创建网格 this.scene.add(sky) },
drawLine() { let material = new Three.LineBasicMaterial( { color: 0x0000ff } ); let geometry = new Three.Geometry(); geometry.vertices.push(new Three.Vector3( -1, 0, 0) ); // 设置线条顶点 geometry.vertices.push(new Three.Vector3( 0, 1, 0) ); geometry.vertices.push(new Three.Vector3( 1, 0, 0) ); geometry.vertices.push(new Three.Vector3( 0, -1, 0) ); geometry.vertices.push(new Three.Vector3( -1, 0, 0) ); var line = new Three.Line( geometry, material ); this.scene.add(line) },
//渲染及动画效果 animate() { requestAnimationFrame(this.animate) // 动画循环 // // let box = this.scene.getObjectByName('box') // 使用mesh命名操作mesh,效果同下 // // box.rotation.x += 0.01 // // box.rotation.y += 0.02
// this.mesh.rotation.x += 0.01 // this.mesh.rotation.y += 0.02 this.renderer.render(this.scene, this.camera) },
//窗口监听函数 onWindowResize() { // 模型比例调整 this.camera.aspect = window.innerWidth / window.innerHeight; this.camera.updateProjectionMatrix(); this.renderer.setSize(window.innerWidth, window.innerHeight); }, } } </script> <style scoped> #container { height: 100vh; } </style>