real preset type stripper

main
Kyle Zheng 2024-08-13 02:44:46 -04:00
rodzic 1d235f017b
commit 9228459cbb
17 zmienionych plików z 1049 dodań i 456 usunięć

Wyświetl plik

@ -28,7 +28,10 @@
"vinxi": "^0.3.11"
},
"devDependencies": {
"@swc/cli": "^0.4.0",
"@swc/core": "^1.7.10",
"@unocss/transformer-variant-group": "^0.59.4",
"prettier": "^3.3.3",
"vite-plugin-wasm-pack": "^0.1.12"
},
"pnpm": {

Plik diff jest za duży Load Diff

Wyświetl plik

@ -115,12 +115,8 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
dotsLayer += `<circle cx="${x + 3.5}" cy="${y + 6.5}" r="0.5"/>`;
dotsLayer += `<circle cx="${x + 6.5}" cy="${y + 6.5}" r="0.5"/>`;
linesLayer += `<line x1="${x + 0.5}" y1="${y + 0.5}" x2="${x + 6.5}" y2="${
y + 6.5
}" stroke-width="${range(0.3, 0.6)}"/>`;
linesLayer += `<line x1="${x + 6.5}" y1="${y + 0.5}" x2="${x + 0.5}" y2="${
y + 6.5
}" stroke-width="${range(0.3, 0.6)}"/>`;
linesLayer += `<line x1="${x + 0.5}" y1="${y + 0.5}" x2="${x + 6.5}" y2="${y + 6.5}" stroke-width="${range(0.3, 0.6)}"/>`;
linesLayer += `<line x1="${x + 6.5}" y1="${y + 0.5}" x2="${x + 0.5}" y2="${y + 6.5}" stroke-width="${range(0.3, 0.6)}"/>`;
}
for (let y = 0; y < matrixWidth; y++) {
@ -129,10 +125,7 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
if ((module | 1) === Module.FinderON) continue;
if (!(module & 1)) continue;
dotsLayer += `<circle cx="${x + 0.5}" cy="${y + 0.5}" r="${range(
0.2,
0.4
)}"/>`;
dotsLayer += `<circle cx="${x + 0.5}" cy="${y + 0.5}" r="${range(0.2, 0.4)}"/>`;
if (!visited1(x, y)) {
let nx = x + 1;
@ -148,9 +141,7 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
ny++;
}
if (ny - y > 1) {
linesLayer += `<line x1="${x + 0.5}" y1="${y + 0.5}" x2="${
nx - 0.5
}" y2="${ny - 0.5}" stroke-width="${range(0.1, 0.3)}"/>`;
linesLayer += `<line x1="${x + 0.5}" y1="${y + 0.5}" x2="${nx - 0.5}" y2="${ny - 0.5}" stroke-width="${range(0.1, 0.3)}"/>`;
}
}
@ -168,9 +159,7 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
ny++;
}
if (ny - y > 1) {
linesLayer += `<line x1="${x + 0.5}" y1="${y + 0.5}" x2="${
nx + 1.5
}" y2="${ny - 0.5}" stroke-width="${range(0.1, 0.3)}"/>`;
linesLayer += `<line x1="${x + 0.5}" y1="${y + 0.5}" x2="${nx + 1.5}" y2="${ny - 0.5}" stroke-width="${range(0.1, 0.3)}"/>`;
}
}
}

Wyświetl plik

@ -112,16 +112,10 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
[0, matrixWidth - 7],
]) {
svg += `<rect x="${x + 2}" y="${y}" width="3" height="1" fill="${fc}"/>`;
svg += `<rect x="${x + 2}" y="${
y + 2
}" width="3" height="3" fill="${fc}"/>`;
svg += `<rect x="${x + 2}" y="${y + 2}" width="3" height="3" fill="${fc}"/>`;
svg += `<rect x="${x}" y="${y + 2}" width="1" height="3" fill="${fc}"/>`;
svg += `<rect x="${x + 6}" y="${
y + 2
}" width="1" height="3" fill="${fc}"/>`;
svg += `<rect x="${x + 2}" y="${
y + 6
}" width="3" height="1" fill="${fc}"/>`;
svg += `<rect x="${x + 6}" y="${y + 2}" width="1" height="3" fill="${fc}"/>`;
svg += `<rect x="${x + 2}" y="${y + 6}" width="3" height="1" fill="${fc}"/>`;
}
for (let y = 0; y < matrixWidth; y++) {
@ -148,12 +142,8 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
!visited(x + 2, y + 1)
) {
topLayer += `<g stroke-width="${ct}" stroke="${cc}">`;
topLayer += `<line x1="${x + co}" y1="${y + co}" x2="${
x + 3 - co
}" y2="${y + 3 - co}"/>`;
topLayer += `<line x1="${x + 3 - co}" y1="${y + co}" x2="${
x + co
}" y2="${y + 3 - co}"/>`;
topLayer += `<line x1="${x + co}" y1="${y + co}" x2="${x + 3 - co}" y2="${y + 3 - co}"/>`;
topLayer += `<line x1="${x + 3 - co}" y1="${y + co}" x2="${x + co}" y2="${y + 3 - co}"/>`;
topLayer += `</g>`;
setVisited(x + 2, y);
@ -170,12 +160,8 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
) {
if (!visited(x + 1, y) && !visited(x + 1, y + 1)) {
topLayer += `<g stroke-width="${ct}" stroke="${cc}">`;
topLayer += `<line x1="${x + co}" y1="${y + co}" x2="${
x + 2 - co
}" y2="${y + 2 - co}"/>`;
topLayer += `<line x1="${x + 2 - co}" y1="${y + co}" x2="${
x + co
}" y2="${y + 2 - co}"/>`;
topLayer += `<line x1="${x + co}" y1="${y + co}" x2="${x + 2 - co}" y2="${y + 2 - co}"/>`;
topLayer += `<line x1="${x + 2 - co}" y1="${y + co}" x2="${x + co}" y2="${y + 2 - co}"/>`;
topLayer += `</g>`;
setVisited(x + 1, y);
@ -190,12 +176,8 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
ny++;
}
if (ny - y > 2) {
svg += `<rect x="${x + vo}" y="${y + vo}" width="${vt}" height="${
ny - y - 1 - 2 * vo
}" fill="${vc}"/>`;
svg += `<rect x="${x + vo}" y="${ny - 1 + vo}" width="${vt}" height="${
1 - 2 * vo
}" fill="${vc}"/>`;
svg += `<rect x="${x + vo}" y="${y + vo}" width="${vt}" height="${ny - y - 1 - 2 * vo}" fill="${vc}"/>`;
svg += `<rect x="${x + vo}" y="${ny - 1 + vo}" width="${vt}" height="${1 - 2 * vo}" fill="${vc}"/>`;
for (let i = y + 1; i < ny; i++) {
setVisited(x, i);
}
@ -207,9 +189,7 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
setVisited(nx, y);
nx++;
}
svg += `<rect x="${x + ho}" y="${y + ho}" width="${
nx - x - 2 * ho
}" height="${ht}" fill="${hc}"/>`;
svg += `<rect x="${x + ho}" y="${y + ho}" width="${nx - x - 2 * ho}" height="${ht}" fill="${hc}"/>`;
}
}

