kopia lustrzana https://github.com/zhengkyl/qrframe
editable x y scaling
rodzic
c9370d62a6
commit
da31679869
|
@ -39,14 +39,6 @@ export enum Toggle {
|
|||
}
|
||||
/**
|
||||
*/
|
||||
export enum ECL {
|
||||
Low = 0,
|
||||
Medium = 1,
|
||||
Quartile = 2,
|
||||
High = 3,
|
||||
}
|
||||
/**
|
||||
*/
|
||||
export enum Mask {
|
||||
M0 = 0,
|
||||
M1 = 1,
|
||||
|
@ -59,9 +51,11 @@ export enum Mask {
|
|||
}
|
||||
/**
|
||||
*/
|
||||
export enum SvgError {
|
||||
InvalidEncoding = 0,
|
||||
ExceedsMaxCapacity = 1,
|
||||
export enum ECL {
|
||||
Low = 0,
|
||||
Medium = 1,
|
||||
Quartile = 2,
|
||||
High = 3,
|
||||
}
|
||||
/**
|
||||
*/
|
||||
|
@ -72,23 +66,91 @@ export enum Mode {
|
|||
}
|
||||
/**
|
||||
*/
|
||||
export enum QrError {
|
||||
InvalidEncoding = 0,
|
||||
ExceedsMaxCapacity = 1,
|
||||
}
|
||||
/**
|
||||
*/
|
||||
export class Margin {
|
||||
free(): void;
|
||||
/**
|
||||
* @param {number} margin
|
||||
*/
|
||||
constructor(margin: number);
|
||||
/**
|
||||
* @param {number} top
|
||||
* @returns {Margin}
|
||||
*/
|
||||
setTop(top: number): Margin;
|
||||
/**
|
||||
* @param {number} right
|
||||
* @returns {Margin}
|
||||
*/
|
||||
setRight(right: number): Margin;
|
||||
/**
|
||||
* @param {number} bottom
|
||||
* @returns {Margin}
|
||||
*/
|
||||
setBottom(bottom: number): Margin;
|
||||
/**
|
||||
* @param {number} left
|
||||
* @returns {Margin}
|
||||
*/
|
||||
setLeft(left: number): Margin;
|
||||
/**
|
||||
* @param {number} y
|
||||
* @returns {Margin}
|
||||
*/
|
||||
y(y: number): Margin;
|
||||
/**
|
||||
* @param {number} x
|
||||
* @returns {Margin}
|
||||
*/
|
||||
x(x: number): Margin;
|
||||
/**
|
||||
*/
|
||||
bottom: number;
|
||||
/**
|
||||
*/
|
||||
left: number;
|
||||
/**
|
||||
*/
|
||||
right: number;
|
||||
/**
|
||||
*/
|
||||
top: number;
|
||||
}
|
||||
/**
|
||||
*/
|
||||
export class Matrix {
|
||||
free(): void;
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
width(): number;
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
height(): number;
|
||||
/**
|
||||
*/
|
||||
ecl: ECL;
|
||||
/**
|
||||
*/
|
||||
margin: Margin;
|
||||
/**
|
||||
*/
|
||||
mask: Mask;
|
||||
/**
|
||||
*/
|
||||
mode: Mode;
|
||||
/**
|
||||
*/
|
||||
value: any[];
|
||||
/**
|
||||
*/
|
||||
version: Version;
|
||||
/**
|
||||
*/
|
||||
width: number;
|
||||
}
|
||||
/**
|
||||
*/
|
||||
|
@ -117,6 +179,11 @@ export class QrOptions {
|
|||
* @returns {QrOptions}
|
||||
*/
|
||||
mask(mask?: Mask): QrOptions;
|
||||
/**
|
||||
* @param {Margin} margin
|
||||
* @returns {QrOptions}
|
||||
*/
|
||||
margin(margin: Margin): QrOptions;
|
||||
}
|
||||
/**
|
||||
*/
|
||||
|
@ -146,20 +213,20 @@ export class SvgOptions {
|
|||
*/
|
||||
background(background: string): SvgOptions;
|
||||
/**
|
||||
* @param {Float64Array} scale_matrix
|
||||
* @param {Uint8Array} scale_matrix
|
||||
* @returns {SvgOptions}
|
||||
*/
|
||||
scale_x_matrix(scale_matrix: Float64Array): SvgOptions;
|
||||
scale_x_matrix(scale_matrix: Uint8Array): SvgOptions;
|
||||
/**
|
||||
* @param {Float64Array} scale_matrix
|
||||
* @param {Uint8Array} scale_matrix
|
||||
* @returns {SvgOptions}
|
||||
*/
|
||||
scale_y_matrix(scale_matrix: Float64Array): SvgOptions;
|
||||
scale_y_matrix(scale_matrix: Uint8Array): SvgOptions;
|
||||
/**
|
||||
* @param {Float64Array} scale_matrix
|
||||
* @param {Uint8Array} scale_matrix
|
||||
* @returns {SvgOptions}
|
||||
*/
|
||||
scale_matrix(scale_matrix: Float64Array): SvgOptions;
|
||||
scale_matrix(scale_matrix: Uint8Array): SvgOptions;
|
||||
/**
|
||||
* @param {Toggle} toggle
|
||||
* @returns {SvgOptions}
|
||||
|
@ -203,23 +270,44 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
|
|||
|
||||
export interface InitOutput {
|
||||
readonly memory: WebAssembly.Memory;
|
||||
readonly __wbg_margin_free: (a: number) => void;
|
||||
readonly __wbg_get_margin_top: (a: number) => number;
|
||||
readonly __wbg_set_margin_top: (a: number, b: number) => void;
|
||||
readonly __wbg_get_margin_right: (a: number) => number;
|
||||
readonly __wbg_set_margin_right: (a: number, b: number) => void;
|
||||
readonly __wbg_get_margin_bottom: (a: number) => number;
|
||||
readonly __wbg_set_margin_bottom: (a: number, b: number) => void;
|
||||
readonly __wbg_get_margin_left: (a: number) => number;
|
||||
readonly __wbg_set_margin_left: (a: number, b: number) => void;
|
||||
readonly margin_new: (a: number) => number;
|
||||
readonly margin_setTop: (a: number, b: number) => number;
|
||||
readonly margin_setRight: (a: number, b: number) => number;
|
||||
readonly margin_setBottom: (a: number, b: number) => number;
|
||||
readonly margin_setLeft: (a: number, b: number) => number;
|
||||
readonly margin_y: (a: number, b: number) => number;
|
||||
readonly margin_x: (a: number, b: number) => number;
|
||||
readonly __wbg_matrix_free: (a: number) => void;
|
||||
readonly __wbg_get_matrix_value: (a: number, b: number) => void;
|
||||
readonly __wbg_set_matrix_value: (a: number, b: number, c: number) => void;
|
||||
readonly __wbg_get_matrix_width: (a: number) => number;
|
||||
readonly __wbg_set_matrix_width: (a: number, b: number) => void;
|
||||
readonly __wbg_get_matrix_margin: (a: number) => number;
|
||||
readonly __wbg_set_matrix_margin: (a: number, b: number) => void;
|
||||
readonly __wbg_get_matrix_mode: (a: number) => number;
|
||||
readonly __wbg_set_matrix_mode: (a: number, b: number) => void;
|
||||
readonly __wbg_get_matrix_version: (a: number) => number;
|
||||
readonly __wbg_set_matrix_version: (a: number, b: number) => void;
|
||||
readonly __wbg_get_matrix_ecl: (a: number) => number;
|
||||
readonly __wbg_set_matrix_ecl: (a: number, b: number) => void;
|
||||
readonly __wbg_get_matrix_mask: (a: number) => number;
|
||||
readonly __wbg_set_matrix_mask: (a: number, b: number) => void;
|
||||
readonly matrix_width: (a: number) => number;
|
||||
readonly matrix_height: (a: number) => number;
|
||||
readonly __wbg_qroptions_free: (a: number) => void;
|
||||
readonly qroptions_new: () => number;
|
||||
readonly qroptions_min_version: (a: number, b: number) => number;
|
||||
readonly qroptions_min_ecl: (a: number, b: number) => number;
|
||||
readonly qroptions_mode: (a: number, b: number) => number;
|
||||
readonly qroptions_mask: (a: number, b: number) => number;
|
||||
readonly qroptions_margin: (a: number, b: number) => number;
|
||||
readonly __wbg_svgoptions_free: (a: number) => void;
|
||||
readonly svgoptions_new: () => number;
|
||||
readonly svgoptions_margin: (a: number, b: number) => number;
|
||||
|
|
252
fuqr/pkg/fuqr.js
252
fuqr/pkg/fuqr.js
|
@ -17,18 +17,6 @@ function addHeapObject(obj) {
|
|||
|
||||
function getObject(idx) { return heap[idx]; }
|
||||
|
||||
function dropObject(idx) {
|
||||
if (idx < 132) return;
|
||||
heap[idx] = heap_next;
|
||||
heap_next = idx;
|
||||
}
|
||||
|
||||
function takeObject(idx) {
|
||||
const ret = getObject(idx);
|
||||
dropObject(idx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
function isLikeNone(x) {
|
||||
return x === undefined || x === null;
|
||||
}
|
||||
|
@ -51,6 +39,18 @@ function getInt32Memory0() {
|
|||
return cachedInt32Memory0;
|
||||
}
|
||||
|
||||
function dropObject(idx) {
|
||||
if (idx < 132) return;
|
||||
heap[idx] = heap_next;
|
||||
heap_next = idx;
|
||||
}
|
||||
|
||||
function takeObject(idx) {
|
||||
const ret = getObject(idx);
|
||||
dropObject(idx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
|
||||
|
||||
if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };
|
||||
|
@ -162,9 +162,9 @@ function passStringToWasm0(arg, malloc, realloc) {
|
|||
return ptr;
|
||||
}
|
||||
|
||||
function passArrayF64ToWasm0(arg, malloc) {
|
||||
const ptr = malloc(arg.length * 8, 8) >>> 0;
|
||||
getFloat64Memory0().set(arg, ptr / 8);
|
||||
function passArray8ToWasm0(arg, malloc) {
|
||||
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
||||
getUint8Memory0().set(arg, ptr / 1);
|
||||
WASM_VECTOR_LEN = arg.length;
|
||||
return ptr;
|
||||
}
|
||||
|
@ -229,16 +229,158 @@ export const Module = Object.freeze({ DataOFF:0,"0":"DataOFF",DataON:1,"1":"Data
|
|||
export const Toggle = Object.freeze({ Background:0,"0":"Background",BackgroundPixels:1,"1":"BackgroundPixels",ForegroundPixels:2,"2":"ForegroundPixels", });
|
||||
/**
|
||||
*/
|
||||
export const ECL = Object.freeze({ Low:0,"0":"Low",Medium:1,"1":"Medium",Quartile:2,"2":"Quartile",High:3,"3":"High", });
|
||||
/**
|
||||
*/
|
||||
export const Mask = Object.freeze({ M0:0,"0":"M0",M1:1,"1":"M1",M2:2,"2":"M2",M3:3,"3":"M3",M4:4,"4":"M4",M5:5,"5":"M5",M6:6,"6":"M6",M7:7,"7":"M7", });
|
||||
/**
|
||||
*/
|
||||
export const SvgError = Object.freeze({ InvalidEncoding:0,"0":"InvalidEncoding",ExceedsMaxCapacity:1,"1":"ExceedsMaxCapacity", });
|
||||
export const ECL = Object.freeze({ Low:0,"0":"Low",Medium:1,"1":"Medium",Quartile:2,"2":"Quartile",High:3,"3":"High", });
|
||||
/**
|
||||
*/
|
||||
export const Mode = Object.freeze({ Numeric:0,"0":"Numeric",Alphanumeric:1,"1":"Alphanumeric",Byte:2,"2":"Byte", });
|
||||
/**
|
||||
*/
|
||||
export const QrError = Object.freeze({ InvalidEncoding:0,"0":"InvalidEncoding",ExceedsMaxCapacity:1,"1":"ExceedsMaxCapacity", });
|
||||
|
||||
const MarginFinalization = (typeof FinalizationRegistry === 'undefined')
|
||||
? { register: () => {}, unregister: () => {} }
|
||||
: new FinalizationRegistry(ptr => wasm.__wbg_margin_free(ptr >>> 0));
|
||||
/**
|
||||
*/
|
||||
export class Margin {
|
||||
|
||||
static __wrap(ptr) {
|
||||
ptr = ptr >>> 0;
|
||||
const obj = Object.create(Margin.prototype);
|
||||
obj.__wbg_ptr = ptr;
|
||||
MarginFinalization.register(obj, obj.__wbg_ptr, obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
__destroy_into_raw() {
|
||||
const ptr = this.__wbg_ptr;
|
||||
this.__wbg_ptr = 0;
|
||||
MarginFinalization.unregister(this);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
free() {
|
||||
const ptr = this.__destroy_into_raw();
|
||||
wasm.__wbg_margin_free(ptr);
|
||||
}
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
get top() {
|
||||
const ret = wasm.__wbg_get_margin_top(this.__wbg_ptr);
|
||||
return ret >>> 0;
|
||||
}
|
||||
/**
|
||||
* @param {number} arg0
|
||||
*/
|
||||
set top(arg0) {
|
||||
wasm.__wbg_set_margin_top(this.__wbg_ptr, arg0);
|
||||
}
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
get right() {
|
||||
const ret = wasm.__wbg_get_margin_right(this.__wbg_ptr);
|
||||
return ret >>> 0;
|
||||
}
|
||||
/**
|
||||
* @param {number} arg0
|
||||
*/
|
||||
set right(arg0) {
|
||||
wasm.__wbg_set_margin_right(this.__wbg_ptr, arg0);
|
||||
}
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
get bottom() {
|
||||
const ret = wasm.__wbg_get_margin_bottom(this.__wbg_ptr);
|
||||
return ret >>> 0;
|
||||
}
|
||||
/**
|
||||
* @param {number} arg0
|
||||
*/
|
||||
set bottom(arg0) {
|
||||
wasm.__wbg_set_margin_bottom(this.__wbg_ptr, arg0);
|
||||
}
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
get left() {
|
||||
const ret = wasm.__wbg_get_margin_left(this.__wbg_ptr);
|
||||
return ret >>> 0;
|
||||
}
|
||||
/**
|
||||
* @param {number} arg0
|
||||
*/
|
||||
set left(arg0) {
|
||||
wasm.__wbg_set_margin_left(this.__wbg_ptr, arg0);
|
||||
}
|
||||
/**
|
||||
* @param {number} margin
|
||||
*/
|
||||
constructor(margin) {
|
||||
const ret = wasm.margin_new(margin);
|
||||
this.__wbg_ptr = ret >>> 0;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* @param {number} top
|
||||
* @returns {Margin}
|
||||
*/
|
||||
setTop(top) {
|
||||
const ptr = this.__destroy_into_raw();
|
||||
const ret = wasm.margin_setTop(ptr, top);
|
||||
return Margin.__wrap(ret);
|
||||
}
|
||||
/**
|
||||
* @param {number} right
|
||||
* @returns {Margin}
|
||||
*/
|
||||
setRight(right) {
|
||||
const ptr = this.__destroy_into_raw();
|
||||
const ret = wasm.margin_setRight(ptr, right);
|
||||
return Margin.__wrap(ret);
|
||||
}
|
||||
/**
|
||||
* @param {number} bottom
|
||||
* @returns {Margin}
|
||||
*/
|
||||
setBottom(bottom) {
|
||||
const ptr = this.__destroy_into_raw();
|
||||
const ret = wasm.margin_setBottom(ptr, bottom);
|
||||
return Margin.__wrap(ret);
|
||||
}
|
||||
/**
|
||||
* @param {number} left
|
||||
* @returns {Margin}
|
||||
*/
|
||||
setLeft(left) {
|
||||
const ptr = this.__destroy_into_raw();
|
||||
const ret = wasm.margin_setLeft(ptr, left);
|
||||
return Margin.__wrap(ret);
|
||||
}
|
||||
/**
|
||||
* @param {number} y
|
||||
* @returns {Margin}
|
||||
*/
|
||||
y(y) {
|
||||
const ptr = this.__destroy_into_raw();
|
||||
const ret = wasm.margin_y(ptr, y);
|
||||
return Margin.__wrap(ret);
|
||||
}
|
||||
/**
|
||||
* @param {number} x
|
||||
* @returns {Margin}
|
||||
*/
|
||||
x(x) {
|
||||
const ptr = this.__destroy_into_raw();
|
||||
const ret = wasm.margin_x(ptr, x);
|
||||
return Margin.__wrap(ret);
|
||||
}
|
||||
}
|
||||
|
||||
const MatrixFinalization = (typeof FinalizationRegistry === 'undefined')
|
||||
? { register: () => {}, unregister: () => {} }
|
||||
|
@ -291,17 +433,32 @@ export class Matrix {
|
|||
wasm.__wbg_set_matrix_value(this.__wbg_ptr, ptr0, len0);
|
||||
}
|
||||
/**
|
||||
* @returns {number}
|
||||
* @returns {Margin}
|
||||
*/
|
||||
get width() {
|
||||
const ret = wasm.__wbg_get_matrix_width(this.__wbg_ptr);
|
||||
return ret >>> 0;
|
||||
get margin() {
|
||||
const ret = wasm.__wbg_get_matrix_margin(this.__wbg_ptr);
|
||||
return Margin.__wrap(ret);
|
||||
}
|
||||
/**
|
||||
* @param {number} arg0
|
||||
* @param {Margin} arg0
|
||||
*/
|
||||
set width(arg0) {
|
||||
wasm.__wbg_set_matrix_width(this.__wbg_ptr, arg0);
|
||||
set margin(arg0) {
|
||||
_assertClass(arg0, Margin);
|
||||
var ptr0 = arg0.__destroy_into_raw();
|
||||
wasm.__wbg_set_matrix_margin(this.__wbg_ptr, ptr0);
|
||||
}
|
||||
/**
|
||||
* @returns {Mode}
|
||||
*/
|
||||
get mode() {
|
||||
const ret = wasm.__wbg_get_matrix_mode(this.__wbg_ptr);
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @param {Mode} arg0
|
||||
*/
|
||||
set mode(arg0) {
|
||||
wasm.__wbg_set_matrix_mode(this.__wbg_ptr, arg0);
|
||||
}
|
||||
/**
|
||||
* @returns {Version}
|
||||
|
@ -344,6 +501,20 @@ export class Matrix {
|
|||
set mask(arg0) {
|
||||
wasm.__wbg_set_matrix_mask(this.__wbg_ptr, arg0);
|
||||
}
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
width() {
|
||||
const ret = wasm.matrix_width(this.__wbg_ptr);
|
||||
return ret >>> 0;
|
||||
}
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
height() {
|
||||
const ret = wasm.matrix_height(this.__wbg_ptr);
|
||||
return ret >>> 0;
|
||||
}
|
||||
}
|
||||
|
||||
const QrOptionsFinalization = (typeof FinalizationRegistry === 'undefined')
|
||||
|
@ -417,6 +588,17 @@ export class QrOptions {
|
|||
const ret = wasm.qroptions_mask(ptr, isLikeNone(mask) ? 8 : mask);
|
||||
return QrOptions.__wrap(ret);
|
||||
}
|
||||
/**
|
||||
* @param {Margin} margin
|
||||
* @returns {QrOptions}
|
||||
*/
|
||||
margin(margin) {
|
||||
const ptr = this.__destroy_into_raw();
|
||||
_assertClass(margin, Margin);
|
||||
var ptr0 = margin.__destroy_into_raw();
|
||||
const ret = wasm.qroptions_margin(ptr, ptr0);
|
||||
return QrOptions.__wrap(ret);
|
||||
}
|
||||
}
|
||||
|
||||
const SvgOptionsFinalization = (typeof FinalizationRegistry === 'undefined')
|
||||
|
@ -493,34 +675,34 @@ export class SvgOptions {
|
|||
return SvgOptions.__wrap(ret);
|
||||
}
|
||||
/**
|
||||
* @param {Float64Array} scale_matrix
|
||||
* @param {Uint8Array} scale_matrix
|
||||
* @returns {SvgOptions}
|
||||
*/
|
||||
scale_x_matrix(scale_matrix) {
|
||||
const ptr = this.__destroy_into_raw();
|
||||
const ptr0 = passArrayF64ToWasm0(scale_matrix, wasm.__wbindgen_malloc);
|
||||
const ptr0 = passArray8ToWasm0(scale_matrix, wasm.__wbindgen_malloc);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
const ret = wasm.svgoptions_scale_x_matrix(ptr, ptr0, len0);
|
||||
return SvgOptions.__wrap(ret);
|
||||
}
|
||||
/**
|
||||
* @param {Float64Array} scale_matrix
|
||||
* @param {Uint8Array} scale_matrix
|
||||
* @returns {SvgOptions}
|
||||
*/
|
||||
scale_y_matrix(scale_matrix) {
|
||||
const ptr = this.__destroy_into_raw();
|
||||
const ptr0 = passArrayF64ToWasm0(scale_matrix, wasm.__wbindgen_malloc);
|
||||
const ptr0 = passArray8ToWasm0(scale_matrix, wasm.__wbindgen_malloc);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
const ret = wasm.svgoptions_scale_y_matrix(ptr, ptr0, len0);
|
||||
return SvgOptions.__wrap(ret);
|
||||
}
|
||||
/**
|
||||
* @param {Float64Array} scale_matrix
|
||||
* @param {Uint8Array} scale_matrix
|
||||
* @returns {SvgOptions}
|
||||
*/
|
||||
scale_matrix(scale_matrix) {
|
||||
const ptr = this.__destroy_into_raw();
|
||||
const ptr0 = passArrayF64ToWasm0(scale_matrix, wasm.__wbindgen_malloc);
|
||||
const ptr0 = passArray8ToWasm0(scale_matrix, wasm.__wbindgen_malloc);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
const ret = wasm.svgoptions_scale_matrix(ptr, ptr0, len0);
|
||||
return SvgOptions.__wrap(ret);
|
||||
|
@ -732,9 +914,6 @@ function __wbg_get_imports() {
|
|||
const ret = arg0;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
|
||||
takeObject(arg0);
|
||||
};
|
||||
imports.wbg.__wbindgen_try_into_number = function(arg0) {
|
||||
let result;
|
||||
try { result = +getObject(arg0) } catch (e) { result = e }
|
||||
|
@ -747,6 +926,9 @@ imports.wbg.__wbindgen_number_get = function(arg0, arg1) {
|
|||
getFloat64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
|
||||
takeObject(arg0);
|
||||
};
|
||||
imports.wbg.__wbg_new_abda76e883ba8a5f = function() {
|
||||
const ret = new Error();
|
||||
return addHeapObject(ret);
|
||||
|
|
Plik binarny nie jest wyświetlany.
|
@ -1,23 +1,44 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export const memory: WebAssembly.Memory;
|
||||
export function __wbg_margin_free(a: number): void;
|
||||
export function __wbg_get_margin_top(a: number): number;
|
||||
export function __wbg_set_margin_top(a: number, b: number): void;
|
||||
export function __wbg_get_margin_right(a: number): number;
|
||||
export function __wbg_set_margin_right(a: number, b: number): void;
|
||||
export function __wbg_get_margin_bottom(a: number): number;
|
||||
export function __wbg_set_margin_bottom(a: number, b: number): void;
|
||||
export function __wbg_get_margin_left(a: number): number;
|
||||
export function __wbg_set_margin_left(a: number, b: number): void;
|
||||
export function margin_new(a: number): number;
|
||||
export function margin_setTop(a: number, b: number): number;
|
||||
export function margin_setRight(a: number, b: number): number;
|
||||
export function margin_setBottom(a: number, b: number): number;
|
||||
export function margin_setLeft(a: number, b: number): number;
|
||||
export function margin_y(a: number, b: number): number;
|
||||
export function margin_x(a: number, b: number): number;
|
||||
export function __wbg_matrix_free(a: number): void;
|
||||
export function __wbg_get_matrix_value(a: number, b: number): void;
|
||||
export function __wbg_set_matrix_value(a: number, b: number, c: number): void;
|
||||
export function __wbg_get_matrix_width(a: number): number;
|
||||
export function __wbg_set_matrix_width(a: number, b: number): void;
|
||||
export function __wbg_get_matrix_margin(a: number): number;
|
||||
export function __wbg_set_matrix_margin(a: number, b: number): void;
|
||||
export function __wbg_get_matrix_mode(a: number): number;
|
||||
export function __wbg_set_matrix_mode(a: number, b: number): void;
|
||||
export function __wbg_get_matrix_version(a: number): number;
|
||||
export function __wbg_set_matrix_version(a: number, b: number): void;
|
||||
export function __wbg_get_matrix_ecl(a: number): number;
|
||||
export function __wbg_set_matrix_ecl(a: number, b: number): void;
|
||||
export function __wbg_get_matrix_mask(a: number): number;
|
||||
export function __wbg_set_matrix_mask(a: number, b: number): void;
|
||||
export function matrix_width(a: number): number;
|
||||
export function matrix_height(a: number): number;
|
||||
export function __wbg_qroptions_free(a: number): void;
|
||||
export function qroptions_new(): number;
|
||||
export function qroptions_min_version(a: number, b: number): number;
|
||||
export function qroptions_min_ecl(a: number, b: number): number;
|
||||
export function qroptions_mode(a: number, b: number): number;
|
||||
export function qroptions_mask(a: number, b: number): number;
|
||||
export function qroptions_margin(a: number, b: number): number;
|
||||
export function __wbg_svgoptions_free(a: number): void;
|
||||
export function svgoptions_new(): number;
|
||||
export function svgoptions_margin(a: number, b: number): number;
|
||||
|
|
32
src/app.tsx
32
src/app.tsx
|
@ -4,29 +4,23 @@ import "virtual:uno.css";
|
|||
import { Router } from "@solidjs/router";
|
||||
import { FileRoutes } from "@solidjs/start/router";
|
||||
import { Suspense } from "solid-js";
|
||||
import { QrContextProvider } from "./lib/QrContext";
|
||||
import { SvgContextProvider } from "./lib/SvgContext";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<>
|
||||
<QrContextProvider>
|
||||
<SvgContextProvider>
|
||||
<Router root={(props) => <Suspense>{props.children}</Suspense>}>
|
||||
<FileRoutes />
|
||||
</Router>
|
||||
<footer class="text-sm text-center p-4">
|
||||
made with ⬛⬜ by{" "}
|
||||
<a
|
||||
class="font-semibold hover:text-fore-base/80 focus-visible:(outline-none ring-2 ring-fore-base ring-offset-2 ring-offset-back-base)"
|
||||
href="https://kylezhe.ng"
|
||||
target="_blank"
|
||||
>
|
||||
@zhengkyl
|
||||
</a>
|
||||
</footer>
|
||||
</SvgContextProvider>
|
||||
</QrContextProvider>
|
||||
<Router root={(props) => <Suspense>{props.children}</Suspense>}>
|
||||
<FileRoutes />
|
||||
</Router>
|
||||
<footer class="text-sm text-center p-4">
|
||||
made with ⬛⬜ by{" "}
|
||||
<a
|
||||
class="font-semibold hover:text-fore-base/80 focus-visible:(outline-none ring-2 ring-fore-base ring-offset-2 ring-offset-back-base)"
|
||||
href="https://kylezhe.ng"
|
||||
target="_blank"
|
||||
>
|
||||
@zhengkyl
|
||||
</a>
|
||||
</footer>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -19,10 +19,14 @@ import { NumberInput } from "./NumberInput";
|
|||
import { Select } from "./Select";
|
||||
import { Switch } from "./Switch";
|
||||
import { useSvgContext } from "~/lib/SvgContext";
|
||||
import { usePaintContext } from "~/lib/PaintContext";
|
||||
import { qroptions_margin } from "../../fuqr/pkg/fuqr_bg.wasm";
|
||||
|
||||
export function Editor(props: any) {
|
||||
const { inputQr, setInputQr } = useQrContext();
|
||||
const { inputQr, setInputQr, outputQr } = useQrContext();
|
||||
const { svgOptions, setSvgOptions } = useSvgContext();
|
||||
const { selections, scaleX, scaleY, setScaleXInPlace, setScaleYInPlace } =
|
||||
usePaintContext();
|
||||
|
||||
// const [logoSize, setLogoSize] = createSignal(25);
|
||||
|
||||
|
@ -67,15 +71,15 @@ export function Editor(props: any) {
|
|||
</For>
|
||||
</ButtonGroup>
|
||||
</Row>
|
||||
<Row title="Margin">
|
||||
{/* <Row title="Margin">
|
||||
<NumberInput
|
||||
min={0}
|
||||
max={10}
|
||||
step={1}
|
||||
value={svgOptions.margin}
|
||||
setValue={(v) => setSvgOptions("margin", v)}
|
||||
value={inputQr.margin.top}
|
||||
setValue={(v) => setInputQr("margin", (prev) => prev.setTop(v))}
|
||||
/>
|
||||
</Row>
|
||||
</Row> */}
|
||||
<Row title="Foreground">
|
||||
<ColorInput
|
||||
color={svgOptions.fgColor}
|
||||
|
@ -132,6 +136,64 @@ export function Editor(props: any) {
|
|||
/> */}
|
||||
</div>
|
||||
</Row>
|
||||
<Row title="Scale X">
|
||||
<NumberInput
|
||||
min={0}
|
||||
max={200}
|
||||
step={1}
|
||||
value={
|
||||
selections().length
|
||||
? scaleX()[
|
||||
selections()[0].top * Math.sqrt(scaleX().length) +
|
||||
selections()[0].left
|
||||
]
|
||||
: 100
|
||||
}
|
||||
setValue={(v) => {
|
||||
if (!selections().length) return
|
||||
setScaleXInPlace((prev) => {
|
||||
let width = Math.sqrt(prev.length);
|
||||
selections().forEach((sel) => {
|
||||
for (let i = sel.top; i < sel.bot; i++) {
|
||||
for (let j = sel.left; j < sel.right; j++) {
|
||||
prev[i * width + j] = v;
|
||||
}
|
||||
}
|
||||
});
|
||||
return prev;
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Row>
|
||||
<Row title="Scale Y">
|
||||
<NumberInput
|
||||
min={0}
|
||||
max={200}
|
||||
step={1}
|
||||
value={
|
||||
selections().length
|
||||
? scaleY()[
|
||||
selections()[0].top * Math.sqrt(scaleY().length) +
|
||||
selections()[0].left
|
||||
]
|
||||
: 100
|
||||
}
|
||||
setValue={(v) => {
|
||||
if (!selections().length) return
|
||||
setScaleYInPlace((prev) => {
|
||||
let width = Math.sqrt(prev.length);
|
||||
selections().forEach((sel) => {
|
||||
for (let i = sel.top; i < sel.bot; i++) {
|
||||
for (let j = sel.left; j < sel.right; j++) {
|
||||
prev[i * width + j] = v;
|
||||
}
|
||||
}
|
||||
});
|
||||
return prev;
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -25,7 +25,12 @@ export function NumberInput(props: Props) {
|
|||
) {
|
||||
return;
|
||||
}
|
||||
props.setValue(value);
|
||||
|
||||
if (value !== props.value) {
|
||||
// TODO, revisit this for x scale/y scale slider
|
||||
// console.log("safe Set", value);
|
||||
props.setValue(value);
|
||||
}
|
||||
};
|
||||
|
||||
const [focused, setFocused] = createSignal(false);
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import { createEffect, createSignal, onCleanup } from "solid-js";
|
||||
import { type SetStoreFunction } from "solid-js/store";
|
||||
import { usePaintContext, type BoxSelection } from "~/lib/PaintContext";
|
||||
|
||||
type Props = {
|
||||
width: number;
|
||||
height: number;
|
||||
color: number;
|
||||
grid: number[];
|
||||
setGrid: SetStoreFunction<number[]>;
|
||||
// grid: number[];
|
||||
// setGrid: SetStoreFunction<number[]>;
|
||||
};
|
||||
|
||||
enum Mode {
|
||||
|
@ -27,6 +28,8 @@ function clamp(a: number, min: number, max: number) {
|
|||
}
|
||||
|
||||
export function RenderGrid(props: Props) {
|
||||
const { selections, setSelectionsInPlace } = usePaintContext();
|
||||
|
||||
let canvas: HTMLCanvasElement;
|
||||
let ctx: CanvasRenderingContext2D;
|
||||
|
||||
|
@ -45,17 +48,17 @@ export function RenderGrid(props: Props) {
|
|||
};
|
||||
|
||||
const setPixel = (x: number, y: number) => {
|
||||
if (props.color === props.grid[y * props.width + x]) return;
|
||||
// if (props.color === props.grid[y * props.width + x]) return;
|
||||
|
||||
props.setGrid(y * props.width + x, props.color!);
|
||||
if (props.color) {
|
||||
ctx.fillRect(x * UNIT, y * UNIT, UNIT, UNIT);
|
||||
} else {
|
||||
ctx.clearRect(x * UNIT, y * UNIT, UNIT, UNIT);
|
||||
}
|
||||
// props.setGrid(y * props.width + x, props.color!);
|
||||
// if (props.color) {
|
||||
// ctx.fillRect(x * UNIT, y * UNIT, UNIT, UNIT);
|
||||
// } else {
|
||||
// ctx.clearRect(x * UNIT, y * UNIT, UNIT, UNIT);
|
||||
// }
|
||||
};
|
||||
|
||||
let selection: Selection | null;
|
||||
let selection: BoxSelection | null;
|
||||
|
||||
function onMouseMove(e: MouseEvent) {
|
||||
const { x, y } = getPos(e);
|
||||
|
@ -66,7 +69,7 @@ export function RenderGrid(props: Props) {
|
|||
selectCtx.clearRect(0, 0, props.width * UNIT, props.height * UNIT);
|
||||
|
||||
selectCtx.fillStyle = "rgb(59, 130, 246)";
|
||||
selectedBoxes.forEach((sel) => {
|
||||
selections().forEach((sel) => {
|
||||
selectCtx.fillRect(
|
||||
sel.left * UNIT,
|
||||
sel.top * UNIT,
|
||||
|
@ -142,7 +145,11 @@ export function RenderGrid(props: Props) {
|
|||
|
||||
const onMouseUp = () => {
|
||||
if (selection != null) {
|
||||
selectedBoxes.push(selection);
|
||||
setSelectionsInPlace((prev) => {
|
||||
// @ts-expect-error i'm right unless somehow this isn't synchronous
|
||||
prev.push(selection);
|
||||
return prev;
|
||||
});
|
||||
}
|
||||
document.removeEventListener("mousemove", onMouseMove);
|
||||
document.removeEventListener("mouseup", onMouseUp);
|
||||
|
@ -157,19 +164,13 @@ export function RenderGrid(props: Props) {
|
|||
|
||||
const [brushSize, setBrushSize] = createSignal(1);
|
||||
|
||||
let selectedBoxes: Selection[] = [];
|
||||
// let selectedBoxes: Selection[] = [];
|
||||
|
||||
let prevX: number;
|
||||
let prevY: number;
|
||||
|
||||
let deselectIntent: boolean;
|
||||
|
||||
createEffect(() => {
|
||||
props.width;
|
||||
props.height;
|
||||
selectedBoxes = [];
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<canvas
|
||||
|
@ -199,7 +200,7 @@ export function RenderGrid(props: Props) {
|
|||
if (mode() === Mode.Select) {
|
||||
deselectIntent = false;
|
||||
if (!(e.shiftKey || e.ctrlKey)) {
|
||||
deselectIntent = selectedBoxes.length > 0;
|
||||
deselectIntent = selections().length > 0;
|
||||
|
||||
if (deselectIntent) {
|
||||
selectCtx.clearRect(
|
||||
|
@ -208,8 +209,8 @@ export function RenderGrid(props: Props) {
|
|||
props.width * UNIT,
|
||||
props.height * UNIT
|
||||
);
|
||||
selectedBoxes = [];
|
||||
selection = null
|
||||
setSelectionsInPlace([]);
|
||||
selection = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import {
|
||||
QrOptions,
|
||||
SvgOptions,
|
||||
Version,
|
||||
get_svg,
|
||||
SvgError,
|
||||
QrError,
|
||||
Version,
|
||||
SvgResult,
|
||||
} from "fuqr";
|
||||
|
||||
|
@ -17,45 +17,43 @@ import {
|
|||
MODE_KEY,
|
||||
MODE_NAMES,
|
||||
} from "~/lib/options";
|
||||
import { createStore } from "solid-js/store";
|
||||
import { RenderGrid } from "../RenderGrid";
|
||||
import { useQrContext } from "~/lib/QrContext";
|
||||
import { useQrContext, type OutputQr } from "~/lib/QrContext";
|
||||
import { useSvgContext } from "~/lib/SvgContext";
|
||||
import { usePaintContext } from "~/lib/PaintContext";
|
||||
|
||||
const PIXELS_PER_MODULE = 20;
|
||||
|
||||
export default function SvgPreview() {
|
||||
const { inputQr } = useQrContext();
|
||||
const { inputQr, outputQr, setOutputQr } = useQrContext();
|
||||
|
||||
const { svgOptions } = useSvgContext();
|
||||
const { scaleX, scaleY } = usePaintContext();
|
||||
|
||||
const [grid, setGrid] = createStore(Array(177 * 177).fill(100));
|
||||
const svgResult = createMemo(() => {
|
||||
console.log("svgResult", inputQr);
|
||||
// what if iterate func return list of coords
|
||||
// combine with list of true/false for placement
|
||||
//
|
||||
let output = outputQr();
|
||||
if (typeof output === "number") {
|
||||
// See <Show> component
|
||||
// svgResult() only called when outputQr() is successful
|
||||
return null as unknown as SvgResult;
|
||||
}
|
||||
const qrOptions = new QrOptions()
|
||||
.min_version(new Version(inputQr.minVersion))
|
||||
.min_ecl(inputQr.minEcl)
|
||||
.mask(inputQr.mask!) // null makes more sense than undefined
|
||||
.mode(inputQr.mode!); // null makes more sense than undefined
|
||||
.min_version(new Version(output.version))
|
||||
.min_ecl(output.ecl)
|
||||
.mask(output.mask!) // wasm-bindgen types None as `undefined`, but null works
|
||||
.mode(output.mode!); // wasm-bindgen types None as `undefined`, but null works
|
||||
|
||||
let svgOpts = new SvgOptions()
|
||||
// .finder_pattern(props.finderPattern)
|
||||
// .finder_roundness(props.finderRoundness)
|
||||
// .margin(margin)
|
||||
.foreground(svgOptions.fgColor)
|
||||
.background(svgOptions.bgColor)
|
||||
.scale_matrix(grid);
|
||||
.scale_x_matrix(new Uint8Array(scaleX()))
|
||||
.scale_y_matrix(new Uint8Array(scaleY()));
|
||||
|
||||
let t;
|
||||
try {
|
||||
t = get_svg(inputQr.text, qrOptions, svgOpts);
|
||||
} catch (e) {
|
||||
// <Show> doesn't play nicely with unions
|
||||
// this requires one "as any" instead of 20
|
||||
t = e as SvgResult;
|
||||
}
|
||||
console.log(typeof t);
|
||||
return t;
|
||||
// infallible b/c outputQr contains successful options
|
||||
return get_svg(inputQr.text, qrOptions, svgOpts);
|
||||
});
|
||||
|
||||
function download(href: string, name: string) {
|
||||
|
@ -73,33 +71,31 @@ export default function SvgPreview() {
|
|||
const bgSrc = () => URL.createObjectURL(svgOptions.bgImgFile!);
|
||||
const logoSrc = () => URL.createObjectURL(svgOptions.fgImgFile!);
|
||||
|
||||
const fullWidth = () =>
|
||||
svgResult().version["0"] * 4 + 17 + 2 * svgOptions.margin;
|
||||
|
||||
const checkerboardPixel = () => (1 / fullWidth()) * 100;
|
||||
const fullWidth = () => {
|
||||
const output = outputQr() as OutputQr;
|
||||
return output.version * 4 + 17 + output.margin.left + output.margin.right;
|
||||
};
|
||||
const fullHeight = () => {
|
||||
const output = outputQr() as OutputQr;
|
||||
return output.version * 4 + 17 + output.margin.top + output.margin.bottom;
|
||||
};
|
||||
|
||||
const [color, setColor] = createSignal(0);
|
||||
|
||||
// createEffect(() => {
|
||||
// console.log("effect", svgResult());
|
||||
// });
|
||||
|
||||
return (
|
||||
<>
|
||||
<Show
|
||||
when={typeof svgResult() != "number" && svgResult() != null}
|
||||
when={typeof outputQr() != "number"}
|
||||
fallback={
|
||||
<div class="aspect-[1/1] border rounded-md flex justify-center items-center">
|
||||
<Switch>
|
||||
<Match
|
||||
when={(svgResult() as any) === SvgError.ExceedsMaxCapacity}
|
||||
>
|
||||
<Match when={outputQr() === QrError.ExceedsMaxCapacity}>
|
||||
Data exceeds max capacity
|
||||
</Match>
|
||||
<Match when={(svgResult() as any) === SvgError.InvalidEncoding}>
|
||||
<Match when={outputQr() === QrError.InvalidEncoding}>
|
||||
{`Input cannot be encoded in ${
|
||||
// @ts-expect-error props.mode not null b/c InvalidEncoding implies mode
|
||||
MODE_NAMES[props.mode + 1]
|
||||
MODE_NAMES[inputQr.mode + 1]
|
||||
} mode`}
|
||||
</Match>
|
||||
</Switch>
|
||||
|
@ -112,7 +108,9 @@ export default function SvgPreview() {
|
|||
"background-image":
|
||||
"repeating-conic-gradient(#ddd 0% 25%, #aaa 25% 50%)",
|
||||
"background-position": "50%",
|
||||
"background-size": `${checkerboardPixel()}% ${checkerboardPixel()}%`,
|
||||
"background-size": `${(1 / fullWidth()) * 100}% ${
|
||||
(1 / fullHeight()) * 100
|
||||
}%`,
|
||||
}}
|
||||
>
|
||||
<Show when={svgOptions.bgImgFile != null}>
|
||||
|
@ -144,10 +142,8 @@ export default function SvgPreview() {
|
|||
</Show>
|
||||
<RenderGrid
|
||||
width={fullWidth()}
|
||||
height={fullWidth()}
|
||||
height={fullHeight()}
|
||||
color={color()}
|
||||
grid={grid}
|
||||
setGrid={setGrid}
|
||||
/>
|
||||
</div>
|
||||
<div class="p-4 grid grid-cols-2 gap-y-2 text-sm text-left">
|
||||
|
@ -181,10 +177,11 @@ export default function SvgPreview() {
|
|||
<FlatButton
|
||||
class="flex-1 px-3 py-2"
|
||||
onClick={async () => {
|
||||
const size = fullWidth() * PIXELS_PER_MODULE;
|
||||
const width = fullWidth() * PIXELS_PER_MODULE;
|
||||
const height = fullHeight() * PIXELS_PER_MODULE;
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = size;
|
||||
canvas.height = size;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
if (svgOptions.bgImgFile != null) {
|
||||
|
@ -192,13 +189,13 @@ export default function SvgPreview() {
|
|||
const bgImg = new Image();
|
||||
bgImg.src = bgSrc();
|
||||
await bgImg.decode();
|
||||
ctx!.drawImage(bgImg, 0, 0, size, size);
|
||||
ctx!.drawImage(bgImg, 0, 0, width, height);
|
||||
}
|
||||
|
||||
const svgImg = new Image();
|
||||
svgImg.src = `data:image/svg+xml;base64,${btoa(svgResult().svg)}`;
|
||||
await svgImg.decode();
|
||||
ctx!.drawImage(svgImg, 0, 0, size, size);
|
||||
ctx!.drawImage(svgImg, 0, 0, width, height);
|
||||
|
||||
if (svgOptions.fgImgFile != null) {
|
||||
ctx!.imageSmoothingEnabled = !svgOptions.pixelateFgImg;
|
||||
|
@ -207,8 +204,9 @@ export default function SvgPreview() {
|
|||
await logoImg.decode();
|
||||
// TODO logoSize
|
||||
const logoSize = (fullWidth() / 4) * PIXELS_PER_MODULE;
|
||||
const offset = (size - logoSize) / 2;
|
||||
ctx!.drawImage(logoImg, offset, offset, logoSize, logoSize);
|
||||
const xOffset = (width - logoSize) / 2;
|
||||
const yOffset = (height - logoSize) / 2;
|
||||
ctx!.drawImage(logoImg, xOffset, yOffset, logoSize, logoSize);
|
||||
}
|
||||
|
||||
download(
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
import {
|
||||
createContext,
|
||||
createEffect,
|
||||
createSignal,
|
||||
untrack,
|
||||
useContext,
|
||||
type Accessor,
|
||||
type JSX,
|
||||
type Setter,
|
||||
} from "solid-js";
|
||||
import { useQrContext } from "./QrContext";
|
||||
import { useSvgContext } from "./SvgContext";
|
||||
import { Margin, QrOptions, Version, get_matrix, type QrError } from "fuqr";
|
||||
|
||||
export type BoxSelection = {
|
||||
top: number;
|
||||
bot: number;
|
||||
left: number;
|
||||
right: number;
|
||||
};
|
||||
|
||||
export const PaintContext = createContext<{
|
||||
selections: Accessor<BoxSelection[]>;
|
||||
setSelectionsInPlace: Setter<BoxSelection[]>;
|
||||
scaleX: Accessor<number[]>;
|
||||
setScaleXInPlace: Setter<number[]>;
|
||||
scaleY: Accessor<number[]>;
|
||||
setScaleYInPlace: Setter<number[]>;
|
||||
}>();
|
||||
|
||||
export function PaintContextProvider(props: { children: JSX.Element }) {
|
||||
const { inputQr, outputQr, setOutputQr } = useQrContext();
|
||||
const { svgOptions } = useSvgContext();
|
||||
|
||||
const [selections, setSelectionsInPlace] = createSignal<BoxSelection[]>([], {
|
||||
equals: false,
|
||||
});
|
||||
|
||||
const [scaleX, setScaleXInPlace] = createSignal<number[]>([], {
|
||||
equals: false,
|
||||
});
|
||||
const [scaleY, setScaleYInPlace] = createSignal<number[]>([], {
|
||||
equals: false,
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
try {
|
||||
// NOTE: Version and Margin cannot be reused, so must be created each time
|
||||
const qrOptions = new QrOptions()
|
||||
.min_version(new Version(inputQr.minVersion))
|
||||
.min_ecl(inputQr.minEcl)
|
||||
.mask(inputQr.mask!) // null makes more sense than undefined
|
||||
.mode(inputQr.mode!) // null makes more sense than undefined
|
||||
.margin(new Margin(10))
|
||||
.margin(
|
||||
new Margin(0)
|
||||
.setTop(inputQr.margin.top)
|
||||
.setRight(inputQr.margin.right)
|
||||
.setBottom(inputQr.margin.bottom)
|
||||
.setLeft(inputQr.margin.left)
|
||||
);
|
||||
|
||||
let m = get_matrix(inputQr.text, qrOptions);
|
||||
setOutputQr({
|
||||
text: inputQr.text,
|
||||
version: m.version["0"],
|
||||
ecl: m.ecl,
|
||||
mode: m.mode,
|
||||
mask: m.mask,
|
||||
margin: {
|
||||
top: m.margin.top,
|
||||
right: m.margin.right,
|
||||
bottom: m.margin.bottom,
|
||||
left: m.margin.left,
|
||||
},
|
||||
});
|
||||
const matrixLength = m.width() * m.height();
|
||||
if (matrixLength === untrack(scaleX).length) return;
|
||||
|
||||
setSelectionsInPlace([]);
|
||||
setScaleXInPlace(Array(matrixLength).fill(100));
|
||||
setScaleYInPlace(Array(matrixLength).fill(100));
|
||||
} catch (e) {
|
||||
setOutputQr(e as QrError);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<PaintContext.Provider
|
||||
value={{
|
||||
selections,
|
||||
setSelectionsInPlace,
|
||||
scaleX,
|
||||
setScaleXInPlace,
|
||||
scaleY,
|
||||
setScaleYInPlace,
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
</PaintContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function usePaintContext() {
|
||||
const context = useContext(PaintContext);
|
||||
if (!context) {
|
||||
throw new Error("usePaintContext: used outside PaintContextProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
|
@ -2,10 +2,11 @@ import {
|
|||
createContext,
|
||||
createSignal,
|
||||
useContext,
|
||||
type Accessor,
|
||||
type JSX,
|
||||
type Setter,
|
||||
} from "solid-js";
|
||||
import { ECL, Mode, Mask } from "fuqr";
|
||||
import { ECL, Mode, Mask, QrError } from "fuqr";
|
||||
import { createStore, type SetStoreFunction } from "solid-js/store";
|
||||
|
||||
type InputQr = {
|
||||
|
@ -14,21 +15,35 @@ type InputQr = {
|
|||
minEcl: ECL;
|
||||
mode: Mode | null;
|
||||
mask: Mask | null;
|
||||
margin: {
|
||||
top: number;
|
||||
right: number;
|
||||
bottom: number;
|
||||
left: number;
|
||||
};
|
||||
};
|
||||
|
||||
type OutputQr = {
|
||||
export type OutputQr = {
|
||||
text: string;
|
||||
/** Stored as value b/c Version is a ptr which becomes null after use */
|
||||
version: number;
|
||||
ecl: ECL;
|
||||
mode: Mode;
|
||||
mask: Mask;
|
||||
/** Stored as value b/c Margin is a ptr which becomes null after use */
|
||||
margin: {
|
||||
top: number;
|
||||
right: number;
|
||||
bottom: number;
|
||||
left: number;
|
||||
};
|
||||
};
|
||||
|
||||
export const QrContext = createContext<{
|
||||
inputQr: InputQr;
|
||||
setInputQr: SetStoreFunction<InputQr>;
|
||||
outputQr: OutputQr | null;
|
||||
setOutputQr: Setter<OutputQr | null>;
|
||||
outputQr: Accessor<OutputQr | QrError>;
|
||||
setOutputQr: Setter<OutputQr | QrError>;
|
||||
}>();
|
||||
|
||||
export function QrContextProvider(props: { children: JSX.Element }) {
|
||||
|
@ -38,14 +53,20 @@ export function QrContextProvider(props: { children: JSX.Element }) {
|
|||
minEcl: ECL.Low,
|
||||
mode: null,
|
||||
mask: null,
|
||||
margin: {
|
||||
top: 2,
|
||||
right: 2,
|
||||
bottom: 2,
|
||||
left: 2,
|
||||
},
|
||||
});
|
||||
|
||||
const [outputQr, setOutputQr] = createSignal<OutputQr | null>(null);
|
||||
const [outputQr, setOutputQr] = createSignal<OutputQr | QrError>(
|
||||
QrError.InvalidEncoding
|
||||
);
|
||||
|
||||
return (
|
||||
<QrContext.Provider
|
||||
value={{ inputQr, setInputQr, outputQr: outputQr(), setOutputQr }}
|
||||
>
|
||||
<QrContext.Provider value={{ inputQr, setInputQr, outputQr, setOutputQr }}>
|
||||
{props.children}
|
||||
</QrContext.Provider>
|
||||
);
|
||||
|
|
|
@ -2,7 +2,6 @@ import { createContext, useContext, type JSX } from "solid-js";
|
|||
import { createStore, type SetStoreFunction } from "solid-js/store";
|
||||
|
||||
type SvgOptions = {
|
||||
margin: number;
|
||||
bgColor: string;
|
||||
fgColor: string;
|
||||
bgImgFile: File | null;
|
||||
|
@ -18,7 +17,6 @@ export const SvgContext = createContext<{
|
|||
|
||||
export function SvgContextProvider(props: { children: JSX.Element }) {
|
||||
const [svgOptions, setSvgOptions] = createStore<SvgOptions>({
|
||||
margin: 2,
|
||||
bgColor: "#ffffff",
|
||||
fgColor: "#000000",
|
||||
bgImgFile: null,
|
||||
|
@ -28,12 +26,7 @@ export function SvgContextProvider(props: { children: JSX.Element }) {
|
|||
});
|
||||
|
||||
return (
|
||||
<SvgContext.Provider
|
||||
value={{
|
||||
svgOptions: svgOptions,
|
||||
setSvgOptions: setSvgOptions,
|
||||
}}
|
||||
>
|
||||
<SvgContext.Provider value={{ svgOptions, setSvgOptions }}>
|
||||
{props.children}
|
||||
</SvgContext.Provider>
|
||||
);
|
||||
|
|
|
@ -2,10 +2,15 @@ import { Switch, Match, createSignal } from "solid-js";
|
|||
import { clientOnly } from "@solidjs/start";
|
||||
import init from "fuqr";
|
||||
import { Editor } from "~/components/Editor";
|
||||
import SvgPreview from "~/components/qr/SvgPreview";
|
||||
import { PaintContextProvider } from "~/lib/PaintContext";
|
||||
import { SvgContextProvider } from "~/lib/SvgContext";
|
||||
|
||||
const QRCode = clientOnly(async () => {
|
||||
const QrContextProvider = clientOnly(async () => {
|
||||
await init();
|
||||
return import("../components/qr/SvgPreview");
|
||||
return {
|
||||
default: (await import("../lib/QrContext")).QrContextProvider,
|
||||
};
|
||||
});
|
||||
|
||||
// const MODULE_NAMES = [
|
||||
|
@ -24,18 +29,24 @@ enum Stage {
|
|||
export default function Home() {
|
||||
const [stage, setStage] = createSignal(Stage.Create);
|
||||
return (
|
||||
<main class="max-w-screen-lg mx-auto">
|
||||
<Switch>
|
||||
<Match when={stage() == Stage.Create}>
|
||||
<div class="flex gap-4 flex-wrap">
|
||||
<Editor />
|
||||
<div class="flex-1 min-w-200px sticky top-0 self-start p-4">
|
||||
<QRCode />
|
||||
</div>
|
||||
</div>
|
||||
</Match>
|
||||
{/* <Match when={stage() == Stage.Customize}></Match> */}
|
||||
</Switch>
|
||||
</main>
|
||||
<QrContextProvider>
|
||||
<SvgContextProvider>
|
||||
<PaintContextProvider>
|
||||
<main class="max-w-screen-lg mx-auto">
|
||||
<Switch>
|
||||
<Match when={stage() == Stage.Create}>
|
||||
<div class="flex gap-4 flex-wrap">
|
||||
<Editor />
|
||||
<div class="flex-1 min-w-200px sticky top-0 self-start p-4">
|
||||
<SvgPreview />
|
||||
</div>
|
||||
</div>
|
||||
</Match>
|
||||
{/* <Match when={stage() == Stage.Customize}></Match> */}
|
||||
</Switch>
|
||||
</main>
|
||||
</PaintContextProvider>
|
||||
</SvgContextProvider>
|
||||
</QrContextProvider>
|
||||
);
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue