首页 > 其他分享 >NOTE

NOTE

时间:2023-02-09 22:24:25浏览次数:26  
标签:Base const private NOTE base new import

/Users/song/Code/threejs_learn_vanilla_class_singleton/threejs_learn_vanilla_ts_class_singleton/src/threejs_全局事件管理/Base.ts

import { Light, Object3D, Scene, Vector2 } from "three";

import Camera from "./Cameras";
import Helper from "./Helpers";
import Renderer from "./Renderer";
import Size from "./Size";
import Time from "./Time";
import Box from "./World/Box";
import Control from "./Controls";
import Lights from "./Lights";
import EventManger from "./Events";

export default class Base {
  public static base: Base;
  public canvas: HTMLCanvasElement;
  public scene: Scene;
  public cameras: Camera;
  public size: Size;
  public time: Time;
  public renderer: Renderer;
  public control: Control;
  public helper: Helper;
  public eventManger: EventManger;
  public noTransfromControlObjs: Object3D[] = [];

  constructor(canvas: HTMLCanvasElement) {
    Base.base = this;

    this.canvas = canvas as HTMLCanvasElement;
    this.scene = new Scene();
    this.size = new Size();
    this.cameras = new Camera();
    this.time = new Time();
    this.renderer = new Renderer();
    new Lights();

    // helper
    const helper = new Helper();
    this.helper = helper;
    this.noTransfromControlObjs.push(helper.gridHelper, helper.axesHelper);

    // control
    const control = new Control();
    this.control = control;
    this.noTransfromControlObjs.push(this.control.transformControl);
    // events
    this.eventManger = new EventManger();

    // 使用EventManager实例注册的事件,就是相当于全局事件,
    this.eventManger.addEventListener("click", (e) => {
      console.log("点击射线穿过了下面这些物体");
      console.log(e);
    });

    // -----------------------
    new Box();

    this.time.on("update", () => {
      this.update();
    });
    this.size.on("resize", () => {
      this.resize();
    });
  }

  public static getInstance(canvas?: HTMLCanvasElement) {
    if (canvas === undefined && Base.base !== undefined) {
      return Base.base;
    }
    Base.base = new Base(canvas as HTMLCanvasElement);
    return Base.base;
  }

  private resize() {
    this.cameras.resize();
    this.renderer.resize();
  }

  private update() {
    this.control.update();
    this.renderer.update();
  }
}

/Users/song/Code/threejs_learn_vanilla_class_singleton/threejs_learn_vanilla_ts_class_singleton/src/threejs_全局事件管理/Helpers.ts

import { AxesHelper, GridHelper } from "three";
import Base from "./Base";

export default class {
  public axesHelper: AxesHelper;
  public gridHelper: GridHelper;
  constructor() {
    const base = Base.getInstance();
    const axesHelper = new AxesHelper(5);
    this.axesHelper = axesHelper;
    base.scene.add(axesHelper);

    const size = 10;
    const divisions = 10;

    const gridHelper = new GridHelper(size, divisions);
    this.gridHelper = gridHelper;
    base.scene.add(gridHelper);
  }
}

/Users/song/Code/threejs_learn_vanilla_class_singleton/threejs_learn_vanilla_ts_class_singleton/src/threejs_全局事件管理/Lights.ts

import { AmbientLight, DirectionalLight } from "three";
import Base from "./Base";

export default class Environment {
  private sunLight: DirectionalLight;
  private ambientLight: AmbientLight;
  constructor() {
    const base = Base.getInstance();
    this.sunLight = new DirectionalLight("#ffffff", 2);
    this.sunLight.castShadow = true;
    this.sunLight.shadow.camera.far = 20;
    this.sunLight.shadow.mapSize.set(2048, 2048);
    this.sunLight.shadow.normalBias = 0.05;

    this.sunLight.position.set(-1.5, 7, 10);
    base.scene.add(this.sunLight);

    this.ambientLight = new AmbientLight("#ffffff", 0.1);
    base.scene.add(this.ambientLight);
  }
}

/Users/song/Code/threejs_learn_vanilla_class_singleton/threejs_learn_vanilla_ts_class_singleton/src/threejs_全局事件管理/Cameras.ts

import { PerspectiveCamera, Scene } from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import Base from "./Base";
import type Size from "./Size";

export default class Camera {
  private size: Size;
  private scene: Scene;
  private canvas: HTMLCanvasElement;
  public perspectiveCamera: PerspectiveCamera;
  // private controls: OrbitControls;

  constructor() {
    const base = Base.getInstance();
    this.size = base.size;
    this.scene = base.scene;
    this.canvas = base.canvas;

    this.perspectiveCamera = this.createPerspectiveCamera();
    this.scene.add(this.perspectiveCamera);
  }
  private createPerspectiveCamera() {
    const perspectiveCamera = new PerspectiveCamera(
      35,
      this.size.aspect,
      0.1,
      1000
    );
    perspectiveCamera.position.set(15, 30, 20);
    return perspectiveCamera;
  }

