Add mousewheel zooming to the editor
This commit is contained in:
parent
9e090f967d
commit
a7553457ad
@ -420,6 +420,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<nav class="controls"></nav>
|
<nav class="controls"></nav>
|
||||||
<div class="palette"></div>
|
<div class="palette"></div>
|
||||||
|
<div id="editor-statusbar"></div>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -3201,6 +3201,7 @@ class Selection {
|
|||||||
// - key
|
// - key
|
||||||
// title
|
// title
|
||||||
// last_modified
|
// last_modified
|
||||||
|
const EDITOR_ZOOM_LEVELS = [0.0625, 0.125, 0.25, 0.5, 1, 2, 3, 4, 6, 8, 10, 12, 16];
|
||||||
export class Editor extends PrimaryView {
|
export class Editor extends PrimaryView {
|
||||||
constructor(conductor) {
|
constructor(conductor) {
|
||||||
super(conductor, document.body.querySelector('main#editor'));
|
super(conductor, document.body.querySelector('main#editor'));
|
||||||
@ -3247,6 +3248,11 @@ export class Editor extends PrimaryView {
|
|||||||
this.svg_cursor = mk_svg('rect.overlay-transient.overlay-cursor', {x: 0, y: 0, width: 1, height: 1});
|
this.svg_cursor = mk_svg('rect.overlay-transient.overlay-cursor', {x: 0, y: 0, width: 1, height: 1});
|
||||||
this.svg_overlay.append(this.preview_g, this.svg_cursor);
|
this.svg_overlay.append(this.preview_g, this.svg_cursor);
|
||||||
|
|
||||||
|
// Populate status bar (needs doing before the mouse stuff, which tries to update it)
|
||||||
|
let statusbar = this.root.querySelector('#editor-statusbar');
|
||||||
|
this.statusbar_zoom = mk('div.-zoom');
|
||||||
|
statusbar.append(this.statusbar_zoom);
|
||||||
|
|
||||||
// Keyboard shortcuts
|
// Keyboard shortcuts
|
||||||
window.addEventListener('keydown', ev => {
|
window.addEventListener('keydown', ev => {
|
||||||
if (! this.active)
|
if (! this.active)
|
||||||
@ -3423,6 +3429,46 @@ export class Editor extends PrimaryView {
|
|||||||
window.addEventListener('mouseleave', ev => {
|
window.addEventListener('mouseleave', ev => {
|
||||||
this.mouse_coords = null;
|
this.mouse_coords = null;
|
||||||
});
|
});
|
||||||
|
// Mouse wheel to zoom
|
||||||
|
this.set_canvas_zoom(1);
|
||||||
|
this.viewport_el.addEventListener('wheel', ev => {
|
||||||
|
// The delta is platform and hardware dependent and ultimately kind of useless, so just
|
||||||
|
// treat each event as a click and hope for the best
|
||||||
|
if (ev.deltaY === 0)
|
||||||
|
return;
|
||||||
|
ev.stopPropagation();
|
||||||
|
ev.preventDefault();
|
||||||
|
|
||||||
|
let index = EDITOR_ZOOM_LEVELS.findIndex(el => el >= this.zoom);
|
||||||
|
if (index < 0) {
|
||||||
|
index = EDITOR_ZOOM_LEVELS.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_zoom;
|
||||||
|
if (ev.deltaY > 0) {
|
||||||
|
// Zoom out
|
||||||
|
if (EDITOR_ZOOM_LEVELS[index] !== this.zoom) {
|
||||||
|
// If we're between levels, pretend we're one level in
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
if (index <= 0)
|
||||||
|
return;
|
||||||
|
new_zoom = EDITOR_ZOOM_LEVELS[index - 1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Zoom in
|
||||||
|
if (EDITOR_ZOOM_LEVELS[index] !== this.zoom) {
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
if (index >= EDITOR_ZOOM_LEVELS.length - 1)
|
||||||
|
return;
|
||||||
|
new_zoom = EDITOR_ZOOM_LEVELS[index + 1];
|
||||||
|
}
|
||||||
|
// FIXME preserve the panning such that the point under the cursor doesn't move
|
||||||
|
// (possibly difficult given that i can't pan at all if there are no scrollbars??)
|
||||||
|
// FIXME add a widget to status bar
|
||||||
|
this.set_canvas_zoom(new_zoom, ev.clientX, ev.clientY);
|
||||||
|
});
|
||||||
|
|
||||||
// Toolbox
|
// Toolbox
|
||||||
// Selected tile and rotation buttons
|
// Selected tile and rotation buttons
|
||||||
@ -4113,6 +4159,13 @@ export class Editor extends PrimaryView {
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
set_canvas_zoom(zoom, origin_x = null, origin_y = null) {
|
||||||
|
this.zoom = zoom;
|
||||||
|
this.renderer.canvas.style.setProperty('--scale', this.zoom);
|
||||||
|
this.renderer.canvas.classList.toggle('--crispy', this.zoom >= 1);
|
||||||
|
this.statusbar_zoom.textContent = `${this.zoom * 100}%`;
|
||||||
|
}
|
||||||
|
|
||||||
open_level_browser() {
|
open_level_browser() {
|
||||||
if (! this._level_browser) {
|
if (! this._level_browser) {
|
||||||
this._level_browser = new EditorLevelBrowserOverlay(this.conductor);
|
this._level_browser = new EditorLevelBrowserOverlay(this.conductor);
|
||||||
|
|||||||
10
style.css
10
style.css
@ -1759,6 +1759,7 @@ body.--debug #player-debug {
|
|||||||
grid:
|
grid:
|
||||||
"controls controls" min-content
|
"controls controls" min-content
|
||||||
"palette level" 1fr
|
"palette level" 1fr
|
||||||
|
"palette status" min-content
|
||||||
/ min-content 1fr
|
/ min-content 1fr
|
||||||
;
|
;
|
||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
@ -1799,6 +1800,10 @@ body.--debug #player-debug {
|
|||||||
--viewport-height: 9;
|
--viewport-height: 9;
|
||||||
--scale: 1;
|
--scale: 1;
|
||||||
}
|
}
|
||||||
|
#editor .editor-canvas canvas.--crispy {
|
||||||
|
image-rendering: crisp-edges;
|
||||||
|
image-rendering: pixelated;
|
||||||
|
}
|
||||||
/* SVG overlays */
|
/* SVG overlays */
|
||||||
#editor svg.level-editor-overlay {
|
#editor svg.level-editor-overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -2003,6 +2008,11 @@ body.--debug #player-debug {
|
|||||||
transition-delay: 0.5s;
|
transition-delay: 0.5s;
|
||||||
transition-timing-function: ease-in;
|
transition-timing-function: ease-in;
|
||||||
}
|
}
|
||||||
|
#editor #editor-statusbar {
|
||||||
|
grid-area: status;
|
||||||
|
display: flex;
|
||||||
|
height: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
.editor-level-browser {
|
.editor-level-browser {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user