<template>
<div>
<div id="container"></div>
</div>
</template>
<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>