坐标辅助器和轨道控制器
这是一个可以直接在 VitePress 页面中运行的 Three.js 示例。上方显示运行效果,下方展示对应源码。
运行效果
源码
js
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'
const canvas = document.querySelector('canvas')
const demo = canvas.parentElement
const scene = new THREE.Scene()
scene.background = new THREE.Color('#111827')
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(3, 2, 4)
const renderer = new THREE.WebGLRenderer({
canvas,
antialias: true
})
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
renderer.setSize(window.innerWidth, window.innerHeight)
const geometry = new THREE.BoxGeometry()
const material = new THREE.MeshNormalMaterial()
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)
const axisLength = 2.5
// 强制设置默认坐标轴颜色,避免受材质或渲染状态影响出现类似渐变的观感。
const axesHelper = new THREE.AxesHelper(axisLength)
axesHelper.setColors(0xff0000, 0x00ff00, 0x0000ff)
scene.add(axesHelper)
// ArrowHelper 组合出带箭头的坐标辅助器,用于和默认 AxesHelper 做切换展示。
const arrowAxesHelper = new THREE.Group()
const arrowHeadLength = 0.35
const arrowHeadWidth = 0.18
arrowAxesHelper.add(
new THREE.ArrowHelper(new THREE.Vector3(1, 0, 0), new THREE.Vector3(0, 0, 0), axisLength, 0xff0000, arrowHeadLength, arrowHeadWidth),
new THREE.ArrowHelper(new THREE.Vector3(0, 1, 0), new THREE.Vector3(0, 0, 0), axisLength, 0x00ff00, arrowHeadLength, arrowHeadWidth),
new THREE.ArrowHelper(new THREE.Vector3(0, 0, 1), new THREE.Vector3(0, 0, 0), axisLength, 0x0000ff, arrowHeadLength, arrowHeadWidth)
)
arrowAxesHelper.visible = false
scene.add(arrowAxesHelper)
const gridHelper = new THREE.GridHelper(6, 6)
scene.add(gridHelper)
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
const guiState = {
showAxesHelper: true,
axesHelperType: '默认',
showGridHelper: true
}
const updateAxesHelperVisibility = () => {
const shouldShowAxesHelper = guiState.showAxesHelper
axesHelper.visible = shouldShowAxesHelper && guiState.axesHelperType === '默认'
arrowAxesHelper.visible = shouldShowAxesHelper && guiState.axesHelperType === '箭头'
}
const gui = new GUI({
title: '调试面板',
autoPlace: false
})
gui.domElement.classList.add('three-gui')
demo.appendChild(gui.domElement)
gui
.add(guiState, 'showAxesHelper')
.name('显示坐标辅助器')
.onChange(updateAxesHelperVisibility)
gui
.add(guiState, 'axesHelperType', ['默认', '箭头'])
.name('坐标样式')
.onChange(updateAxesHelperVisibility)
gui
.add(guiState, 'showGridHelper')
.name('显示网格辅助器')
.onChange((value) => {
gridHelper.visible = value
})
function animate() {
requestAnimationFrame(animate)
controls.update()
renderer.render(scene, camera)
}
animate()