Files
crowd-funder-for-time-pwa/src/components/World/World.js
Matthew Raymer e5518cd47c fix: update Vue template syntax and improve Vite config
- Fix Vue template syntax in App.vue by using proper event handler format
- Update Vite config to properly handle ESM imports and crypto modules
- Add manual chunks for better code splitting
- Improve environment variable handling in vite-env.d.ts
- Fix TypeScript linting errors in App.vue
2025-04-18 09:59:33 +00:00

111 lines
2.9 KiB
JavaScript

// from https://medium.com/nicasource/building-an-interactive-web-portfolio-with-vue-three-js-part-three-implementing-three-js-452cb375ef80
import * as TWEEN from '@tweenjs/tween.js'
import * as THREE from 'three'
import { createCamera } from './components/camera.js'
import { createLights } from './components/lights.js'
import { createScene } from './components/scene.js'
import { loadLandmarks } from './components/objects/landmarks.js'
import { createTerrain } from './components/objects/terrain.js'
import { Loop } from './systems/Loop.js'
import { Resizer } from './systems/Resizer.js'
import { createControls } from './systems/controls.js'
import { createRenderer } from './systems/renderer.js'
const COLOR1 = '#dddddd'
const COLOR2 = '#0055aa'
class World {
constructor(container, vue) {
this.PLATFORM_BORDER = 5
this.PLATFORM_EDGE_FOR_UNKNOWNS = 10
this.PLATFORM_SIZE = 100 // note that the loadLandmarks calculations may still assume 100
this.update = this.update.bind(this)
this.vue = vue
// Instances of camera, scene, and renderer
this.camera = createCamera()
this.scene = createScene(COLOR2)
this.renderer = createRenderer()
// necessary for models, says https://threejs.org/docs/index.html#examples/en/loaders/GLTFLoader
this.renderer.outputColorSpace = THREE.SRGBColorSpace
this.light = null
this.lights = []
this.bushes = []
// Initialize Loop
this.loop = new Loop(this.camera, this.scene, this.renderer)
container.append(this.renderer.domElement)
// Orbit Controls
const controls = createControls(this.camera, this.renderer.domElement)
// Light Instance, with optional light helper
const { light } = createLights(COLOR1)
// Terrain Instance
const terrain = createTerrain({
color: COLOR1,
height: this.PLATFORM_SIZE + this.PLATFORM_BORDER * 2,
width:
this.PLATFORM_SIZE +
this.PLATFORM_BORDER * 2 +
this.PLATFORM_EDGE_FOR_UNKNOWNS * 2
})
this.loop.updatables.push(controls)
this.loop.updatables.push(light)
this.loop.updatables.push(terrain)
this.scene.add(light, terrain)
loadLandmarks(vue, this, this.scene, this.loop)
requestAnimationFrame(this.update)
// Responsive handler
const resizer = new Resizer(container, this.camera, this.renderer)
resizer.onResize = () => {
this.render()
}
}
update(time) {
TWEEN.update(time)
this.lights.forEach((light) => {
light.updateMatrixWorld()
light.target.updateMatrixWorld()
})
this.lights.forEach((bush) => {
bush.updateMatrixWorld()
})
requestAnimationFrame(this.update)
}
render() {
// draw a single frame
this.renderer.render(this.scene, this.camera)
}
// Animation handlers
start() {
this.loop.start()
}
stop() {
this.loop.stop()
}
setExposedWorldProperties(key, value) {
this.vue.setWorldProperty(key, value)
}
}
export { World }