restructured rendering, added Tweener & smoothMove

This commit is contained in:
STEINNI
2025-09-27 11:40:33 +00:00
parent 69c9034d73
commit dd3b4f32f4
10 changed files with 967 additions and 146 deletions
+66 -42
View File
@@ -1,24 +1,24 @@
import * as THREE from './three.module.js';
import { OrbitControls } from './OrbitControls.module.js';
import * as THREE from './three.module.js'
import { OrbitControls } from './OrbitControls.module.js'
import * as TWEEN from './tween.module.js'
export class Threetobus{
constructor(canvasEl){
this.canvasEl = canvasEl
constructor(){
this.cameras = {}
this.renderers = []
}
initScene(){
// Scene
this.scene = new THREE.Scene()
this.grid = new THREE.GridHelper(20, 20, 0x444444, 0x888888)
//this.grid.rotation.x = Math.PI / 2 // Default is on the XZ plane → rotate to XY
this.grid = new THREE.GridHelper(20, 20, 0x8888AA, 0x8888AA)
this.scene.add(this.grid)
// Cameras
this.cameras.persp1 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
this.cameras.persp1.position.set(3, 3, 5)
this.cameras.camPerspective = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
this.cameras.camPerspective.position.set(3, 3, 5)
const aspect = window.innerWidth / window.innerHeight
const frustumSize = 10
this.cameras.cam2Dtop = new THREE.OrthographicCamera(
@@ -31,7 +31,6 @@ export class Threetobus{
)
this.cameras.cam2Dtop.position.set(0, 100, 0)
this.cameras.cam2Dtop.lookAt(0, 0, 0)
//this.camera = this.cameras.persp1
// Lights
const light = new THREE.DirectionalLight(0xffffff, 1)
@@ -40,31 +39,21 @@ export class Threetobus{
this.scene.add(light)
this.scene.add(new THREE.AmbientLight(0xffffff, 0.4))
// Renderer
this.renderer = new THREE.WebGLRenderer({ antialias: true, canvas: this.canvasEl })
}
startRendering(mode){
startRendering(canvasEl, mode){
let renderEngine
if(mode=='2D'){
this.changeCamera('cam2Dtop')
} else if(mode=='3D') {
this.changeCamera('persp1')
this.controls = new OrbitControls(this.camera, this.renderer.domElement)
window.addEventListener('resize', () => {
this.camera.aspect = window.innerWidth / window.innerHeight
this.camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
})
}
this.render()
renderEngine = new RenderingEngine(canvasEl, this.scene, this.cameras.cam2Dtop)
} else if(mode=='3D') {
renderEngine = new RenderingEngine(canvasEl, this.scene, this.cameras.camPerspective)
renderEngine.addControls()
} else console.error('Unknown rendering mode !')
renderEngine.render()
this.renderers.push(renderEngine)
}
changeCamera(camName){
if(camName in this.cameras){
this.camera = this.cameras[camName]
}
}
buildFromJSON(desc){
let obj
@@ -93,29 +82,64 @@ export class Threetobus{
return obj
}
_resizeRendererToDisplaySize() {
const canvas = this.renderer.domElement
const width = canvas.clientWidth
const height = canvas.clientHeight
if (canvas.width !== width || canvas.height !== height) {
this.renderer.setSize(width, height, false)
return true
}
return false
smoothRelMove(options){
// options: object, dX, dY, dZ, delay, easing, easingMode
// easings: Linear, Quadratic, Cubic, Quartic, Quintic, Sinusoidal, Exponential, Circular, Elastic, Back, Bounce
// easingMode: In → starts slow, accelerates towards the end.
// Out → starts fast, decelerates smoothly.
// InOut → slow at both ends, faster in the middle.
options.easing = options.easing ? options.easing : 'Quadratic'
options.easingMode = options.easingMode ? options.easingMode : 'InOut'
new TWEEN.Tween(options.object.position)
.to({ x: options.object.position.x + options.dX,
y: options.object.position.y + options.dY,
z: options.object.position.z + options.dZ,
}, options.delay)
.easing(TWEEN.Easing[options.easing][options.easingMode])
.start()
}
}
class RenderingEngine{
constructor(canvasEl, scene, camera){
this.canvasEl = canvasEl
this.scene = scene
this.renderer = new THREE.WebGLRenderer({ antialias: true, canvas: this.canvasEl })
this.camera = camera
}
addControls(){
this.controls = new OrbitControls(this.camera, this.canvasEl)
window.addEventListener('resize', () => {
this.camera.aspect = window.innerWidth / window.innerHeight
this.camera.updateProjectionMatrix()
this.renderer.setSize(window.innerWidth, window.innerHeight)
})
}
render() {
if(this._resizeRendererToDisplaySize()) {
this.camera.aspect = this.renderer.domElement.clientWidth / this.renderer.domElement.clientHeight
TWEEN.update()
if(this.resizeRendererToDisplaySize()) {
this.camera.aspect = this.renderer.domElement.clientWidth / this.canvasEl.clientHeight
this.camera.updateProjectionMatrix()
}
this.renderer.render(this.scene, this.camera)
requestAnimationFrame(this.render.bind(this))
}
}
resizeRendererToDisplaySize() {
const width = this.canvasEl.clientWidth
const height = this.canvasEl.clientHeight
if (this.canvasEl.width !== width || this.canvasEl.height !== height) {
this.renderer.setSize(width, height, false)
return true
}
return false
}
}
// Make this module available to common JS
if(!app.LoadedModules) app.LoadedModules = {}