ThingOrigin.js & three.js
创建场景对比
before ::: code-group
js
//引入three.js
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
// 获取dom元素
let sceneDom = document.getElementById('TO')
// 创建场景
const scene = new THREE.Scene()
// 创建相机
const camera = new THREE.PerspectiveCamera(75, sceneDom.clientWidth / sceneDom.clientHeight, 0.1, 1000)
camera.position.set(10, 10, 10)
// 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(window.innerWidth, sceneDom.clientHeight)
renderer.setPixelRatio(window.devicePixelRatio)
sceneDom.appendChild(renderer.domElement)
// 添加轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
controls.dampingFactor = 0.05
// 创建网格辅助线
const gridHelper = new THREE.GridHelper(20, 20, 0x888888, 0x444444)
scene.add(gridHelper)
// 创建坐标轴辅助线
const axesHelper = new THREE.AxesHelper(10)
scene.add(axesHelper)
// 创建天空盒
const createSkybox = () => {
const loader = new THREE.CubeTextureLoader()
const texture = loader.load([
'./skybox/px.jpg',
'./skybox/nx.jpg',
'./skybox/py.jpg',
'./skybox/ny.jpg',
'./skybox/pz.jpg',
'./skybox/nz.jpg'
])
scene.background = texture
}
// 调用天空盒函数
createSkybox()
// 添加环境光
const ambientLight = new THREE.AmbientLight(0x404040)
scene.add(ambientLight)
// 添加方向光
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5)
directionalLight.position.set(1, 1, 1)
scene.add(directionalLight)
// 动画循环
function animate() {
requestAnimationFrame(animate)
controls.update()
renderer.render(scene, camera)
}
// 处理窗口大小变化
window.addEventListener('resize', () => {
camera.aspect = sceneDom.clientWidth / sceneDom.clientHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, sceneDom.clientHeight)
})
animate():::
after ::: code-group
js
let TO = new ThingOrigin('TOScene', document.getElementById('TO')):::
TOScene 为自定义的场景名称。
document.getElementById('TO') 为用于渲染的 dom 元素。
总结:通过简化API设计和提供预制组件,大幅减少了开发3D场景所需的代码量
控制模型旋转对比
before ::: code-group
js
// 定义目标旋转角度(弧度制)
const targetRotationY = Math.PI / 2 // 90度
// 创建 Tween 动画
// 定义旋转角度(以度为单位)
const startAngle = 0 // 起始角度
const endAngle = 90 // 结束角度
// 创建Tween动画
const rotationTween = new TWEEN.Tween({ angle: startAngle })
.to({ angle: endAngle }, 1000) // 1秒内从0度旋转到90度
.easing(TWEEN.Easing.Quadratic.InOut) // 使用缓动函数
.onUpdate(function () {
// 将角度转换为弧度(Three.js使用弧度)
const radians = THREE.MathUtils.degToRad(this.angle)
// 更新模型1的旋转
model1.rotation.y = radians
})
.onComplete(function () {
console.log('旋转动画完成')
})
.start():::
after ::: code-group
js
//找到模型对象
let rotateModel = TO.scene.getObjectByProperty('name', 'WS30-1')
//模型绕y轴旋转180度,旋转时间为2秒
TO.animate.rotateAxis(rotateModel, 'y', 0, 180, 2000, 0, 'deg'):::
总结:对比来看,控制模型旋转代码就由原来的十几行代码简化为一行代码