<template>
<div class="container" style="height:100%">
<div id="container"></div>
</div>
</template>
<script lang='ts' 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 lang="less" 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