{canvasDims().width}x{canvasDims().height} px
@@ -194,7 +213,7 @@ function RenderedQrCode() {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d")!;
// TODO allow adjust resolution/aspect ratio
- const size = 300 //(outputQr().version * 4 + 17) * 10;
+ const size = 300; //(outputQr().version * 4 + 17) * 10;
canvas.width = size;
canvas.height = size;
@@ -214,7 +233,7 @@ function RenderedQrCode() {
Download PNG
-
+
{
diff --git a/src/lib/QrContext.tsx b/src/lib/QrContext.tsx
index 7b574c4..e3eddc0 100644
--- a/src/lib/QrContext.tsx
+++ b/src/lib/QrContext.tsx
@@ -43,14 +43,10 @@ export const QrContext = createContext<{
inputQr: InputQr;
setInputQr: SetStoreFunction;
outputQr: Accessor;
-
- getRenderSVG: Accessor;
- setRenderSVG: Setter;
- getRenderCanvas: Accessor;
- setRenderCanvas: Setter;
-
- renderFuncKey: Accessor;
- setRenderFuncKey: Setter;
+ render: Accessor;
+ setRender: Setter;
+ renderKey: Accessor;
+ setRenderKey: Setter;
params: Params;
setParams: SetStoreFunction;
paramsSchema: Accessor;
@@ -65,6 +61,14 @@ export type RenderCanvas = (
export type RenderSVG = (qr: OutputQr, params: Params) => string;
+const renderTypes = ["svg", "canvas"] as const;
+export type RenderType = (typeof renderTypes)[number];
+
+type Render = {
+ type: RenderType;
+ url: string;
+};
+
export function QrContextProvider(props: { children: JSX.Element }) {
const [inputQr, setInputQr] = createStore({
text: "https://qrframe.kylezhe.ng",
@@ -76,11 +80,8 @@ export function QrContextProvider(props: { children: JSX.Element }) {
mask: null,
});
- const [renderCanvas, setRenderCanvas] = createSignal(
- null
- );
- const [renderSVG, setRenderSVG] = createSignal(null);
- const [renderFuncKey, setRenderFuncKey] = createSignal("");
+ const [renderKey, setRenderKey] = createSignal("Square");
+ const [render, setRender] = createSignal(null);
const [paramsSchema, setParamsSchema] = createSignal({});
const [params, setParams] = createStore({});
@@ -122,12 +123,10 @@ export function QrContextProvider(props: { children: JSX.Element }) {
inputQr,
setInputQr,
outputQr,
- getRenderSVG: renderSVG,
- setRenderSVG,
- getRenderCanvas: renderCanvas,
- setRenderCanvas,
- renderFuncKey,
- setRenderFuncKey,
+ render,
+ setRender,
+ renderKey,
+ setRenderKey,
params,
setParams,
paramsSchema,
@@ -147,13 +146,4 @@ export function useQrContext() {
return context;
}
-// pre generated b/c needed often for thumbnails (generated on every save/load)
-export const PREVIEW_OUTPUTQR = {
- text: "https://qrfra.me",
- // prettier-ignore
- matrix: [3,3,3,3,3,3,3,12,8,0,0,0,0,12,3,3,3,3,3,3,3,3,2,2,2,2,2,3,12,9,0,0,1,1,12,3,2,2,2,2,2,3,3,2,3,3,3,2,3,12,8,1,0,1,1,12,3,2,3,3,3,2,3,3,2,3,3,3,2,3,12,9,1,0,1,0,12,3,2,3,3,3,2,3,3,2,3,3,3,2,3,12,8,0,1,0,0,12,3,2,3,3,3,2,3,3,2,2,2,2,2,3,12,9,1,1,1,1,12,3,2,2,2,2,2,3,3,3,3,3,3,3,3,12,7,6,7,6,7,12,3,3,3,3,3,3,3,12,12,12,12,12,12,12,12,8,0,1,0,0,12,12,12,12,12,12,12,12,9,9,9,9,9,8,7,9,9,1,0,1,0,9,8,9,8,9,8,9,8,0,0,0,1,0,0,6,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,7,1,0,0,1,0,1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,6,0,0,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,0,0,7,1,1,0,0,0,1,1,1,0,1,1,0,0,1,12,12,12,12,12,12,12,12,9,1,0,0,0,0,0,1,1,1,1,0,1,3,3,3,3,3,3,3,12,9,1,1,1,1,1,0,1,0,0,1,1,0,3,2,2,2,2,2,3,12,8,1,0,0,0,1,0,1,1,1,1,0,0,3,2,3,3,3,2,3,12,9,0,0,0,1,1,1,1,1,1,0,0,0,3,2,3,3,3,2,3,12,9,0,1,1,0,0,0,0,1,0,1,1,0,3,2,3,3,3,2,3,12,9,1,1,1,1,0,1,1,0,0,1,0,0,3,2,2,2,2,2,3,12,9,0,0,0,0,1,0,0,1,1,1,0,0,3,3,3,3,3,3,3,12,9,1,0,1,1,0,1,1,0,1,0,1,0],
- version: 1,
- ecl: ECL.Low,
- mode: Mode.Byte,
- mask: Mask.M2,
-};
+
diff --git a/src/lib/presets/Halftone.ts b/src/lib/presets/Halftone.ts
index 0c56692..0092b4c 100644
--- a/src/lib/presets/Halftone.ts
+++ b/src/lib/presets/Halftone.ts
@@ -58,7 +58,7 @@ const Module = {
SeparatorOFF: 12,
};
-export async function renderCanvas(qr, params, ctx) {
+export async function renderCanvas(qr, params, canvas) {
const unit = 3;
const pixel = 1;
@@ -68,10 +68,17 @@ export async function renderCanvas(qr, params, ctx) {
const bg = params["Background"];
const alignment = params["Alignment pattern"];
const timing = params["Timing pattern"];
- const file = params["Image"];
+ let file = params["Image"];
+ if (file == null) {
+ file = await fetch(
+ "https://upload.wikimedia.org/wikipedia/commons/1/14/The_Widow_%28Boston_Public_Library%29_%28cropped%29.jpg"
+ ).then((res) => res.blob());
+ }
+ const image = await createImageBitmap(file)
const pixelWidth = matrixWidth + 2 * margin;
const canvasSize = pixelWidth * unit;
+ const ctx = canvas.getContext("2d");
ctx.canvas.width = canvasSize;
ctx.canvas.height = canvasSize;
@@ -91,27 +98,10 @@ export async function renderCanvas(qr, params, ctx) {
}
}
- const image = new Image();
-
- if (file != null) {
- image.src = URL.createObjectURL(file);
- } else {
- // if canvas tainted, need to reload
- // https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image
- image.crossOrigin = "anonymous";
- image.src =
- "https://upload.wikimedia.org/wikipedia/commons/1/14/The_Widow_%28Boston_Public_Library%29_%28cropped%29.jpg";
- }
- await image.decode();
-
ctx.filter = \`brightness(\${params["Brightness"]}) contrast(\${params["Contrast"]})\`;
ctx.drawImage(image, 0, 0, canvasSize, canvasSize);
ctx.filter = "none";
- if (file != null) {
- URL.revokeObjectURL(image.src);
- }
-
const imageData = ctx.getImageData(0, 0, canvasSize, canvasSize);
const data = imageData.data;
diff --git a/src/lib/presets/Quantum.ts b/src/lib/presets/Quantum.ts
index df8e56c..b72e510 100644
--- a/src/lib/presets/Quantum.ts
+++ b/src/lib/presets/Quantum.ts
@@ -89,7 +89,7 @@ export function renderSVG(qr, params) {
svg += \`\`;
switch (params["Finder pattern"]) {
- case "Atom": {
+ case "Atom":
let r1 = 0.98;
let r2 = 1.5;
@@ -101,11 +101,11 @@ export function renderSVG(qr, params) {
svg += \`M\${x + 3.5},\${y + 3.5 - 3 * r2}a\${r1},\${r2} 0,0,1 0,\${6 * r2}a\${r1},\${r2} 0,0,1 0,\${-6 * r2}\`;
break;
- }
- case "Planet": {
+
+ case "Planet":
svg += \`\`;
}