Wyświetl plik

@ -88,9 +88,7 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
const bg = params["Background"];
const size = matrixWidth + 2 * margin;
let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${-margin} ${-margin} ${size} ${size}" fill="${
params["Tiny circle"]
}">`;
let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${-margin} ${-margin} ${size} ${size}" fill="${params["Tiny circle"]}">`;
svg += `<rect x="${-margin}" y="${-margin}" width="${size}" height="${size}" fill="${bg}"/>`;
let botLayer = `<g fill="none" stroke="${params["Large circle"]}" stroke-width="0.6">`;
@ -115,9 +113,7 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
[matrixWidth - 7, 0],
[0, matrixWidth - 7],
]) {
svg += `<circle cx="${x + 3.5}" cy="${
y + 3.5
}" r="3" fill="none" stroke="${fc}" stroke-width="1"/>`;
svg += `<circle cx="${x + 3.5}" cy="${y + 3.5}" r="3" fill="none" stroke="${fc}" stroke-width="1"/>`;
svg += `<circle cx="${x + 3.5}" cy="${y + 3.5}" r="1.5" fill="${fc}"/>`;
}
@ -140,10 +136,7 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
!visited(x + 1, y + 1) &&
!visited(x + 2, y + 1)
) {
botLayer += `<circle cx="${x + 1.5}" cy="${y + 1.5}" r="${range(
0.8,
1.2
)}"/>`;
botLayer += `<circle cx="${x + 1.5}" cy="${y + 1.5}" r="${range(0.8, 1.2)}"/>`;
setVisited(x + 1, y);
setVisited(x, y + 1);
@ -161,28 +154,19 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
!visited(x + 1, y) &&
!visited(x + 1, y + 1)
) {
midLayer += `<circle cx="${x + 1}" cy="${y + 1}" r="${range(
0.4,
0.6
)}"/>`;
midLayer += `<circle cx="${x + 1}" cy="${y + 1}" r="${range(0.4, 0.6)}"/>`;
setVisited(x + 1, y);
setVisited(x, y + 1);
setVisited(x + 1, y + 1);
continue;
}
if (x < matrixWidth - 1 && matrix(x + 1, y) & 1 && !visited(x + 1, y)) {
topLayer += `<circle cx="${x + 1}" cy="${y + 0.5}" r="${range(
0.4,
0.6
)}"/>`;
topLayer += `<circle cx="${x + 1}" cy="${y + 0.5}" r="${range(0.4, 0.6)}"/>`;
setVisited(x + 1, y);
continue;
}
if (y < matrixWidth - 1 && matrix(x, y + 1) & 1 && !visited(x, y + 1)) {
topLayer += `<circle cx="${x + 0.5}" cy="${y + 1}" r="${range(
0.3,
0.5
)}"/>`;
topLayer += `<circle cx="${x + 0.5}" cy="${y + 1}" r="${range(0.3, 0.5)}"/>`;
setVisited(x, y + 1);
continue;
}

Wyświetl plik

@ -65,9 +65,6 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
const fg = params["Foreground"];
const bg = params["Background"];
const moduleSize = 3;
const lineSize = 1;
const qrWidth = qr.version * 4 + 17;
const matrixWidth = qrWidth + 2 * margin;
@ -101,11 +98,6 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
}
let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${matrixWidth} ${matrixWidth}">`;
svg += `<filter id="shadow">
<feDropShadow dx="0" dy="0" stdDeviation="0.5" flood-color="cyan" />
</filter>`
svg += `<rect width="${matrixWidth}" height="${matrixWidth}" fill="${bg}"/>`;
const xMax = matrixWidth - 1;
@ -124,7 +116,7 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
visited[y * matrixWidth + x] = shape;
while (x < xMax) {
const right = on(x + 1, y);
const vertRight = y > 0 && on(x + 1, y - 1)
const vertRight = y > 0 && on(x + 1, y - 1);
if (!right || vertRight) {
vert = right && vertRight;
break;
@ -134,11 +126,11 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
}
paths[shape] += `h${x - sx}`;
if (vert) {
paths[shape] += `a.5.5 0,0,0 .5-.5`
goUp(x + 1, y - 1, shape)
paths[shape] += `a.5.5 0,0,0 .5-.5`;
goUp(x + 1, y - 1, shape);
} else {
paths[shape] += `a.5.5 0,0,1 .5.5`
goDown(x, y, shape)
paths[shape] += `a.5.5 0,0,1 .5.5`;
goDown(x, y, shape);
}
}
@ -147,8 +139,8 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
let vert = false;
visited[y * matrixWidth + x] = shape;
while (x > 0) {
const left = on(x - 1, y)
const vertLeft = y < yMax && on(x - 1, y + 1)
const left = on(x - 1, y);
const vertLeft = y < yMax && on(x - 1, y + 1);
if (!left || vertLeft) {
vert = left && vertLeft;
break;
@ -157,17 +149,17 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
visited[y * matrixWidth + x] = shape;
}
if (shape !== paths.length - 1 && x === baseX && y === baseY) {
paths[shape] += "z"
paths[shape] += "z";
return;
}
paths[shape] += `h${x - sx}`;
if (vert) {
paths[shape] += `a.5.5 0,0,0 -.5.5`
goDown(x - 1, y + 1, shape)
paths[shape] += `a.5.5 0,0,0 -.5.5`;
goDown(x - 1, y + 1, shape);
} else {
paths[shape] += `a.5.5 0,0,1 -.5-.5`
goUp(x, y, shape)
paths[shape] += `a.5.5 0,0,1 -.5-.5`;
goUp(x, y, shape);
}
}
@ -177,7 +169,7 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
visited[y * matrixWidth + x] = shape;
while (y > 0) {
const up = on(x, y - 1);
const horzUp = x > 0 && on(x - 1, y - 1)
const horzUp = x > 0 && on(x - 1, y - 1);
if (!up || horzUp) {
horz = up && horzUp;
break;
@ -187,16 +179,16 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
}
if (shape === paths.length - 1 && x === baseX && y === baseY) {
paths[shape] += "z"
paths[shape] += "z";
return;
}
paths[shape] += `v${y - sy}`
paths[shape] += `v${y - sy}`;
if (horz) {
paths[shape] += `a.5.5 0,0,0 -.5-.5`
goLeft(x - 1, y - 1, shape)
paths[shape] += `a.5.5 0,0,0 -.5-.5`;
goLeft(x - 1, y - 1, shape);
} else {
paths[shape] += `a.5.5 0,0,1 .5-.5`
goRight(x, y, shape)
paths[shape] += `a.5.5 0,0,1 .5-.5`;
goRight(x, y, shape);
}
}
@ -206,7 +198,7 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
visited[y * matrixWidth + x] = shape;
while (y < yMax) {
const down = on(x, y + 1);
const horzDown = x < xMax && on(x + 1, y + 1)
const horzDown = x < xMax && on(x + 1, y + 1);
if (!down || horzDown) {
horz = down && horzDown;
break;
@ -214,26 +206,26 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
y++;
visited[y * matrixWidth + x] = shape;
}
paths[shape] += `v${y - sy}`
paths[shape] += `v${y - sy}`;
if (horz) {
paths[shape] += `a.5.5 0,0,0 .5.5`
goRight(x + 1, y + 1, shape)
paths[shape] += `a.5.5 0,0,0 .5.5`;
goRight(x + 1, y + 1, shape);
} else {
paths[shape] += `a.5.5 0,0,1 -.5.5`
goLeft(x, y, shape)
paths[shape] += `a.5.5 0,0,1 -.5.5`;
goLeft(x, y, shape);
}
}
const stack: [number, number][] = []
const stack: [number, number][] = [];
for (let x = 0; x < matrixWidth; x++) {
if (!on(x, 0)) stack.push([x, 0])
if (!on(x, 0)) stack.push([x, 0]);
}
for (let y = 1; y < yMax; y++) {
if (!on(0, y)) stack.push([0, y])
if (!on(xMax, y)) stack.push([xMax, y])
if (!on(0, y)) stack.push([0, y]);
if (!on(xMax, y)) stack.push([xMax, y]);
}
for (let x = 0; x < matrixWidth; x++) {
if (!on(x, yMax)) stack.push([x, yMax])
if (!on(x, yMax)) stack.push([x, yMax]);
}
// recursion dfs limited to ~4000
@ -255,52 +247,51 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
}
}
}
dfsOff()
dfsOff();
const paths = [""]
const paths = [""];
for (let y = 0; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
if (visited[y * matrixWidth + x]) continue;
if (!on(x, y)) {
const shape = visited[y * matrixWidth + x - 1]
paths[shape] += `M${x + 0.5},${y}a.5.5 0,0,0 -.5.5`
const shape = visited[y * matrixWidth + x - 1];
paths[shape] += `M${x + 0.5},${y}a.5.5 0,0,0 -.5.5`;
// these indexes are correct, think about it
baseY = y - 1;
baseX = x;
goDown(x - 1, y, shape)
stack.push([x, y])
dfsOff()
goDown(x - 1, y, shape);
stack.push([x, y]);
dfsOff();
continue;
};
}
if (y > 0 && on(x, y - 1) && visited[(y - 1) * matrixWidth + x]) {
visited[y * matrixWidth + x] = visited[(y - 1) * matrixWidth + x];
continue;
};
}
if (x > 0 && on(x - 1, y) && visited[y * matrixWidth + x - 1]) {
visited[y * matrixWidth + x] = visited[y * matrixWidth + x - 1];
continue;
};
}
paths.push(`<path fill="${fg}" d="M${x},${y+0.5}a.5.5 0,0,1 .5-.5`)
paths.push(`<path fill="${fg}" d="M${x},${y + 0.5}a.5.5 0,0,1 .5-.5`);
baseY = y;
baseX = x
baseX = x;
goRight(x, y, paths.length - 1);
}
}
paths.forEach((path, i) => {
if (i === 0) return
if (i === 0) return;
svg += path;
svg += `"/>`
})
svg += `"/>`;
});
svg += `</svg>`;
return svg;
}

