From a7553457adc6fcd0727284f1e9530fe85b4eae6e Mon Sep 17 00:00:00 2001 From: "Eevee (Evelyn Woods)" Date: Fri, 23 Apr 2021 13:28:20 -0600 Subject: [PATCH] Add mousewheel zooming to the editor --- index.html | 1 + js/main-editor.js | 53 +++++++++++++++++++++++++++++++++++++++++++++++ style.css | 10 +++++++++ 3 files changed, 64 insertions(+) diff --git a/index.html b/index.html index ccd5532..ea75d32 100644 --- a/index.html +++ b/index.html @@ -420,6 +420,7 @@
+
diff --git a/js/main-editor.js b/js/main-editor.js index 574e42c..3e88e7e 100644 --- a/js/main-editor.js +++ b/js/main-editor.js @@ -3201,6 +3201,7 @@ class Selection { // - key // title // 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 { constructor(conductor) { 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_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 window.addEventListener('keydown', ev => { if (! this.active) @@ -3423,6 +3429,46 @@ export class Editor extends PrimaryView { window.addEventListener('mouseleave', ev => { 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 // 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() { if (! this._level_browser) { this._level_browser = new EditorLevelBrowserOverlay(this.conductor); diff --git a/style.css b/style.css index b996152..e9a9d40 100644 --- a/style.css +++ b/style.css @@ -1759,6 +1759,7 @@ body.--debug #player-debug { grid: "controls controls" min-content "palette level" 1fr + "palette status" min-content / min-content 1fr ; gap: 0.5em; @@ -1799,6 +1800,10 @@ body.--debug #player-debug { --viewport-height: 9; --scale: 1; } +#editor .editor-canvas canvas.--crispy { + image-rendering: crisp-edges; + image-rendering: pixelated; +} /* SVG overlays */ #editor svg.level-editor-overlay { position: absolute; @@ -2003,6 +2008,11 @@ body.--debug #player-debug { transition-delay: 0.5s; transition-timing-function: ease-in; } +#editor #editor-statusbar { + grid-area: status; + display: flex; + height: 1em; +} .editor-level-browser { display: grid;