mirror of
https://github.com/MultiMote/niimblue
synced 2026-01-19 19:37:11 +03:00
Refactoring
This commit is contained in:
@@ -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];
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
53
niimblue/src/utils/file_utils.ts
Normal file
53
niimblue/src/utils/file_utils.ts
Normal 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();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user