61 lines
1.6 KiB
JavaScript
61 lines
1.6 KiB
JavaScript
import {
|
|
EVENT_ZOOM,
|
|
SCALE_POWER_MAX,
|
|
SCALE_POWER_MIN,
|
|
} from './config.js';
|
|
|
|
export class Zoom {
|
|
sim = undefined;
|
|
nextZoom = undefined;
|
|
|
|
constructor(sim) {
|
|
this.sim = sim;
|
|
}
|
|
|
|
// velocity should be in Sim coordinate scale
|
|
scheduleZoom({x, y}, factor, velocity) {
|
|
this.nextZoom = {x, y, factor, velocity};
|
|
}
|
|
|
|
frame() {
|
|
if (this.nextZoom) {
|
|
this.zoom(this.nextZoom);
|
|
this.nextZoom = undefined;
|
|
}
|
|
}
|
|
|
|
// x, y should be in Sim coordinates
|
|
// velocity should be in Sim coordinate scale
|
|
zoom({x, y, factor, velocity}) {
|
|
const { display } = this.sim;
|
|
// x, y are the mouse coordinates, which should be the center of the new view frame
|
|
// the new view origin should be x, y minus half the new view width and height
|
|
// compute new scale
|
|
// TODO: Lossy rescaling to expand zoom range
|
|
let scalePower = display.scalePower + factor;
|
|
scalePower = Math.max(scalePower, SCALE_POWER_MIN);
|
|
scalePower = Math.min(scalePower, SCALE_POWER_MAX);
|
|
this.sim.display.scalePower = scalePower;
|
|
|
|
// compute coordinates of new view frame
|
|
display.viewOrigin.x = x - display.width / 2;
|
|
display.viewOrigin.y = y - display.height / 2;
|
|
|
|
// Pointer history is stored in client coordinates, so we shouldn't need to clear it?
|
|
// this.pointer.clearPointerHistory();
|
|
|
|
// TODO: If paused, set panning velocity on resume
|
|
// if (this.sim.playing && velocity) {
|
|
if (velocity) {
|
|
this.sim.panning = {
|
|
velocity: { ...velocity },
|
|
paused: !this.sim.playing,
|
|
};
|
|
}
|
|
|
|
const e = new CustomEvent(EVENT_ZOOM);
|
|
this.sim.div.dispatchEvent(e);
|
|
}
|
|
|
|
}
|