Wyświetl plik

@ -92,9 +92,7 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
[matrixWidth - 7, 0],
[0, matrixWidth - 7],
]) {
svg += `<circle cx="${x + 3.5}" cy="${
y + 3.5
}" r="3" fill="none" stroke="${fg}" stroke-width="1"/>`;
svg += `<circle cx="${x + 3.5}" cy="${y + 3.5}" r="3" fill="none" stroke="${fg}" stroke-width="1"/>`;
svg += `<circle cx="${x + 3.5}" cy="${y + 3.5}" r="1.5" fill="${fg}"/>`;
}
}
@ -168,9 +166,7 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
const radius = Math.trunc(100 * 0.5 * ratio) / 100;
svg += `M${x + 0.5},${y + 0.5 - radius}a${radius},${radius} 0,0,0 0,${
2 * radius
}a${radius},${radius} 0,0,0 0,${-2 * radius}`;
svg += `M${x + 0.5},${y + 0.5 - radius}a${radius},${radius} 0,0,0 0,${2 * radius}a${radius},${radius} 0,0,0 0,${-2 * radius}`;
}
}
svg += `"/></svg>`;

Wyświetl plik

@ -66,8 +66,8 @@ export async function renderCanvas(
params: Params<typeof paramsSchema>,
ctx: CanvasRenderingContext2D
) {
const moduleSize = 3;
const pixelSize = 1;
const unit = 3;
const pixel = 1;
const matrixWidth = qr.version * 4 + 17;
const margin = params["Margin"];
@ -78,7 +78,7 @@ export async function renderCanvas(
const file = params["Image"];
const pixelWidth = matrixWidth + 2 * margin;
const canvasSize = pixelWidth * moduleSize;
const canvasSize = pixelWidth * unit;
ctx.canvas.width = canvasSize;
ctx.canvas.height = canvasSize;
@ -93,10 +93,10 @@ export async function renderCanvas(
const px = x + margin;
const py = y + margin;
ctx.fillRect(
px * moduleSize,
py * moduleSize,
moduleSize,
moduleSize
px * unit,
py * unit,
unit,
unit
);
}
}
@ -144,7 +144,7 @@ export async function renderCanvas(
newPixel = 255;
ctx.fillStyle = bg;
}
ctx.fillRect(x * pixelSize, y * pixelSize, pixelSize, pixelSize);
ctx.fillRect(x * pixel, y * pixel, pixel, pixel);
data[i] = data[i + 1] = data[i + 2] = newPixel;
const error = oldPixel - newPixel;
@ -165,7 +165,7 @@ export async function renderCanvas(
}
}
const dataOffset = (moduleSize - pixelSize) / 2;
const dataOffset = (unit - pixel) / 2;
for (let y = 0; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
@ -185,13 +185,13 @@ export async function renderCanvas(
(alignment && type === Module.AlignmentON) ||
(timing && type === Module.TimingON)
) {
ctx.fillRect(px * moduleSize, py * moduleSize, moduleSize, moduleSize);
ctx.fillRect(px * unit, py * unit, unit, unit);
} else {
ctx.fillRect(
px * moduleSize + dataOffset,
py * moduleSize + dataOffset,
pixelSize,
pixelSize
px * unit + dataOffset,
py * unit + dataOffset,
pixel,
pixel
);
}
}

Wyświetl plik

