1
0
mirror of https://github.com/MultiMote/niimblue synced 2026-01-19 19:37:11 +03:00

Refactoring

This commit is contained in:
MultiMote
2024-09-03 14:05:40 +03:00
parent 0399d9f185
commit fd4e525f4e
8 changed files with 102 additions and 72 deletions

View File

@@ -1,6 +1,6 @@
import { fabric } from "fabric";
import { code128b, ean13 } from "../utils/barcode";
import { equalSpacingFillText } from "../utils/canvas";
import { equalSpacingFillText } from "../utils/canvas_utils";
const PRESERVE_PROPERTIES = ["text", "encoding", "printText"];
const EAN13_LONG_IDX: number[] = [0, 1, 2, 45, 46, 47, 48, 49, 92, 93, 94];

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import { onDestroy, onMount } from "svelte";
import { fabric } from "fabric";
import { type LabelProps, type OjectType } from "../types";
import { type LabelProps, type OjectType, type ExportedLabelTemplate } from "../types";
import LabelPropsEditor from "./LabelPropsEditor.svelte";
import IconPicker from "./IconPicker.svelte";
import { type IconName, icon as faIcon, parse as faParse } from "@fortawesome/fontawesome-svg-core";
@@ -10,12 +10,13 @@
import PrintPreview from "./PrintPreview.svelte";
import TextParamsPanel from "./TextParamsControls.svelte";
import GenericObjectParamsControls from "./GenericObjectParamsControls.svelte";
import { ImageEditorUtils } from "../image_editor_utils";
import { ImageEditorUtils } from "../utils/image_editor_utils";
import { QRCode } from "../fabric-object/qrcode.class";
import QrCodeParamsPanel from "./QRCodeParamsControls.svelte";
import { Barcode } from "../fabric-object/barcode.class";
import BarcodeParamsPanel from "./BarcodeParamsControls.svelte";
import Dropdown from "bootstrap/js/dist/dropdown";
import { FileUtils } from "../utils/file_utils";
let htmlCanvas: HTMLCanvasElement;
let fabricCanvas: fabric.Canvas;
@@ -66,60 +67,26 @@
};
const onExportClicked = () => {
const json: string = JSON.stringify({
canvas: fabricCanvas.toJSON(),
label: labelProps,
});
const link = document.createElement("a");
const file: Blob = new Blob([json], { type: "text/json" });
link.href = URL.createObjectURL(file);
link.download = "canvas.json";
link.click();
URL.revokeObjectURL(link.href);
FileUtils.saveLabelAsJson(fabricCanvas, labelProps);
};
const onImportClicked = () => {
const input: HTMLInputElement = document.createElement("input");
const reader = new FileReader();
const onImportClicked = async () => {
const contents = await FileUtils.pickAndReadTextFile("json");
const data = JSON.parse(contents);
input.type = "file";
// todo: validation and merge with onLoadClicked
labelProps = data.label;
onUpdateLabelProps();
input.onchange = (e: Event) => {
let target = e.target as HTMLInputElement;
if (target.files !== null) {
let file: File = target.files[0];
if (file.type === "application/json") {
reader.readAsText(file, "UTF-8");
reader.onload = (readerEvt: ProgressEvent<FileReader>) => {
if (readerEvt?.target?.result) {
const json = readerEvt.target.result as string;
const data = JSON.parse(json);
// todo: validation and merge with onLoadClicked
labelProps = data.label;
onUpdateLabelProps();
fabricCanvas.loadFromJSON(
data.canvas,
() => {
fabricCanvas.requestRenderAll();
},
(src: object, obj: fabric.Object, error: any) => {
obj.set({ snapAngle: 10 });
// console.log(error);
}
);
}
};
reader.onerror = (readerEvt: ProgressEvent<FileReader>) => {
console.error(readerEvt);
};
}
fabricCanvas.loadFromJSON(
data.canvas,
() => {
fabricCanvas.requestRenderAll();
},
(src: object, obj: fabric.Object, error: any) => {
obj.set({ snapAngle: 10 });
}
};
input.click();
);
};
const onLoadClicked = () => {
@@ -143,22 +110,8 @@
);
};
const onObjectPicked = (name: OjectType) => {
if (name === "text") {
ImageEditorUtils.addText(fabricCanvas);
} else if (name === "line") {
ImageEditorUtils.addHLine(fabricCanvas);
} else if (name === "circle") {
ImageEditorUtils.addCircle(fabricCanvas);
} else if (name === "rectangle") {
ImageEditorUtils.addRect(fabricCanvas);
} else if (name === "image") {
ImageEditorUtils.addImageWithFilePicker(fabricCanvas);
} else if (name === "qrcode") {
ImageEditorUtils.addQrCode(fabricCanvas);
} else if (name === "barcode") {
ImageEditorUtils.addBarcode(fabricCanvas);
}
const onObjectPicked = (objectType: OjectType) => {
ImageEditorUtils.addObject(fabricCanvas, objectType);
};
const onIconPicked = (i: IconName) => {

View File

@@ -3,7 +3,7 @@
import { derived } from "svelte/store";
import Modal from "bootstrap/js/dist/modal";
import { connectionState, printerClient, printerMeta } from "../stores";
import { copyImageData, threshold, atkinson } from "../post_process";
import { copyImageData, threshold, atkinson } from "../utils/post_process";
import { type EncodedImage, ImageEncoder, LabelType, PacketGenerator, ProtocolVersion } from "@mmote/niimbluelib";
import type { LabelProps } from "../types";
import FaIcon from "./FaIcon.svelte";

View File

@@ -16,3 +16,8 @@ export type LabelPreset = {
};
export type OjectType = "text" | "rectangle" | "line" | "circle" | "image" | "qrcode" | "barcode";
export interface ExportedLabelTemplate {
canvas: { version: string; objects: Object[] };
label: LabelProps;
};

View File

@@ -0,0 +1,53 @@
import type { fabric } from "fabric";
import type { ExportedLabelTemplate, LabelProps } from "../types";
export class FileUtils {
/** Convert label template to JSON and download it */
public static saveLabelAsJson(canvas: fabric.Canvas, labelProps: LabelProps) {
const timestamp = Math.floor(Date.now() / 1000);
const label: ExportedLabelTemplate = {
canvas: canvas.toJSON(),
label: labelProps,
};
const json: string = JSON.stringify(label);
const link = document.createElement("a");
const file: Blob = new Blob([json], { type: "text/json" });
link.href = URL.createObjectURL(file);
link.download = `label_${timestamp}.json`;
link.click();
URL.revokeObjectURL(link.href);
}
/** Open file picker and return file contents */
public static async pickAndReadTextFile(acceptExtension: string): Promise<string> {
return new Promise((resolve, reject) => {
const input: HTMLInputElement = document.createElement("input");
const reader = new FileReader();
input.type = "file";
input.accept = `.${acceptExtension}`;
input.onchange = (e: Event) => {
const target = e.target as HTMLInputElement;
if (target.files !== null) {
const file: File = target.files[0];
const ext = file.name.split(".").pop();
if (ext === acceptExtension) {
reader.readAsText(file, "UTF-8");
reader.onload = (readerEvt: ProgressEvent<FileReader>) => {
if (readerEvt?.target?.result) {
resolve(readerEvt.target.result as string);
}
};
reader.onerror = (readerEvt: ProgressEvent<FileReader>) => {
console.error(readerEvt);
reject(new Error("Unable to load file"));
};
}
}
};
input.click();
});
}
}

View File

@@ -1,6 +1,7 @@
import { fabric } from "fabric";
import { QRCode } from "./fabric-object/qrcode.class";
import Barcode from "./fabric-object/barcode.class";
import { QRCode } from "../fabric-object/qrcode.class";
import Barcode from "../fabric-object/barcode.class";
import type { OjectType } from "../types";
export class ImageEditorUtils {
static readonly SIZE_DEFAULT: number = 64;
@@ -142,7 +143,25 @@ export class ImageEditorUtils {
width: ImageEditorUtils.SIZE_DEFAULT * 2,
height: ImageEditorUtils.SIZE_DEFAULT,
encoding: "EAN13",
})
});
canvas.add(barcode);
}
public static addObject(canvas: fabric.Canvas, objType: OjectType): void {
if (objType === "text") {
this.addText(canvas);
} else if (objType === "line") {
this.addHLine(canvas);
} else if (objType === "circle") {
this.addCircle(canvas);
} else if (objType === "rectangle") {
this.addRect(canvas);
} else if (objType === "image") {
this.addImageWithFilePicker(canvas);
} else if (objType === "qrcode") {
this.addQrCode(canvas);
} else if (objType === "barcode") {
this.addBarcode(canvas);
}
}
}