import { ref, reactive, toRef, watch, 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() { this.animateFuncs = {} this.lights = reactive([]) } addScene() { this.scene = new THREE.Scene() } addRenderer() { this.renderer = new THREE.WebGLRenderer() } startRender(container) { this.renderer.rendering = true 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); this.animate() } animate() { if (!this.renderer.rendering) { return } requestAnimationFrame(this.animate.bind(this)) Object.values(this.animateFuncs).forEach(animFunc => animFunc()) this.renderer.render(this.scene, this.camera) } initDefaultScene() { this.scene.add(new THREE.GridHelper(100, 100, 0x660000, 0x004400)) this.addPlane() this.addCube() this.addAmbientLight() } 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() { const light = TT.createLight(THREE.AmbientLight, [0xffffff, .1]) this.scene.add(light) this.lights.push(light) light.name = light.type + `-` + this.lights.length return light } addDirectLight() { const light = TT.createLight(THREE.DirectionalLight, [0xff0000, 1], [-4, 5, -3]) this.scene.add(light) this.lights.push(light) light.name = light.type + `-` + this.lights.length return light } addPointLight() { const light = TT.createLight(THREE.PointLight, [0x00ff00, 50, 10], [3, 3, -2]) this.scene.add(light) this.lights.push(light) light.name = light.type + `-` + this.lights.length return light } addSpotLight() { const light = TT.createLight(THREE.SpotLight, [0x0000ff, 1000, 7, .2, .5], [-1, 6, 1]) this.scene.add(light) this.lights.push(light) light.name = light.type + `-` + this.lights.length return light } }