@ -37,14 +37,14 @@ const Module = {
export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
const matrixWidth = qr.version * 4 + 17;
const moduleSize = 10;
const unit = 10;
const dataSize = params["Data pixel size"];
const margin = params["Margin"] * moduleSize;
const margin = params["Margin"] * unit;
const fg = "#000";
const bg = "#fff";
const size = matrixWidth * moduleSize + 2 * margin;
const size = matrixWidth * unit + 2 * margin;
let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${-margin} ${-margin} ${size} ${size}">`;
if (params["Background"]) {
svg += `<rect x="${-margin}" y="${-margin}" width="${size}" height="${size}" fill="${bg}"/>`;
@ -56,25 +56,15 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
[matrixWidth - 7, 0],
[0, matrixWidth - 7],
]) {
svg += `M${(x + 3) * moduleSize},${
y * moduleSize
}h${moduleSize}v${moduleSize}h-${moduleSize}z`;
svg += `M${x * moduleSize},${
(y + 3) * moduleSize
}h${moduleSize}v${moduleSize}h-${moduleSize}z`;
svg += `M${(x + 6) * moduleSize},${
(y + 3) * moduleSize
}h${moduleSize}v${moduleSize}h-${moduleSize}z`;
svg += `M${(x + 3) * moduleSize},${
(y + 6) * moduleSize
}h${moduleSize}v${moduleSize}h-${moduleSize}z`;
svg += `M${(x + 3) * unit},${y * unit}h${unit}v${unit}h-${unit}z`;
svg += `M${x * unit},${(y + 3) * unit}h${unit}v${unit}h-${unit}z`;
svg += `M${(x + 6) * unit},${(y + 3) * unit}h${unit}v${unit}h-${unit}z`;
svg += `M${(x + 3) * unit},${(y + 6) * unit}h${unit}v${unit}h-${unit}z`;
svg += `M${(x + 2) * moduleSize},${(y + 2) * moduleSize}h${
moduleSize * 3
}v${moduleSize * 3}h-${moduleSize * 3}z`;
svg += `M${(x + 2) * unit},${(y + 2) * unit}h${unit * 3}v${unit * 3}h-${unit * 3}z`;
}
const offset = (moduleSize - dataSize) / 2;
const offset = (unit - dataSize) / 2;
for (let y = 0; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
const module = qr.matrix[y * matrixWidth + x];
@ -84,8 +74,8 @@ export function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
}
if (module & 1) {
const sx = x * moduleSize + offset;
const sy = y * moduleSize + offset;
const sx = x * unit + offset;
const sy = y * unit + offset;
svg += `M${sx},${sy}h${dataSize}v${dataSize}h-${dataSize}z`;
}
}

Wyświetl plik

