Skip to content

ThingOrigin.js & three.js

创建场景对比

before

javascript
//引入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

javascript
let TO = new ThingOrigin("TOScene", document.getElementById("TO"))

其中TOScene为自定义的场景名称, --> document.getElementById('TO')为用于渲染的 dom 元素

总结:通过简化API设计和提供预制组件,大幅减少了开发3D场景所需的代码量

控制模型旋转对比

before

javascript
//间补旋转动画(旋转角度)
public rotateAngle(
    model: Object3D,
    axis: string,
    from: number,
    to: number,
    time: number
  ): TWEEN.Tween<any> {
    if (!model) {
      console.warn("旋转(角度)失败,物体不存在");
      return;
    }
    model.updateWorldMatrix(true, true);
    let coords = { t: from };

    return new TWEEN.Tween(coords)
      .to({ t: to }, time)
      .easing(TWEEN.Easing.Linear.None)
      .onUpdate(function () {
        if (axis == "x") {
          model.rotation.x = (coords.t / 180) * Math.PI;
        } else if (axis == "y") {
          model.rotation.y = (coords.t / 180) * Math.PI;
        } else if (axis == "z") {
          model.rotation.z = (coords.t / 180) * Math.PI;
        }
      })
      .start();
  }

after

javascript
//找到模型对象
let rotateModel = TO.scene.getObjectByProperty("name", "WS30-1") 
//模型绕y轴旋转180度,旋转时间为2秒
TO.animate.rotateAngle(rotateModel, 'y', 0, 180, 2000);

总结:对比来看,控制模型旋转代码就由原来的十几行代码简化为一行代码