  public resize() {
    // Updating Perspective Camera on Resize
    this.perspectiveCamera.aspect = this.size.aspect;
    this.perspectiveCamera.updateProjectionMatrix();
  }
}

/Users/song/Code/threejs_learn_vanilla_class_singleton/threejs_learn_vanilla_ts_class_singleton/src/threejs_全局事件管理/Size.ts

import EventEmitter from "eventemitter2";
export default class Size extends EventEmitter {
  public width: number;
  public height: number;
  public aspect: number;
  public pixelRatio: number;

  constructor() {
    super();
    this.width = window.innerWidth;
    this.height = window.innerHeight;
    this.aspect = this.width / this.height;
    this.pixelRatio = Math.min(window.devicePixelRatio, 2);

    window.addEventListener("resize", () => {
      this.width = window.innerWidth;
      this.height = window.innerHeight;
      this.aspect = this.width / this.height;
      this.pixelRatio = Math.min(window.devicePixelRatio, 2);
      this.emit("resize");
    });
  }
}

/Users/song/Code/threejs_learn_vanilla_class_singleton/threejs_learn_vanilla_ts_class_singleton/src/threejs_全局事件管理/Events.ts

import {
  Camera,
  EventDispatcher,
  Object3D,
  Raycaster,
  Scene,
  Vector2,
} from "three";
import Base from "./Base";

export default class EventManger extends EventDispatcher {
  private raycaster: Raycaster = new Raycaster();
  private mouse: Vector2 = new Vector2();
  private dom: HTMLCanvasElement;
  private scene: Scene;
  private camera: Camera;
  constructor() {
    super();
    const base = Base.getInstance();

    this.dom = base.canvas;
    this.scene = base.scene;
    this.camera = base.cameras.perspectiveCamera;

    const mouse = this.mouse;
    const raycaster = this.raycaster;
    const dom = this.dom;

    let cacheObject: Object3D | null = null;

    dom.addEventListener("mousedown", (event) => {
      // 选取物体的操作
      raycaster.setFromCamera(mouse, this.camera);
      const intersection = raycaster.intersectObjects(this.scene.children);

      // 这里将事件派发到this上面,相当于注册全局事件,也就是将事件派发到EventManager的实例上面
      this.dispatchEvent({
        type: "mousedown",
        intersection,
      });

      if (intersection.length) {
        const object = intersection[0].object;
        // 派发事件到3d物体上面
        object.dispatchEvent({
          type: "mousedown",
        });
      }
    });

    dom.addEventListener("mousemove", (event) => {
      mouse.x = (event.offsetX / dom.offsetWidth) * 2 - 1;
      mouse.y = (-event.offsetY * 2) / dom.offsetHeight + 1;

      // 选取物体的操作
      raycaster.setFromCamera(mouse, this.camera);

      const intersection = raycaster.intersectObjects(this.scene.children);

      // 全局派发事件
      this.dispatchEvent({
        type: "mousemove",
        intersection,
      });

      if (intersection.length) {
        const object = intersection[0].object;

        if (object !== cacheObject) {
          if (cacheObject) {
            cacheObject.dispatchEvent({
              type: "mouseleave",
            });
          }
          object.dispatchEvent({
            type: "mouseenter",
          });
        } else if (object === cacheObject) {
          object.dispatchEvent({
            type: "mousemove",
          });
        }
        cacheObject = object;
      } else {
        if (cacheObject) {
          cacheObject.dispatchEvent({
            type: "mouseleave",
          });
        }
        cacheObject = null;
      }
    });

    dom.addEventListener("mouseup", (event) => {
      // 选取物体的操作
      raycaster.setFromCamera(mouse, this.camera);
      const intersection = raycaster.intersectObjects(this.scene.children);

      this.dispatchEvent({
        type: "mouseup",
        intersection,
      });
      if (intersection.length) {
        const object = intersection[0].object;
        object.dispatchEvent({
          type: "mouseup",
        });
      }
    });

    dom.addEventListener("click", (event) => {
      // 选取物体的操作
      raycaster.setFromCamera(mouse, this.camera);
      const intersection = raycaster.intersectObjects(this.scene.children);

      this.dispatchEvent({
        type: "click",
        intersection,
      });

      if (intersection.length) {
        const object = intersection[0].object;
        object.dispatchEvent({
          type: "click",
        });
      }
    });
  }
}

/Users/song/Code/threejs_learn_vanilla_class_singleton/threejs_learn_vanilla_ts_class_singleton/src/threejs_全局事件管理/Renderer.ts

import * as THREE from "three";
import Base from "./Base";
import { Scene, WebGLRenderer } from "three";
import Camera from "./Cameras";
import Size from "./Size";

export default class Renderer {
  private size: Size;
  private scene: Scene;
  private canvas: HTMLCanvasElement;
  private camera: Camera;
  private renderer: WebGLRenderer;

  constructor() {
    const base = Base.getInstance();

    this.size = base.size;
    this.scene = base.scene;
    this.canvas = base.canvas;
    this.camera = base.cameras;

    this.renderer = this.setRenderer();
  }