@ -112,12 +112,8 @@ export function renderSVG(qr, params) {
dotsLayer += \`<circle cx="\${x + 3.5}" cy="\${y + 6.5}" r="0.5"/>\`;
dotsLayer += \`<circle cx="\${x + 6.5}" cy="\${y + 6.5}" r="0.5"/>\`;
linesLayer += \`<line x1="\${x + 0.5}" y1="\${y + 0.5}" x2="\${x + 6.5}" y2="\${
y + 6.5
}" stroke-width="\${range(0.3, 0.6)}"/>\`;
linesLayer += \`<line x1="\${x + 6.5}" y1="\${y + 0.5}" x2="\${x + 0.5}" y2="\${
y + 6.5
}" stroke-width="\${range(0.3, 0.6)}"/>\`;
linesLayer += \`<line x1="\${x + 0.5}" y1="\${y + 0.5}" x2="\${x + 6.5}" y2="\${y + 6.5}" stroke-width="\${range(0.3, 0.6)}"/>\`;
linesLayer += \`<line x1="\${x + 6.5}" y1="\${y + 0.5}" x2="\${x + 0.5}" y2="\${y + 6.5}" stroke-width="\${range(0.3, 0.6)}"/>\`;
}
for (let y = 0; y < matrixWidth; y++) {
@ -126,10 +122,7 @@ export function renderSVG(qr, params) {
if ((module | 1) === Module.FinderON) continue;
if (!(module & 1)) continue;
dotsLayer += \`<circle cx="\${x + 0.5}" cy="\${y + 0.5}" r="\${range(
0.2,
0.4
)}"/>\`;
dotsLayer += \`<circle cx="\${x + 0.5}" cy="\${y + 0.5}" r="\${range(0.2, 0.4)}"/>\`;
if (!visited1(x, y)) {
let nx = x + 1;
@ -145,9 +138,7 @@ export function renderSVG(qr, params) {
ny++;
}
if (ny - y > 1) {
linesLayer += \`<line x1="\${x + 0.5}" y1="\${y + 0.5}" x2="\${
nx - 0.5
}" y2="\${ny - 0.5}" stroke-width="\${range(0.1, 0.3)}"/>\`;
linesLayer += \`<line x1="\${x + 0.5}" y1="\${y + 0.5}" x2="\${nx - 0.5}" y2="\${ny - 0.5}" stroke-width="\${range(0.1, 0.3)}"/>\`;
}
}
@ -165,9 +156,7 @@ export function renderSVG(qr, params) {
ny++;
}
if (ny - y > 1) {
linesLayer += \`<line x1="\${x + 0.5}" y1="\${y + 0.5}" x2="\${
nx + 1.5
}" y2="\${ny - 0.5}" stroke-width="\${range(0.1, 0.3)}"/>\`;
linesLayer += \`<line x1="\${x + 0.5}" y1="\${y + 0.5}" x2="\${nx + 1.5}" y2="\${ny - 0.5}" stroke-width="\${range(0.1, 0.3)}"/>\`;
}
}
}

Wyświetl plik

@ -109,16 +109,10 @@ export function renderSVG(qr, params) {
[0, matrixWidth - 7],
]) {
svg += \`<rect x="\${x + 2}" y="\${y}" width="3" height="1" fill="\${fc}"/>\`;
svg += \`<rect x="\${x + 2}" y="\${
y + 2
}" width="3" height="3" fill="\${fc}"/>\`;
svg += \`<rect x="\${x + 2}" y="\${y + 2}" width="3" height="3" fill="\${fc}"/>\`;
svg += \`<rect x="\${x}" y="\${y + 2}" width="1" height="3" fill="\${fc}"/>\`;
svg += \`<rect x="\${x + 6}" y="\${
y + 2
}" width="1" height="3" fill="\${fc}"/>\`;
svg += \`<rect x="\${x + 2}" y="\${
y + 6
}" width="3" height="1" fill="\${fc}"/>\`;
svg += \`<rect x="\${x + 6}" y="\${y + 2}" width="1" height="3" fill="\${fc}"/>\`;
svg += \`<rect x="\${x + 2}" y="\${y + 6}" width="3" height="1" fill="\${fc}"/>\`;
}
for (let y = 0; y < matrixWidth; y++) {
@ -145,12 +139,8 @@ export function renderSVG(qr, params) {
!visited(x + 2, y + 1)
) {
topLayer += \`<g stroke-width="\${ct}" stroke="\${cc}">\`;
topLayer += \`<line x1="\${x + co}" y1="\${y + co}" x2="\${
x + 3 - co
}" y2="\${y + 3 - co}"/>\`;
topLayer += \`<line x1="\${x + 3 - co}" y1="\${y + co}" x2="\${
x + co
}" y2="\${y + 3 - co}"/>\`;
topLayer += \`<line x1="\${x + co}" y1="\${y + co}" x2="\${x + 3 - co}" y2="\${y + 3 - co}"/>\`;
topLayer += \`<line x1="\${x + 3 - co}" y1="\${y + co}" x2="\${x + co}" y2="\${y + 3 - co}"/>\`;
topLayer += \`</g>\`;
setVisited(x + 2, y);
@ -167,12 +157,8 @@ export function renderSVG(qr, params) {
) {
if (!visited(x + 1, y) && !visited(x + 1, y + 1)) {
topLayer += \`<g stroke-width="\${ct}" stroke="\${cc}">\`;
topLayer += \`<line x1="\${x + co}" y1="\${y + co}" x2="\${
x + 2 - co
}" y2="\${y + 2 - co}"/>\`;
topLayer += \`<line x1="\${x + 2 - co}" y1="\${y + co}" x2="\${
x + co
}" y2="\${y + 2 - co}"/>\`;
topLayer += \`<line x1="\${x + co}" y1="\${y + co}" x2="\${x + 2 - co}" y2="\${y + 2 - co}"/>\`;
topLayer += \`<line x1="\${x + 2 - co}" y1="\${y + co}" x2="\${x + co}" y2="\${y + 2 - co}"/>\`;
topLayer += \`</g>\`;
setVisited(x + 1, y);
@ -187,12 +173,8 @@ export function renderSVG(qr, params) {
ny++;
}
if (ny - y > 2) {
svg += \`<rect x="\${x + vo}" y="\${y + vo}" width="\${vt}" height="\${
ny - y - 1 - 2 * vo
}" fill="\${vc}"/>\`;
svg += \`<rect x="\${x + vo}" y="\${ny - 1 + vo}" width="\${vt}" height="\${
1 - 2 * vo
}" fill="\${vc}"/>\`;
svg += \`<rect x="\${x + vo}" y="\${y + vo}" width="\${vt}" height="\${ny - y - 1 - 2 * vo}" fill="\${vc}"/>\`;
svg += \`<rect x="\${x + vo}" y="\${ny - 1 + vo}" width="\${vt}" height="\${1 - 2 * vo}" fill="\${vc}"/>\`;
for (let i = y + 1; i < ny; i++) {
setVisited(x, i);
}
@ -204,9 +186,7 @@ export function renderSVG(qr, params) {
setVisited(nx, y);
nx++;
}
svg += \`<rect x="\${x + ho}" y="\${y + ho}" width="\${
nx - x - 2 * ho
}" height="\${ht}" fill="\${hc}"/>\`;
svg += \`<rect x="\${x + ho}" y="\${y + ho}" width="\${nx - x - 2 * ho}" height="\${ht}" fill="\${hc}"/>\`;
}
}

Wyświetl plik

@ -75,57 +75,51 @@ export function renderSVG(qr, params) {
const rand = splitmix32(params["Seed"]);
const range = params["Randomize circle size"]
? (min, max) =>
Math.trunc(100 * (rand() * (max - min) + min)) / 100
: (min, max) =>
Math.trunc(100 * ((max - min) / 2 + min)) / 100;
? (min, max) => Math.trunc(100 * (rand() * (max - min) + min)) / 100
: (min, max) => Math.trunc(100 * ((max - min) / 2 + min)) / 100;
const matrixWidth = qr.version * 4 + 17;
const margin = params["Margin"];
const bg = params["Background"];
const size = matrixWidth + 2 * margin;
let svg = \`<svg xmlns="http://www.w3.org/2000/svg" viewBox="\${-margin} \${-margin} \${size} \${size}" fill="\${
params["Tiny circle"]
}">\`;
svg += \`<rect x="\${-margin}" y="\${-margin}" width="\${size}" height="\${size}" fill="\${bg}"/>\`;
let svg = \`<svg xmlns="http://www.w3.org/2000/svg" viewBox="\${-margin} \${-margin} \${size} \${size}" fill="\${params["Tiny circle"]}">\`;
svg += \`<rect x="\${-margin}" y="\${-margin}" width="\${size}" height="\${size}" fill="\${bg}"/>\`;
let botLayer = \`<g fill="none" stroke="\${params["Large circle"]}" stroke-width="0.6">\`;
let midLayer = \`<g fill="none" stroke="\${params["Medium circle"]}" stroke-width="0.5">\`;
let topLayer = \`<g fill="none" stroke="\${params["Small circle"]}" stroke-width="0.4">\`;
let topLayer = \`<g fill="none" stroke="\${params["Small circle"]}" stroke-width="0.4">\`;
function matrix(x, y) {
return qr.matrix[y * matrixWidth + x];
}
}
const visitedMatrix = Array(matrixWidth * matrixWidth).fill(false);
function visited(x, y) {
return visitedMatrix[y * matrixWidth + x];
}
function setVisited(x, y) {
visitedMatrix[y * matrixWidth + x] = true;
}
const fc = params["Finder"];
for (const [x, y] of [
[0, 0],
[matrixWidth - 7, 0],
[0, matrixWidth - 7],
]) {
svg += \`<circle cx="\${x + 3.5}" cy="\${
y + 3.5
}" r="3" fill="none" stroke="\${fc}" stroke-width="1"/>\`;
svg += \`<circle cx="\${x + 3.5}" cy="\${y + 3.5}" r="3" fill="none" stroke="\${fc}" stroke-width="1"/>\`;
svg += \`<circle cx="\${x + 3.5}" cy="\${y + 3.5}" r="1.5" fill="\${fc}"/>\`;
}
for (let y = 0; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
const module = matrix(x, y);
if ((module | 1) === Module.FinderON) continue;
if (visited(x, y)) continue;
if (
y < matrixWidth - 2 &&
x < matrixWidth - 2 &&
matrix(x + 1, y) &
matrix(x, y + 1) &
@ -137,65 +131,54 @@ export function renderSVG(qr, params) {
!visited(x + 1, y + 1) &&
!visited(x + 2, y + 1)
) {
botLayer += \`<circle cx="\${x + 1.5}" cy="\${y + 1.5}" r="\${range(
0.8,
1.2
)}"/>\`;
botLayer += \`<circle cx="\${x + 1.5}" cy="\${y + 1.5}" r="\${range(0.8, 1.2)}"/>\`;
setVisited(x + 1, y);
setVisited(x, y + 1);
setVisited(x + 2, y + 1);
setVisited(x + 1, y + 2);
continue;
}
if (!(module & 1)) continue;
setVisited(x, y);
if (
y < matrixWidth - 1 &&
x < matrixWidth - 1 &&
matrix(x + 1, y) & matrix(x, y + 1) & matrix(x + 1, y + 1) & 1 &&
!visited(x + 1, y) &&
!visited(x + 1, y + 1)
) {
midLayer += \`<circle cx="\${x + 1}" cy="\${y + 1}" r="\${range(
0.4,
0.6
)}"/>\`;
midLayer += \`<circle cx="\${x + 1}" cy="\${y + 1}" r="\${range(0.4, 0.6)}"/>\`;
setVisited(x + 1, y);
setVisited(x, y + 1);
setVisited(x + 1, y + 1);
continue;
}
if (x < matrixWidth - 1 && matrix(x + 1, y) & 1 && !visited(x + 1, y)) {
topLayer += \`<circle cx="\${x + 1}" cy="\${y + 0.5}" r="\${range(
0.4,
0.6
)}"/>\`;
topLayer += \`<circle cx="\${x + 1}" cy="\${y + 0.5}" r="\${range(0.4, 0.6)}"/>\`;
setVisited(x + 1, y);
continue;
}
if (y < matrixWidth - 1 && matrix(x, y + 1) & 1 && !visited(x, y + 1)) {
topLayer += \`<circle cx="\${x + 0.5}" cy="\${y + 1}" r="\${range(
0.3,
0.5
)}"/>\`;
topLayer += \`<circle cx="\${x + 0.5}" cy="\${y + 1}" r="\${range(0.3, 0.5)}"/>\`;
setVisited(x, y + 1);
continue;
}
svg += \`<circle cx="\${x + 0.5}" cy="\${y + 0.5}" r="\${range(0.2, 0.4)}"/>\`;
}
}
}
botLayer += \`</g>\`;
svg += botLayer;
midLayer += \`</g>\`;
svg += midLayer;
topLayer += \`</g>\`;
svg += topLayer;
svg += \`</svg>\`;
return svg;
}
`

Wyświetl plik

@ -62,9 +62,6 @@ export function renderSVG(qr, params) {
const fg = params["Foreground"];
const bg = params["Background"];
const moduleSize = 3;
const lineSize = 1;
const qrWidth = qr.version * 4 + 17;
const matrixWidth = qrWidth + 2 * margin;
@ -98,11 +95,6 @@ export function renderSVG(qr, params) {
}
let svg = \`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 \${matrixWidth} \${matrixWidth}">\`;
svg += \`<filter id="shadow">
<feDropShadow dx="0" dy="0" stdDeviation="0.5" flood-color="cyan" />
</filter>\`
svg += \`<rect width="\${matrixWidth}" height="\${matrixWidth}" fill="\${bg}"/>\`;
const xMax = matrixWidth - 1;
@ -121,7 +113,7 @@ export function renderSVG(qr, params) {
visited[y * matrixWidth + x] = shape;
while (x < xMax) {
const right = on(x + 1, y);
const vertRight = y > 0 && on(x + 1, y - 1)
const vertRight = y > 0 && on(x + 1, y - 1);
if (!right || vertRight) {
vert = right && vertRight;
break;
@ -131,11 +123,11 @@ export function renderSVG(qr, params) {
}
paths[shape] += \`h\${x - sx}\`;
if (vert) {
paths[shape] += \`a.5.5 0,0,0 .5-.5\`
goUp(x + 1, y - 1, shape)
paths[shape] += \`a.5.5 0,0,0 .5-.5\`;
goUp(x + 1, y - 1, shape);
} else {
paths[shape] += \`a.5.5 0,0,1 .5.5\`
goDown(x, y, shape)
paths[shape] += \`a.5.5 0,0,1 .5.5\`;
goDown(x, y, shape);
}
}
@ -144,8 +136,8 @@ export function renderSVG(qr, params) {
let vert = false;
visited[y * matrixWidth + x] = shape;
while (x > 0) {
const left = on(x - 1, y)
const vertLeft = y < yMax && on(x - 1, y + 1)
const left = on(x - 1, y);
const vertLeft = y < yMax && on(x - 1, y + 1);
if (!left || vertLeft) {
vert = left && vertLeft;
break;
@ -154,17 +146,17 @@ export function renderSVG(qr, params) {
visited[y * matrixWidth + x] = shape;
}
if (shape !== paths.length - 1 && x === baseX && y === baseY) {
paths[shape] += "z"
paths[shape] += "z";
return;
}
paths[shape] += \`h\${x - sx}\`;
if (vert) {
paths[shape] += \`a.5.5 0,0,0 -.5.5\`
goDown(x - 1, y + 1, shape)
paths[shape] += \`a.5.5 0,0,0 -.5.5\`;
goDown(x - 1, y + 1, shape);
} else {
paths[shape] += \`a.5.5 0,0,1 -.5-.5\`
goUp(x, y, shape)
paths[shape] += \`a.5.5 0,0,1 -.5-.5\`;
goUp(x, y, shape);
}
}
@ -174,7 +166,7 @@ export function renderSVG(qr, params) {
visited[y * matrixWidth + x] = shape;
while (y > 0) {
const up = on(x, y - 1);
const horzUp = x > 0 && on(x - 1, y - 1)
const horzUp = x > 0 && on(x - 1, y - 1);
if (!up || horzUp) {
horz = up && horzUp;
break;
@ -184,16 +176,16 @@ export function renderSVG(qr, params) {
}
if (shape === paths.length - 1 && x === baseX && y === baseY) {
paths[shape] += "z"
paths[shape] += "z";
return;
}
paths[shape] += \`v\${y - sy}\`
paths[shape] += \`v\${y - sy}\`;
if (horz) {
paths[shape] += \`a.5.5 0,0,0 -.5-.5\`
goLeft(x - 1, y - 1, shape)
paths[shape] += \`a.5.5 0,0,0 -.5-.5\`;
goLeft(x - 1, y - 1, shape);
} else {
paths[shape] += \`a.5.5 0,0,1 .5-.5\`
goRight(x, y, shape)
paths[shape] += \`a.5.5 0,0,1 .5-.5\`;
goRight(x, y, shape);
}
}
@ -203,7 +195,7 @@ export function renderSVG(qr, params) {
visited[y * matrixWidth + x] = shape;
while (y < yMax) {
const down = on(x, y + 1);
const horzDown = x < xMax && on(x + 1, y + 1)
const horzDown = x < xMax && on(x + 1, y + 1);
if (!down || horzDown) {
horz = down && horzDown;
break;
@ -211,26 +203,26 @@ export function renderSVG(qr, params) {
y++;
visited[y * matrixWidth + x] = shape;
}
paths[shape] += \`v\${y - sy}\`
paths[shape] += \`v\${y - sy}\`;
if (horz) {
paths[shape] += \`a.5.5 0,0,0 .5.5\`
goRight(x + 1, y + 1, shape)
paths[shape] += \`a.5.5 0,0,0 .5.5\`;
goRight(x + 1, y + 1, shape);
} else {
paths[shape] += \`a.5.5 0,0,1 -.5.5\`
goLeft(x, y, shape)
paths[shape] += \`a.5.5 0,0,1 -.5.5\`;
goLeft(x, y, shape);
}
}
const stack = []
const stack = [];
for (let x = 0; x < matrixWidth; x++) {
if (!on(x, 0)) stack.push([x, 0])
if (!on(x, 0)) stack.push([x, 0]);
}
for (let y = 1; y < yMax; y++) {
if (!on(0, y)) stack.push([0, y])
if (!on(xMax, y)) stack.push([xMax, y])
if (!on(0, y)) stack.push([0, y]);
if (!on(xMax, y)) stack.push([xMax, y]);
}
for (let x = 0; x < matrixWidth; x++) {
if (!on(x, yMax)) stack.push([x, yMax])
if (!on(x, yMax)) stack.push([x, yMax]);
}
// recursion dfs limited to ~4000
@ -252,53 +244,52 @@ export function renderSVG(qr, params) {
}
}
}
dfsOff()
dfsOff();
const paths = [""]
const paths = [""];
for (let y = 0; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
if (visited[y * matrixWidth + x]) continue;
if (!on(x, y)) {
const shape = visited[y * matrixWidth + x - 1]
paths[shape] += \`M\${x + 0.5},\${y}a.5.5 0,0,0 -.5.5\`
const shape = visited[y * matrixWidth + x - 1];
paths[shape] += \`M\${x + 0.5},\${y}a.5.5 0,0,0 -.5.5\`;
// these indexes are correct, think about it
baseY = y - 1;
baseX = x;
goDown(x - 1, y, shape)
stack.push([x, y])
dfsOff()
goDown(x - 1, y, shape);
stack.push([x, y]);
dfsOff();
continue;
};
}
if (y > 0 && on(x, y - 1) && visited[(y - 1) * matrixWidth + x]) {
visited[y * matrixWidth + x] = visited[(y - 1) * matrixWidth + x];
continue;
};
}
if (x > 0 && on(x - 1, y) && visited[y * matrixWidth + x - 1]) {
visited[y * matrixWidth + x] = visited[y * matrixWidth + x - 1];
continue;
};
}
paths.push(\`<path fill="\${fg}" d="M\${x},\${y+0.5}a.5.5 0,0,1 .5-.5\`)
paths.push(\`<path fill="\${fg}" d="M\${x},\${y + 0.5}a.5.5 0,0,1 .5-.5\`);
baseY = y;
baseX = x
baseX = x;
goRight(x, y, paths.length - 1);
}
}
paths.forEach((path, i) => {
if (i === 0) return
if (i === 0) return;
svg += path;
svg += \`"/>\`
})
svg += \`"/>\`;
});
svg += \`</svg>\`;
return svg;
}
`

Wyświetl plik

@ -89,9 +89,7 @@ export function renderSVG(qr, params) {
[matrixWidth - 7, 0],
[0, matrixWidth - 7],
]) {
svg += \`<circle cx="\${x + 3.5}" cy="\${
y + 3.5
}" r="3" fill="none" stroke="\${fg}" stroke-width="1"/>\`;
svg += \`<circle cx="\${x + 3.5}" cy="\${y + 3.5}" r="3" fill="none" stroke="\${fg}" stroke-width="1"/>\`;
svg += \`<circle cx="\${x + 3.5}" cy="\${y + 3.5}" r="1.5" fill="\${fg}"/>\`;
}
}
@ -165,9 +163,7 @@ export function renderSVG(qr, params) {
const radius = Math.trunc(100 * 0.5 * ratio) / 100;
svg += \`M\${x + 0.5},\${y + 0.5 - radius}a\${radius},\${radius} 0,0,0 0,\${
2 * radius
}a\${radius},\${radius} 0,0,0 0,\${-2 * radius}\`;
svg += \`M\${x + 0.5},\${y + 0.5 - radius}a\${radius},\${radius} 0,0,0 0,\${2 * radius}a\${radius},\${radius} 0,0,0 0,\${-2 * radius}\`;
}
}
svg += \`"/></svg>\`;

Wyświetl plik

@ -59,19 +59,18 @@ const Module = {
};
export async function renderCanvas(qr, params, ctx) {
const moduleSize = 3;
const pixelSize = 1;
const unit = 3;
const pixel = 1;
const matrixWidth = qr.version * 4 + 17;
const margin = params["Margin"];
const fg = params["Foreground"];
const bg = params["Background"];
const alignment = params["Alignment pattern"];
const timing = params["Timing pattern"];
const file = params["Image"];
const pixelWidth = matrixWidth + 2 * margin;
const canvasSize = pixelWidth * moduleSize;
const canvasSize = pixelWidth * unit;
ctx.canvas.width = canvasSize;
ctx.canvas.height = canvasSize;
@ -79,25 +78,19 @@ export async function renderCanvas(qr, params, ctx) {
ctx.fillStyle = bg;
ctx.fillRect(0, 0, canvasSize, canvasSize);
ctx.fillStyle = fg;
for (let y = 0; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
const module = qr.matrix[y * matrixWidth + x];
if (module & 1) {
const px = x + margin;
const py = y + margin;
ctx.fillRect(
px * moduleSize,
py * moduleSize,
moduleSize,
moduleSize
);
ctx.fillRect(px * unit, py * unit, unit, unit);
}
}
}
}
const image = new Image();
if (file != null) {
image.src = URL.createObjectURL(file);
} else {
@ -106,42 +99,42 @@ export async function renderCanvas(qr, params, ctx) {
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();
}
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;
for (let y = 0; y < canvasSize; y++) {
for (let x = 0; x < canvasSize; x++) {
const i = (y * canvasSize + x) * 4;
if (data[i + 3] === 0) continue;
// Convert to grayscale and normalize to 0-255
const oldPixel =
(data[i] * 0.299 + data[i + 1] * 0.587 + data[i + 2] * 0.114) | 0;
let newPixel;
if (oldPixel < 128) {
newPixel = 0;
ctx.fillStyle = fg;
} else {
newPixel = 255;
ctx.fillStyle = bg;
}
ctx.fillRect(x * pixelSize, y * pixelSize, pixelSize, pixelSize);
ctx.fillRect(x * pixel, y * pixel, pixel, pixel);
data[i] = data[i + 1] = data[i + 2] = newPixel;
const error = oldPixel - newPixel;
// Distribute error to neighboring pixels
if (x < canvasSize - 1) {
data[i + 4] += (error * 7) / 16;
@ -149,17 +142,17 @@ export async function renderCanvas(qr, params, ctx) {
if (y < canvasSize - 1) {
if (x > 0) {
data[i + canvasSize * 4 - 4] += (error * 3) / 16;
}
data[i + canvasSize * 4] += (error * 5) / 16;
if (x < canvasSize - 1) {
data[i + canvasSize * 4 + 4] += (error * 1) / 16;
}
}
}
}
const dataOffset = (moduleSize - pixelSize) / 2;
const dataOffset = (unit - pixel) / 2;
for (let y = 0; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
const module = qr.matrix[y * matrixWidth + x];
@ -170,24 +163,27 @@ export async function renderCanvas(qr, params, ctx) {
}
const px = x + margin;
const py = y + margin;
const py = y + margin;
const type = module | 1;
if (
type === Module.FinderON ||
(alignment && type === Module.AlignmentON) ||
(timing && type === Module.TimingON)
) {
ctx.fillRect(px * moduleSize, py * moduleSize, moduleSize, moduleSize);
ctx.fillRect(px * unit, py * unit, unit, unit);
} else {
ctx.fillRect(
px * moduleSize + dataOffset,
py * moduleSize + dataOffset,
pixelSize,
pixelSize
px * unit + dataOffset,
py * unit + dataOffset,
pixel,
pixel,
);
}
}
}
}
`

Wyświetl plik

@ -34,14 +34,14 @@ const Module = {
export function renderSVG(qr, params) {
const matrixWidth = qr.version * 4 + 17;
const moduleSize = 10;
const unit = 10;
const dataSize = params["Data pixel size"];
const margin = params["Margin"] * moduleSize;
const margin = params["Margin"] * unit;
const fg = "#000";
const bg = "#fff";
const size = matrixWidth * moduleSize + 2 * margin;
const size = matrixWidth * unit + 2 * margin;
let svg = \`<svg xmlns="http://www.w3.org/2000/svg" viewBox="\${-margin} \${-margin} \${size} \${size}">\`;
if (params["Background"]) {
svg += \`<rect x="\${-margin}" y="\${-margin}" width="\${size}" height="\${size}" fill="\${bg}"/>\`;
@ -53,25 +53,15 @@ export function renderSVG(qr, params) {
[matrixWidth - 7, 0],
[0, matrixWidth - 7],
]) {
svg += \`M\${(x + 3) * moduleSize},\${
y * moduleSize
}h\${moduleSize}v\${moduleSize}h-\${moduleSize}z\`;
svg += \`M\${x * moduleSize},\${
(y + 3) * moduleSize
}h\${moduleSize}v\${moduleSize}h-\${moduleSize}z\`;
svg += \`M\${(x + 6) * moduleSize},\${
(y + 3) * moduleSize
}h\${moduleSize}v\${moduleSize}h-\${moduleSize}z\`;
svg += \`M\${(x + 3) * moduleSize},\${
(y + 6) * moduleSize
}h\${moduleSize}v\${moduleSize}h-\${moduleSize}z\`;
svg += \`M\${(x + 3) * unit},\${y * unit}h\${unit}v\${unit}h-\${unit}z\`;
svg += \`M\${x * unit},\${(y + 3) * unit}h\${unit}v\${unit}h-\${unit}z\`;
svg += \`M\${(x + 6) * unit},\${(y + 3) * unit}h\${unit}v\${unit}h-\${unit}z\`;
svg += \`M\${(x + 3) * unit},\${(y + 6) * unit}h\${unit}v\${unit}h-\${unit}z\`;
svg += \`M\${(x + 2) * moduleSize},\${(y + 2) * moduleSize}h\${
moduleSize * 3
}v\${moduleSize * 3}h-\${moduleSize * 3}z\`;
svg += \`M\${(x + 2) * unit},\${(y + 2) * unit}h\${unit * 3}v\${unit * 3}h-\${unit * 3}z\`;
}
const offset = (moduleSize - dataSize) / 2;
const offset = (unit - dataSize) / 2;
for (let y = 0; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
const module = qr.matrix[y * matrixWidth + x];
@ -81,8 +71,8 @@ export function renderSVG(qr, params) {
}
if (module & 1) {
const sx = x * moduleSize + offset;
const sy = y * moduleSize + offset;
const sx = x * unit + offset;
const sy = y * unit + offset;
svg += \`M\${sx},\${sy}h\${dataSize}v\${dataSize}h-\${dataSize}z\`;
}
}

Wyświetl plik

@ -1,63 +1,71 @@
import fs from "node:fs/promises";
import path from "node:path";
import { promises as fs } from "fs";
import path from "path";
import swc from "@swc/core";
import prettier from "prettier";
async function stringifyPresets(src, dst) {
async function convertTsToJs(inputDir, outputDir) {
try {
const dir = await fs.opendir(src);
for await (const dirent of dir) {
const srcPath = path.join(src, dirent.name);
const dstPath = path.join(dst, dirent.name);
// Ensure output directory exists
await fs.mkdir(outputDir, { recursive: true });
if (dirent.isDirectory()) {
try {
await fs.access(dstPath, fs.constants.F_OK);
} catch (e) {
await fs.mkdir(dstPath);
const files = await fs.readdir(inputDir);
const tsFiles = files.filter((file) => file.endsWith(".ts"));
for (const file of tsFiles) {
const inputPath = path.join(inputDir, file);
const outputPath = path.join(outputDir, file);
const tsCode = await fs.readFile(inputPath, "utf-8");
const { code } = await swc.transform(tsCode, {
filename: inputPath,
sourceMaps: false,
jsc: {
parser: {
syntax: "typescript",
},
target: "ES2020",
},
});
const formattedCode = await prettier.format(code, {
parser: "babel",
});
const originalLines = tsCode.split("\n").slice(3);
const strippedLines = formattedCode.split("\n");
let preservedCode = "";
let strippedIndex = 0;
for (const originalLine of originalLines) {
if (originalLine.trim() === "") {
// Preserve empty lines
preservedCode += "\n";
} else {
if (strippedIndex < strippedLines.length) {
preservedCode += strippedLines[strippedIndex] + "\n";
strippedIndex++;
}
}
stringifyPresets(srcPath, dstPath);
continue;
}
let fileString = await fs.readFile(srcPath, "utf-8");
// Quick & dirty "type stripping" only works b/c files are formatted
// This preserves spacing + comments which other methods don't
// Remove imports (identical for all files)
fileString = fileString.slice(111);
// Strip types from simple function args
fileString = fileString.replace(
/\((?:\s*.+: .+,\s)*\s*.+: [^)]+\s*\)/g,
(match) =>
"(" +
match
.slice(1, match.length - 1)
.split(",")
.map((typedArg) =>
typedArg.slice(0, typedArg.indexOf(":")).trimStart()
)
.join(", ") +
")"
);
fileString = fileString.replace("} satisfies RawParamsSchema;", "};");
fileString = fileString.replaceAll("`", "\\`");
fileString = fileString.replaceAll("${", "\\${");
const name = dirent.name.slice(0, dirent.name.length - 3);
preservedCode = preservedCode.replaceAll("`", "\\`");
preservedCode = preservedCode.replaceAll("${", "\\${");
await fs.writeFile(
dstPath,
`export const ${name} = \`${fileString}\`\n`,
{
flag: "w+",
}
outputPath,
`export const ${file.slice(0, -3)} = \`${preservedCode.slice(0, -1)}\`\n`,
"utf-8"
);
console.log(`Converted and formatted: ${inputPath} -> ${outputPath}`);
}
} catch (err) {
console.error(err);
console.log("Conversion and formatting completed successfully.");
} catch (error) {
console.error("An error occurred:", error);
}
}
stringifyPresets("./presets", "./src/lib/presets");
const inputDir = "./presets";
const outputDir = "./src/lib/presets";
convertTsToJs(inputDir, outputDir);