@spearwolf/twopoint5d
Version:
Create 2.5D realtime graphics and pixelart with WebGL and three.js
49 lines • 2.13 kB
JavaScript
import { PerspectiveCamera, Vector2 } from 'three/webgpu';
import { ProjectionPlane } from './ProjectionPlane.js';
import { fitIntoRectangle } from './fitIntoRectangle.js';
export class ParallaxProjection {
#viewRect = new Vector2();
#pixelRatio = new Vector2();
#halfHeight;
#near;
#far;
#distanceToProjectionPlane;
#aspect;
#fovy;
constructor(projectionPlane, specs) {
this.projectionPlane = typeof projectionPlane === 'string' ? ProjectionPlane.get(projectionPlane) : projectionPlane;
this.viewSpecs = specs ?? {};
}
updateViewRect(width, height) {
fitIntoRectangle(new Vector2(width, height), this.viewSpecs, this.#viewRect);
this.#halfHeight = this.#viewRect.height / 2;
this.#pixelRatio.set(width, height).divide(this.#viewRect);
this.#near = this.viewSpecs.near ?? 0.1;
this.#far = this.viewSpecs.far ?? 100000;
this.#distanceToProjectionPlane = this.viewSpecs.distanceToProjectionPlane ?? 300;
this.#aspect = this.#viewRect.width / this.#viewRect.height;
this.#fovy = (2 * Math.atan(this.#halfHeight / this.#distanceToProjectionPlane) * 180) / Math.PI;
}
getViewRect() {
return [this.#viewRect.width, this.#viewRect.height, this.#pixelRatio.x, this.#pixelRatio.y];
}
createCamera() {
const camera = new PerspectiveCamera(this.#fovy, this.#aspect, this.#near, this.#far);
this.projectionPlane.applyRotation(camera);
camera.position.copy(this.projectionPlane.getPointByDistance(this.#distanceToProjectionPlane));
camera.updateProjectionMatrix();
return camera;
}
updateCamera(camera) {
camera.fov = this.#fovy;
camera.aspect = this.#aspect;
camera.updateProjectionMatrix();
}
getZoom(distanceToProjectionPlane) {
if (distanceToProjectionPlane === 0)
return 1;
const d = this.#distanceToProjectionPlane - distanceToProjectionPlane;
return (Math.tan(((this.#fovy / 2) * Math.PI) / 180) * d) / this.#halfHeight;
}
}
//# sourceMappingURL=ParallaxProjection.js.map