File size: 3,078 Bytes
df38526 e1243e2 7ffaa9e e1243e2 df38526 7ffaa9e e1243e2 df38526 7ffaa9e df38526 e1243e2 7ffaa9e e1243e2 7ffaa9e df38526 7ffaa9e e1243e2 7ffaa9e e1243e2 df38526 7ffaa9e e1243e2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
import { Transform } from './transform.js';
import { Matrix } from './matrix.js';
import { lerp } from './math.js';
import { getConfig } from './config.js';
export class Camera {
constructor() {
this.transform = new Transform();
this.scale = 1;
this.targetScale = 1;
this.viewportWidth = 0; // Initialize to 0, will be set by setViewport
this.viewportHeight = 0; // Initialize to 0, will be set by setViewport
this.targetPosition = { x: 0, y: 0, z: 0 };
// Set default values in case config isn't ready
this.moveLerpFactor = 0.1;
this.zoomLerpFactor = 0.1;
// Try to get config
const config = getConfig();
if (config?.camera) {
this.moveLerpFactor = config.camera.moveLerpFactor;
this.zoomLerpFactor = config.camera.zoomLerpFactor;
}
}
setViewport(width, height) {
this.viewportWidth = width;
this.viewportHeight = height;
}
getViewMatrix() {
// First translate to center of viewport
const centerMatrix = Matrix.translation(
this.viewportWidth / 2,
this.viewportHeight / 2,
0
);
// Then apply camera transform
const cameraMatrix = Matrix.multiply(
Matrix.scaling(this.scale, this.scale, 1),
Matrix.translation(
-this.transform.position.x,
-this.transform.position.y,
0
)
);
return Matrix.multiply(cameraMatrix, centerMatrix);
}
update(deltaTime) {
// Store old position to calculate velocity
if (this._oldPos === undefined) {
this._oldPos = { x: this.transform.position.x, y: this.transform.position.y };
}
// Smooth position movement
const pos = this.transform.position;
pos.x = lerp(pos.x, this.targetPosition.x, this.moveLerpFactor);
pos.y = lerp(pos.y, this.targetPosition.y, this.moveLerpFactor);
// Calculate velocity in units/s
const dx = pos.x - this._oldPos.x;
const dy = pos.y - this._oldPos.y;
this.currentVelocity = {
x: dx / deltaTime,
y: dy / deltaTime
};
this._oldPos.x = pos.x;
this._oldPos.y = pos.y;
// Smooth scale/zoom
this.scale = lerp(this.scale, this.targetScale, this.zoomLerpFactor);
}
moveBy(dx, dy, dz = 0) {
// Invert dy for natural camera movement (up is negative, down is positive)
this.targetPosition.x += dx;
this.targetPosition.y -= dy; // Invert dy here
this.targetPosition.z += dz;
}
moveTo(x, y, z = 0) {
this.targetPosition.x = x;
this.targetPosition.y = y;
this.targetPosition.z = z;
this.transform.setPosition(x, y, z); // Immediate for reset
}
setZoom(scale) {
this.targetScale = scale;
this.scale = scale; // Immediate for reset
}
zoomBy(factor) {
this.targetScale *= factor;
}
}
|