  setRenderer() {
    const renderer = new WebGLRenderer({
      canvas: this.canvas,
      antialias: true,
    });

    renderer.physicallyCorrectLights = true;
    renderer.outputEncoding = THREE.sRGBEncoding;
    renderer.toneMapping = THREE.CineonToneMapping;
    renderer.toneMappingExposure = 1.75;
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    renderer.setSize(this.size.width, this.size.height);
    renderer.setPixelRatio(this.size.pixelRatio);

    return renderer;
  }

  resize() {
    this.renderer.setSize(this.size.width, this.size.height);
    this.renderer.setPixelRatio(this.size.pixelRatio);
  }

  update() {
    this.renderer.render(this.scene, this.camera.perspectiveCamera);
  }
}

/Users/song/Code/threejs_learn_vanilla_class_singleton/threejs_learn_vanilla_ts_class_singleton/src/threejs_全局事件管理/Controls.ts

import {
  TransformControls,
  TransformControlsGizmo,
  TransformControlsPlane,
} from "three/examples/jsm/controls/TransformControls";
import Base from "./Base";
import {
  AxesHelper,
  GridHelper,
  Line,
  MOUSE,
  Object3D,
  PerspectiveCamera,
  Raycaster,
  Scene,
  Vector2,
} from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

export default class Control {
  public transformControl: TransformControls;
  public orbitControl: OrbitControls;
  private base: Base;
  private camera: PerspectiveCamera;
  private canvas: HTMLCanvasElement;
  private scene: Scene;
  private transing: boolean;
  constructor() {
    const base = Base.getInstance();
    this.base = base;

    this.camera = base.cameras.perspectiveCamera;
    this.canvas = base.canvas;
    this.scene = base.scene;

    // 正在变换的标志位
    this.transing = false;
    this.transformControl = this.createTransformControl();
    this.initTransformControlEvent();
    this.scene.add(this.transformControl);
    this.orbitControl = this.createOrbitControl();
  }

  private createTransformControl() {
    const transformControls = new TransformControls(this.camera, this.canvas);
    return transformControls;
  }

  private initTransformControlEvent() {
    this.transformControl.addEventListener("mouseDown", (e) => {
      this.transing = true;
    });
  }

  public update() {
    this.orbitControl.update();
  }

  private createOrbitControl() {
    const controls = new OrbitControls(this.camera, this.canvas);
    controls.enableDamping = true;
    controls.enableZoom = true;
    // 取消鼠标控制器的鼠标左键旋转功能
    controls.mouseButtons = {
      LEFT: null as unknown as MOUSE,
      MIDDLE: MOUSE.DOLLY,
      RIGHT: MOUSE.PAN,
    };

    return controls;
  }
}

/Users/song/Code/threejs_learn_vanilla_class_singleton/threejs_learn_vanilla_ts_class_singleton/src/threejs_全局事件管理/Time.ts

import EventEmitter from "eventemitter2";
import { Clock } from "three";

export default class Time extends EventEmitter {
  public clock: Clock;
  constructor() {
    super();
    this.clock = new Clock();

    this.update();
  }

  update() {
    this.emit("update");
    window.requestAnimationFrame(() => this.update());
  }
}

/Users/song/Code/threejs_learn_vanilla_class_singleton/threejs_learn_vanilla_ts_class_singleton/src/threejs_全局事件管理/World/Box.ts

import {
  BoxGeometry,
  MeshBasicMaterial,
  Mesh,
  MeshLambertMaterial,
  Color,
} from "three";
import Base from "../Base";

export default class Box {
  private cube: Mesh;
  private cubeMaterial: MeshBasicMaterial;

  constructor() {
    const base = Base.getInstance();
    this.cubeMaterial = new MeshBasicMaterial({ color: 0x00ff00 });
    const cube = this.createCube();
    this.cube = cube;
    base.scene.add(cube);
    const cube2 = new Mesh(
      new BoxGeometry(1, 1, 1),
      new MeshBasicMaterial({ color: 0x00ff00 })
    );
    cube2.position.setX(3);
    base.scene.add(cube2);

    this.initCubeEvent();
  }
  private createCube() {
    const cube = new Mesh(new BoxGeometry(1, 1, 1), this.cubeMaterial);
    cube.position.y = 0.5;
    return cube;
  }
  private initCubeEvent() {
    this.cube.addEventListener("mouseenter", (e) => {
      console.log("鼠标进入");
      this.cubeMaterial.color = new Color(0xff0000);
    });
    this.cube.addEventListener("mousemove", (e) => {
      console.log("鼠标正在移动");
    });

    this.cube.addEventListener("mouseleave", (e) => {
      console.log("鼠标离开");
      this.cubeMaterial.color = new Color(0x00ff00);
    });
    this.cube.addEventListener("click", (e) => {
      console.log("鼠标点击");
      this.cubeMaterial.color = new Color(0x0000ff);
    });
  }
}

标签:Base,const,private,NOTE,base,new,import
From: https://www.cnblogs.com/zhuoss/p/17107350.html

相关文章