import { onMounted } from 'vue' import * as THREE from 'three' import { OrbitControls } from 'three/addons/controls/OrbitControls.js' import * as TT from './threejs-tools' export default class ThreejsManager { constructor(container) { // init scene camera this.scene = new THREE.Scene() // init renderer this.renderer = new THREE.WebGLRenderer() this.animateFuncs = {} const animate = () => { requestAnimationFrame(animate) Object.values(this.animateFuncs).forEach(animFunc => animFunc()) this.renderer.render(this.scene, this.camera) } onMounted(() => { container.value.appendChild(this.renderer.domElement) this.renderer.setSize(container.value.clientWidth, container.value.clientHeight) this.camera = new THREE.PerspectiveCamera(60, container.value.clientWidth / container.value.clientHeight, 0.1, 1000) this.camera.position.set(0, 10, 10) this.controls = new OrbitControls(this.camera, this.renderer.domElement); animate() }) this.initDefaultScene() } initDefaultScene() { this.scene.add(new THREE.GridHelper(100, 100, 0x660000, 0x004400)) this.addPlane() this.addCube() this.lightHelpers = [] this.lightHelpers.push(this.addAmbientLight()) this.lightHelpers.push(this.addDirectLight()) this.lightHelpers.push(this.addPointLight()) this.lightHelpers.push(this.addSpotLight()) } onAnimate(name, animFunc) { this.animateFuncs[name] = animFunc } addPlane() { const plane = TT.createPlane() this.scene.add(plane) return plane } addCube() { const cube = TT.createCube() cube.position.y = 1 this.onAnimate('cube', () => { cube.rotation.x += 0.01 cube.rotation.y += 0.01 }) this.scene.add(cube) return cube } addAmbientLight() { return TT.addLight(this.scene, THREE.AmbientLight, [0xffffff, .1]) } addDirectLight() { return TT.addLight(this.scene, THREE.DirectionalLight, [0xff0000, 1], [-4, 5, -3]) } addPointLight() { return TT.addLight(this.scene, THREE.PointLight, [0x00ff00, 50], [3, 3, -2], .5) } addSpotLight() { return TT.addLight(this.scene, THREE.SpotLight, [0x0000ff, 1000, 7, .2, .5], [-1, 6, 1]) } }