From 359b8f648ef153b9f77e1468253bbafe3b3d4ef7 Mon Sep 17 00:00:00 2001 From: Xiang Date: Fri, 29 Nov 2024 18:30:55 +0800 Subject: [PATCH] Zoom using the mouse wheel (#59) --- src/fabric-object/custom_canvas.ts | 54 ++++++++++++++++++++++++++++++ src/lib/ImageEditor.svelte | 1 + src/utils/file_utils.ts | 4 +++ 3 files changed, 59 insertions(+) diff --git a/src/fabric-object/custom_canvas.ts b/src/fabric-object/custom_canvas.ts index 21ddaf4..642a1c2 100644 --- a/src/fabric-object/custom_canvas.ts +++ b/src/fabric-object/custom_canvas.ts @@ -11,6 +11,60 @@ export class CustomCanvas extends fabric.Canvas { private readonly MIRROR_GHOST_COLOR = "rgba(0, 0, 0, 0.3)"; private customBackground: boolean = true; private highlightMirror: boolean = true; + private virtualZoomRatio: number = 1; + + constructor(el?: string | HTMLCanvasElement, options?: fabric.TOptions) { + super(el, options); + this.setupZoom(); + } + + private setupZoom() { + this.on("mouse:wheel", (opt) => { + const event = opt.e as WheelEvent; + event.preventDefault(); + + const delta = event.deltaY; + if (delta > 0) { + this.virtualZoomOut(); + } else { + this.virtualZoomIn(); + } + }); + this.on("mouse:down:before", (opt) => { + const event = opt.e as MouseEvent; + if (event.button == 1) { + event.preventDefault(); + this.resetVirtualZoom(); + } + }); + } + + public virtualZoom(newZoom: number) { + this.virtualZoomRatio = Math.min(Math.max(0.25, newZoom), 4); + this.setDimensions( + { + width: this.virtualZoomRatio * this.getWidth() + "px", + height: this.virtualZoomRatio * this.getHeight() + "px", + }, + { cssOnly: true } + ); + } + + public virtualZoomIn() { + this.virtualZoom(this.virtualZoomRatio * 1.05); + } + + public virtualZoomOut() { + this.virtualZoom(this.virtualZoomRatio * 0.95); + } + + public getVirtualZoom(): number { + return this.virtualZoomRatio; + } + + public resetVirtualZoom() { + this.virtualZoom(1); + } setLabelProps(value: LabelProps) { this.labelProps = value; diff --git a/src/lib/ImageEditor.svelte b/src/lib/ImageEditor.svelte index 3a73611..dcefe7a 100644 --- a/src/lib/ImageEditor.svelte +++ b/src/lib/ImageEditor.svelte @@ -141,6 +141,7 @@ const onUpdateLabelProps = (newProps: LabelProps) => { labelProps = newProps; fabricCanvas.setDimensions(labelProps.size); + fabricCanvas.virtualZoom(fabricCanvas.getVirtualZoom()); try { LocalStoragePersistence.saveLastLabelProps(labelProps); undo.push(fabricCanvas, labelProps); diff --git a/src/utils/file_utils.ts b/src/utils/file_utils.ts index 0a7c10c..773ce47 100644 --- a/src/utils/file_utils.ts +++ b/src/utils/file_utils.ts @@ -11,6 +11,7 @@ import { OBJECT_DEFAULTS, THUMBNAIL_HEIGHT, THUMBNAIL_QUALITY } from "../default import { z } from "zod"; import { FileSharer } from "@byteowls/capacitor-filesharer"; import { Toasts } from "./toasts"; +import { CustomCanvas } from "../fabric-object/custom_canvas"; export class FileUtils { static timestamp(): number { @@ -140,6 +141,9 @@ export class FileUtils { await canvas.loadFromJSON(state, (_, obj) => { if ("set" in obj) obj.set({ snapAngle: OBJECT_DEFAULTS.snapAngle }); }); + if (canvas instanceof CustomCanvas) { + canvas.virtualZoom(canvas.getVirtualZoom()) + } canvas.requestRenderAll(); } }