21 خطوط
1.1 KiB
JavaScript
21 خطوط
1.1 KiB
JavaScript
/** SVG viewBox camera. All pointer math is in viewport pixels / document units. */
|
|
export class Camera {
|
|
constructor(bounds, width, height) { this.bounds = bounds; this.resize(width, height); this.fit(); }
|
|
resize(width, height) { this.width = Math.max(1, width); this.height = Math.max(1, height); }
|
|
fit() {
|
|
const b = this.bounds;
|
|
this.scale = Math.min(this.width / b.width, this.height / b.height);
|
|
this.fitScale = this.scale;
|
|
this.x = (this.width - b.width * this.scale) / 2 - b.x * this.scale;
|
|
this.y = (this.height - b.height * this.scale) / 2 - b.y * this.scale;
|
|
}
|
|
world(x, y) { return { x: (x - this.x) / this.scale, y: (y - this.y) / this.scale }; }
|
|
zoom(factor, x, y) {
|
|
const p = this.world(x, y);
|
|
this.scale = Math.min(this.fitScale * 200, Math.max(this.fitScale * .05, this.scale * factor));
|
|
this.x = x - p.x * this.scale; this.y = y - p.y * this.scale;
|
|
}
|
|
pan(x, y) { this.x += x; this.y += y; }
|
|
get viewBox() { return `${-this.x / this.scale} ${-this.y / this.scale} ${this.width / this.scale} ${this.height / this.scale}`; }
|
|
}
|