2024-09-13 07:52:47 +00:00
|
|
|
import { Module } from "REPLACE_URL/utils.js";
|
|
|
|
|
2024-08-28 07:17:55 +00:00
|
|
|
export const paramsSchema = {
|
|
|
|
Margin: {
|
|
|
|
type: "number",
|
|
|
|
min: 0,
|
|
|
|
max: 20,
|
|
|
|
default: 10,
|
|
|
|
},
|
|
|
|
"Inner square": {
|
|
|
|
type: "number",
|
|
|
|
min: 0,
|
|
|
|
max: 10,
|
|
|
|
default: 2,
|
|
|
|
},
|
|
|
|
"Outer square": {
|
|
|
|
type: "number",
|
|
|
|
min: 0,
|
|
|
|
max: 10,
|
|
|
|
default: 6,
|
|
|
|
},
|
|
|
|
Foreground: {
|
2024-09-01 00:21:10 +00:00
|
|
|
type: "color",
|
2024-08-28 07:17:55 +00:00
|
|
|
default: "#000000",
|
|
|
|
},
|
|
|
|
Background: {
|
2024-09-01 00:21:10 +00:00
|
|
|
type: "color",
|
2024-08-28 07:17:55 +00:00
|
|
|
default: "#ffffff",
|
|
|
|
},
|
|
|
|
Grout: {
|
2024-09-01 00:21:10 +00:00
|
|
|
type: "color",
|
2024-08-28 07:17:55 +00:00
|
|
|
default: "#b3b8fd",
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
export function renderSVG(qr, params) {
|
|
|
|
const unit = 16;
|
|
|
|
const gap = 2;
|
|
|
|
const offset = gap / 2;
|
|
|
|
|
|
|
|
const margin = params["Margin"];
|
|
|
|
const qrWidth = qr.version * 4 + 17;
|
|
|
|
const matrixWidth = qrWidth + 2 * margin;
|
|
|
|
|
|
|
|
const fg = params["Foreground"];
|
|
|
|
const bg = params["Background"];
|
|
|
|
const grout = params["Grout"];
|
|
|
|
|
2024-09-13 07:52:47 +00:00
|
|
|
const newMatrix = Array.from({ length: matrixWidth * matrixWidth }).fill(0);
|
2024-08-28 07:17:55 +00:00
|
|
|
|
|
|
|
const start = margin;
|
|
|
|
const end = matrixWidth - 1 - margin;
|
|
|
|
const inner = params["Inner square"];
|
|
|
|
const outer = params["Outer square"];
|
|
|
|
for (let y = 0; y < matrixWidth; y++) {
|
|
|
|
for (let x = 0; x < matrixWidth; x++) {
|
|
|
|
// outer square
|
|
|
|
if (y === start - outer && x >= start - outer && x <= end + outer) {
|
2024-09-13 07:52:47 +00:00
|
|
|
newMatrix[y * matrixWidth + x] = Module.ON;
|
2024-08-28 07:17:55 +00:00
|
|
|
} else if (
|
|
|
|
(x === start - outer || x === end + outer) &&
|
|
|
|
y >= start - outer + 1 &&
|
|
|
|
y <= end + outer - 1
|
|
|
|
) {
|
2024-09-13 07:52:47 +00:00
|
|
|
newMatrix[y * matrixWidth + x] = Module.ON;
|
|
|
|
newMatrix[y * matrixWidth + x] = Module.ON;
|
2024-08-28 07:17:55 +00:00
|
|
|
} else if (y === end + outer && x >= start - outer && x <= end + outer) {
|
2024-09-13 07:52:47 +00:00
|
|
|
newMatrix[y * matrixWidth + x] = Module.ON;
|
2024-08-28 07:17:55 +00:00
|
|
|
}
|
|
|
|
// inner square
|
|
|
|
else if (y === start - inner && x >= start - inner && x <= end + inner) {
|
2024-09-13 07:52:47 +00:00
|
|
|
newMatrix[y * matrixWidth + x] = Module.ON;
|
2024-08-28 07:17:55 +00:00
|
|
|
} else if (
|
|
|
|
(x === start - inner || x === end + inner) &&
|
|
|
|
y >= start - inner + 1 &&
|
|
|
|
y <= end + inner - 1
|
|
|
|
) {
|
2024-09-13 07:52:47 +00:00
|
|
|
newMatrix[y * matrixWidth + x] = Module.ON;
|
|
|
|
newMatrix[y * matrixWidth + x] = Module.ON;
|
2024-08-28 07:17:55 +00:00
|
|
|
} else if (y === end + inner && x >= start - inner && x <= end + inner) {
|
2024-09-13 07:52:47 +00:00
|
|
|
newMatrix[y * matrixWidth + x] = Module.ON;
|
2024-08-28 07:17:55 +00:00
|
|
|
}
|
|
|
|
// qr code w/ quiet zone
|
|
|
|
else if (
|
|
|
|
y >= margin - inner &&
|
|
|
|
y < matrixWidth - margin + inner &&
|
|
|
|
x >= margin - inner &&
|
|
|
|
x < matrixWidth - margin + inner
|
|
|
|
) {
|
|
|
|
if (
|
|
|
|
y >= margin &&
|
|
|
|
y < matrixWidth - margin &&
|
|
|
|
x >= margin &&
|
|
|
|
x < matrixWidth - margin
|
|
|
|
) {
|
|
|
|
newMatrix[y * matrixWidth + x] =
|
|
|
|
qr.matrix[(y - margin) * qrWidth + x - margin];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// between squares
|
|
|
|
else if (
|
|
|
|
y > start - outer &&
|
|
|
|
y < end + outer &&
|
|
|
|
x > start - outer &&
|
|
|
|
x < end + outer
|
|
|
|
) {
|
|
|
|
if ((x + y) & 1) {
|
2024-09-13 07:52:47 +00:00
|
|
|
newMatrix[y * matrixWidth + x] = Module.ON;
|
2024-08-28 07:17:55 +00:00
|
|
|
}
|
|
|
|
// outside squares
|
|
|
|
} else {
|
|
|
|
if (x % 4 && y % 4) {
|
|
|
|
if ((x % 8 < 4 && y % 8 < 4) || (x % 8 > 4 && y % 8 > 4)) {
|
2024-09-13 07:52:47 +00:00
|
|
|
newMatrix[y * matrixWidth + x] = Module.ON;
|
2024-08-28 07:17:55 +00:00
|
|
|
}
|
|
|
|
} else {
|
2024-09-13 07:52:47 +00:00
|
|
|
newMatrix[y * matrixWidth + x] = Module.ON;
|
2024-08-28 07:17:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const size = matrixWidth * unit;
|
|
|
|
let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${size} ${size}">`;
|
|
|
|
svg += `<rect width="${size}" height="${size}" fill="${grout}"/>`;
|
|
|
|
svg += `<path fill="${fg}" d="`;
|
|
|
|
let layer = `<path fill="${bg}" d="`;
|
|
|
|
|
|
|
|
for (let y = 0; y < matrixWidth; y++) {
|
|
|
|
for (let x = 0; x < matrixWidth; x++) {
|
|
|
|
const module = newMatrix[y * matrixWidth + x];
|
|
|
|
let tiles;
|
2024-09-13 07:52:47 +00:00
|
|
|
if (module & Module.ON) {
|
|
|
|
if (module & Module.FINDER) {
|
2024-08-28 07:17:55 +00:00
|
|
|
svg += `M${x * unit},${y * unit}h${unit}v${unit}h-${unit}z`;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
tiles = 1;
|
|
|
|
} else {
|
|
|
|
tiles = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
const tile = (unit - tiles * gap) / tiles;
|
|
|
|
for (let dy = 0; dy < tiles; dy++) {
|
|
|
|
const ny = y * unit + offset + dy * (tile + gap);
|
|
|
|
for (let dx = 0; dx < tiles; dx++) {
|
|
|
|
const nx = x * unit + offset + dx * (tile + gap);
|
2024-09-13 07:52:47 +00:00
|
|
|
if (module & Module.ON) {
|
2024-08-28 07:17:55 +00:00
|
|
|
svg += `M${nx},${ny}h${tile}v${tile}h-${tile}z`;
|
|
|
|
} else {
|
|
|
|
layer += `M${nx},${ny}h${tile}v${tile}h-${tile}z`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
svg += `"/>`;
|
|
|
|
svg += layer + `"/>`;
|
|
|
|
svg += `</svg>`;
|
|
|
|
|
|
|
|
return svg;
|
|
|
|
}
|