D:\code_gitee\threejs_learn_vanilla_class_singleton\threejs_learn_vanilla_ts_class_singleton\index.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <link rel="icon" type="image/svg+xml" href="/vite.svg" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title>Vite + TS</title> |
| </head> |
| <body> |
| <div id="app"></div> |
| <script type="module" src="/src/main.ts"></script> |
| </body> |
| </html> |
| |
D:\code_gitee\threejs_learn_vanilla_class_singleton\threejs_learn_vanilla_ts_class_singleton\src\main.ts
| import "./style.css"; |
| |
| import Base from "./threejs/Base"; |
| |
| ((document) => { |
| const oApp = document.getElementById("app")!; |
| const oCanvas = document.createElement("canvas"); |
| oCanvas.style.position = "absolute"; |
| Base.getInstance(oCanvas); |
| oApp.appendChild(oCanvas); |
| })(document); |
| |
D:\code_gitee\threejs_learn_vanilla_class_singleton\threejs_learn_vanilla_ts_class_singleton\src\main_单例模式_constructor.ts
| import "./style.css"; |
| |
| import Base from "./threejs/Base"; |
| |
| ((document) => { |
| const oApp = document.getElementById("app")!; |
| const oCanvas = document.createElement("canvas"); |
| new Base(oCanvas); |
| oApp.appendChild(oCanvas); |
| })(document); |
| |
D:\code_gitee\threejs_learn_vanilla_class_singleton\threejs_learn_vanilla_ts_class_singleton\src\threejs\Base.ts
| import { Scene } from "three"; |
| |
| import Camera from "./Camera"; |
| import Helper from "./Helper"; |
| import Renderer from "./Renderer"; |
| import Size from "./Size"; |
| import Time from "./Time"; |
| import World from "./World/World"; |
| |
| export default class Base { |
| public static base: Base; |
| public canvas: HTMLCanvasElement; |
| public scene: Scene; |
| public camera: Camera; |
| public size: Size; |
| public time: Time; |
| public renderer: Renderer; |
| |
| public world: World; |
| |
| constructor(canvas: HTMLCanvasElement) { |
| Base.base = this; |
| |
| this.canvas = canvas as HTMLCanvasElement; |
| this.scene = new Scene(); |
| this.size = new Size(); |
| this.camera = new Camera(); |
| this.time = new Time(); |
| this.renderer = new Renderer(); |
| new Helper(); |
| |
| this.world = new World(); |
| |
| 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.camera.resize(); |
| this.renderer.resize(); |
| } |
| |
| private update() { |
| this.camera.update(); |
| this.renderer.update(); |
| } |
| } |
| |
D:\code_gitee\threejs_learn_vanilla_class_singleton\threejs_learn_vanilla_ts_class_singleton\src\threejs\Camera.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); |
| |
| this.controls = this.createOrbitControls(); |
| } |
| private createPerspectiveCamera() { |
| const perspectiveCamera = new PerspectiveCamera( |
| 35, |
| this.size.aspect, |
| 0.1, |
| 1000 |
| ); |
| perspectiveCamera.position.set(15, 30, 20); |
| return perspectiveCamera; |
| } |
| private createOrbitControls() { |
| const controls = new OrbitControls(this.perspectiveCamera, this.canvas); |
| controls.enableDamping = true; |
| controls.enableZoom = true; |
| return controls; |
| } |
| public update() { |
| this.controls.update(); |
| } |
| public resize() { |
| |
| this.perspectiveCamera.aspect = this.size.aspect; |
| this.perspectiveCamera.updateProjectionMatrix(); |
| } |
| } |
| |
D:\code_gitee\threejs_learn_vanilla_class_singleton\threejs_learn_vanilla_ts_class_singleton\src\threejs\Helper.ts
| import { AxesHelper, GridHelper } from "three"; |
| import Base from "./Base"; |
| |
| export default class { |
| constructor() { |
| const base = Base.getInstance(); |
| const axesHelper = new AxesHelper(5); |
| base.scene.add(axesHelper); |
| |
| const size = 10; |
| const divisions = 10; |
| |
| const gridHelper = new GridHelper(size, divisions); |
| base.scene.add(gridHelper); |
| } |
| } |
| |
D:\code_gitee\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 "./Camera"; |
| 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.camera; |
| |
| 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); |
| } |
| } |
| |
D:\code_gitee\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"); |
| }); |
| } |
| } |
| |
D:\code_gitee\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()); |
| } |
| } |
| |
D:\code_gitee\threejs_learn_vanilla_class_singleton\threejs_learn_vanilla_ts_class_singleton\src\threejs\World\Environment.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", 3); |
| 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, 3); |
| base.scene.add(this.sunLight); |
| |
| this.ambientLight = new AmbientLight("#ffffff", 1); |
| base.scene.add(this.ambientLight); |
| } |
| } |
| |
D:\code_gitee\threejs_learn_vanilla_class_singleton\threejs_learn_vanilla_ts_class_singleton\src\threejs\World\World.ts
| import { BackSide, Mesh, MeshBasicMaterial, PlaneGeometry } from "three"; |
| import Base from "../Base"; |
| |
| export default class World { |
| private plane: Mesh; |
| constructor() { |
| const base = Base.getInstance(); |
| const geometry = new PlaneGeometry(10, 10); |
| const material = new MeshBasicMaterial({ |
| color: 0xfefefe, |
| side: BackSide, |
| }); |
| this.plane = new Mesh(geometry, material); |
| this.plane.rotateX(Math.PI * 0.5); |
| |
| base.scene.add(this.plane); |
| } |
| } |
| |
D:\code_gitee\threejs_learn_vanilla_class_singleton\threejs_learn_vanilla_ts_class_singleton\src\threejs_单例模式_constructor\Base.ts
| import { Scene } from "three"; |
| |
| import Camera from "./Camera"; |
| |
| export default class Base { |
| public static base: Base; |
| public canvas!: HTMLCanvasElement; |
| public scene!: Scene; |
| public camera!: Camera; |
| |
| constructor(canvas?: HTMLCanvasElement) { |
| if (canvas === undefined && Base.base !== undefined) { |
| return Base.base; |
| } |
| Base.base = this; |
| |
| this.canvas = canvas as HTMLCanvasElement; |
| this.scene = new Scene(); |
| this.camera = new Camera(); |
| } |
| } |
| |
D:\code_gitee\threejs_learn_vanilla_class_singleton\threejs_learn_vanilla_ts_class_singleton\src\threejs_单例模式_constructor\Camera.ts
| import Base from "./Base"; |
| |
| export default class Camera { |
| constructor() { |
| const base = new Base(); |
| console.log(base.canvas); |
| } |
| } |
| |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战