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; } }