<template>
<div class="container" style="height:100%">
<div id="container"></div>
</div>
</template>
<script setup>
import { onMounted, onBeforeUnmount, getCurrentInstance } from 'vue'
import type { OrbitControls as oc } from 'three/examples/jsm/controls/OrbitControls.js'
import type {
AmbientLight,
AxesHelper,
Clock,
DirectionalLight,
Mesh,
PerspectiveCamera,
HemisphereLight,
OrthographicCamera,
DirectionalLightHelper,
HemisphereLightHelper,
Scene,
WebGLRenderer
} from 'three'
const { proxy } = getCurrentInstance() as any
const three = proxy.$Three
const OrbitControls = proxy.$OrbitControls
let scene: Scene,
renderer: WebGLRenderer,
mesh: Mesh,
camera: PerspectiveCamera,
directionalLight: DirectionalLight,
hemisphereLight: HemisphereLight,
ambientLight: AmbientLight,
dhelper: DirectionalLightHelper,
hHelper: HemisphereLightHelper,
controls: oc;
onMounted(() => {
init()
animate()
initControls()
window.addEventListener('resize', windowResize)
})
onBeforeUnmount( () => {
window.removeEventListener('resize', windowResize)
})
const windowResize = () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
}
const init = () => {
const container: HTMLElement | null = document.getElementById('container')
camera = new three.PerspectiveCamera(70, container!.clientWidth / container!.clientHeight, 0.1, 100)
const axesHelper = new three.AxesHelper(50)
const gridHelper = new three.GridHelper(100, 40, 0x007aff, 0xcccccc)
gridHelper.position.set(0, -1, 0)
// 移動相機
camera.position.z = 1
// 建立場景
scene = new three.Scene()
scene.background = new three.Color(0x000000)
// 建立幾何體
const geometry = new three.BoxGeometry()
const material = new three.MeshNormalMaterial({ color: 0x007aff })
// 建立網格
mesh = new three.Mesh(geometry, material)
mesh.position.set(10, 0, 0)
// this.mesh.translateY(12)
// 添加網格模型
scene.add(mesh)
scene.add(axesHelper)
scene.add(gridHelper)
// 建立渲染器 - 設定顯示視窗大小 antialias// 反鋸齒
renderer = new three.WebGLRenderer({ antialias: true, alpha: true })
renderer.setSize(container!.clientWidth, container!.clientHeight)
container!.appendChild(renderer.domElement)
// renderer.render(scene, camera) // 渲染
}
const initControls = () => {
controls = new OrbitControls(camera, renderer.domElement)
console.log(controls)
// 使動畫循環使用時阻尼或自轉 意思是否有慣性
controls.enableDamping = false
// 是否可以縮放
controls.enableZoom = true
// 是否自動旋轉
controls.autoRotate = false
// 設定相機距離原點的最遠距離
controls.minDistance = 1
// 設定相機距離原點的最遠距離
controls.maxDistance = 10
// 是否開啟右鍵拖拽
controls.enablePan = true
}
const animate = () => {
requestAnimationFrame(animate)
mesh.rotation.x += 0.01
mesh.rotation.y += 0.02
renderer.render(scene, camera)
}
</script>
<style scoped>
#container {
height: 100%;
width: 100%;
}
</style>
// main.ts
import * as Three from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js'
app.config.globalProperties.$Three = Three
app.config.globalProperties.$CSS3DObject = CSS3DObject
app.config.globalProperties.$CSS3DRenderer = CSS3DRenderer
app.config.globalProperties.$OrbitControls = OrbitControls