fixed zoom to fit
This commit is contained in:
parent
103fd7f694
commit
1e3efe5150
@ -86,7 +86,8 @@ export class Pointer {
|
||||
// Monitor wheel events
|
||||
el.addEventListener('wheel', e => {
|
||||
const factor = e.deltaY > 0 ? ZOOM_IN_FACTOR : ZOOM_OUT_FACTOR;
|
||||
this.sim.scheduleZoom({x: e.clientX, y: e.clientY}, factor);
|
||||
const {x, y} = this.sim.screenToSim(e.clientX, e.clientY);
|
||||
this.sim.scheduleZoom({x, y}, factor);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@ -56,12 +56,13 @@ export class Sim {
|
||||
this.nextZoom = {x, y, factor};
|
||||
}
|
||||
|
||||
zoom({x: screenX, y: screenY, factor}) {
|
||||
const {x, y} = this.screenToSim(screenX, screenY);
|
||||
// x, y should be in Sim coordinates
|
||||
zoom({x, y, factor}) {
|
||||
// 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
|
||||
this.display.scalePower += factor;
|
||||
// TODO: Lossy rescaling to expand zoom range
|
||||
if (this.display.scalePower > SCALE_POWER_MAX) this.display.scalePower = SCALE_POWER_MAX;
|
||||
if (this.display.scalePower < SCALE_POWER_MIN) this.display.scalePower = SCALE_POWER_MIN;
|
||||
// compute coordinates of new view frame
|
||||
@ -71,7 +72,7 @@ export class Sim {
|
||||
this.pointer.clearPointerHistory();
|
||||
if (this.pointer.panning) {
|
||||
this.pointer.panning = undefined;
|
||||
// TODO: Maybe rescale velocity
|
||||
// TODO: Maybe show velocity vectors relative to view velocity
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
21
tool/zoom.js
21
tool/zoom.js
@ -24,21 +24,21 @@ export class Zoom extends Tool {
|
||||
zoomIn.innerHTML = '<h2>Zoom<br>In</h2>';
|
||||
zoomAll.innerHTML = '<h2>Zoom to Fit</h2>';
|
||||
|
||||
zoomOut.addEventListener('click', (e) => {
|
||||
zoomOut.addEventListener('click', () => {
|
||||
// Aim at center of view
|
||||
const x = this.sim.display.width * this.sim.display.scale / 2;
|
||||
const y = this.sim.display.height * this.sim.display.scale / 2;
|
||||
this.sim.scheduleZoom({x, y}, ZOOM_OUT_FACTOR);
|
||||
this.sim.scheduleZoom(this.sim.screenToSim(x, y), ZOOM_OUT_FACTOR);
|
||||
});
|
||||
|
||||
zoomIn.addEventListener('click', (e) => {
|
||||
zoomIn.addEventListener('click', () => {
|
||||
// Aim at center of view
|
||||
const x = this.sim.display.width * this.sim.display.scale / 2;
|
||||
const y = this.sim.display.height * this.sim.display.scale / 2;
|
||||
this.sim.scheduleZoom({x, y}, ZOOM_IN_FACTOR);
|
||||
this.sim.scheduleZoom(this.sim.screenToSim(x, y), ZOOM_IN_FACTOR);
|
||||
});
|
||||
|
||||
zoomAll.addEventListener('click', (e) => {
|
||||
zoomAll.addEventListener('click', () => {
|
||||
// Determine bounding box
|
||||
const box = this.sim.objects.boundingBox;
|
||||
const x = (box.start.x + box.end.x) / 2;
|
||||
@ -47,13 +47,10 @@ export class Zoom extends Tool {
|
||||
const widthRatio = Math.abs(box.start.x - box.end.x) / this.sim.display.width;
|
||||
const heightRatio = Math.abs(box.start.y - box.end.y) / this.sim.display.height;
|
||||
const biggerRatio = Math.max(widthRatio, heightRatio);
|
||||
if (biggerRatio <= 1) {
|
||||
const base2Ratio = Math.log(1/biggerRatio) / Math.log(2);
|
||||
this.sim.scheduleZoom({x, y}, Math.floor(base2Ratio));
|
||||
} else {
|
||||
const base2Ratio = Math.log(1/biggerRatio) / Math.log(2);
|
||||
this.sim.scheduleZoom({x, y}, Math.ceil(base2Ratio));
|
||||
}
|
||||
const base2factor = Math.log(1/biggerRatio) / Math.log(2);
|
||||
const factor = Math.floor(base2factor) - 1;
|
||||
console.log({biggerRatio, base2factor, factor});
|
||||
this.sim.scheduleZoom({x, y}, factor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user