salary-management-oneself/src/lib/three/Viewer/index.ts

101 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { AxesHelper, Camera, PerspectiveCamera, Scene, WebGLRenderer } from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
export type Animate = {
fun: (arg: any) => any;
content: any;
};
export default class Viewer {
public id: string;
public viewerDom!: HTMLElement;
public renderer!: WebGLRenderer;
public scene!: Scene;
public camera!: PerspectiveCamera;
public controls!: OrbitControls;
public isDestroy = false; // 是否销毁
public animateEventList = new Map();
constructor(id: string) {
this.id = id;
this.initViewer();
}
private initViewer() {
this.initRender();
this.initScene();
this.initCamera();
this.initControl();
const animate = () => {
if (this.isDestroy) return;
requestAnimationFrame(animate);
this.updateDom();
this.renderDom();
// 全局的公共动画函数,添加函数可同步执行
this.animateEventList.forEach((event) => {
if (event.fun && event.content) event.fun(event.content);
});
};
animate();
}
private initRender() {
// 获取画布dom
this.viewerDom = document.getElementById(this.id) as HTMLElement;
this.renderer = new WebGLRenderer({ antialias: true });
this.viewerDom.appendChild(this.renderer.domElement);
}
// 创建场景
private initScene() {
this.scene = new Scene();
}
private initControl() {
this.controls = new OrbitControls(this.camera as Camera, this.renderer?.domElement);
this.controls.enableDamping = false;
this.controls.screenSpacePanning = false;
this.controls.minDistance = 2;
this.controls.maxDistance = 1000;
}
// 初始化相机
public initCamera() {
this.camera = new PerspectiveCamera(75, this.viewerDom.clientWidth / this.viewerDom.clientHeight, 0.1, 1000);
this.camera.position.set(5, 5, 10);
this.camera.lookAt(0, 0, 0);
}
//创建坐标轴辅助对象
public addAxis() {
const axis = new AxesHelper(1000);
this.scene?.add(axis);
}
// 添加动画事件
public addAnimate(id: string, animate: Animate) {
this.animateEventList.set(id, animate);
}
// 根据传入的id删除动画事件列表中的对应事件
public removeAnimate(id: string) {
this.animateEventList?.delete(id);
}
// 更新参数
public updateDom() {
this.camera.aspect = this.viewerDom.clientWidth / this.viewerDom.clientHeight; // 摄像机视锥体的长宽比,通常是使用画布的宽/画布的高
this.camera.updateProjectionMatrix(); // 更新摄像机投影矩阵。在任何参数被改变以后必须被调用,来使得这些改变生效
this.renderer.setSize(this.viewerDom.clientWidth, this.viewerDom.clientHeight);
this.renderer.setPixelRatio(window.devicePixelRatio); // 设置设备像素比
}
// 渲染dom
public renderDom() {
this.renderer?.render(this.scene as Scene, this.camera as Camera);
}
}