fuck, minify breaks function toString

main
Kyle Zheng 2024-07-30 04:56:39 -04:00
rodzic dadb2cb282
commit ae20e21f27
5 zmienionych plików z 467 dodań i 6 usunięć

Wyświetl plik

@ -156,9 +156,114 @@ const code = `export const paramsSchema = ${objString(paramsSchema)};
const Module = ${objString(Module)};
${splitmix32.toString()}
function splitmix32(a) {
return function () {
a |= 0;
a = (a + 0x9e3779b9) | 0;
let t = a ^ (a >>> 16);
t = Math.imul(t, 0x21f0aaad);
t = t ^ (t >>> 15);
t = Math.imul(t, 0x735a2d97);
return ((t = t ^ (t >>> 15)) >>> 0) / 4294967296;
};
}
export ${renderCanvas.toString()}
export function renderCanvas(qr, params, ctx) {
const seededRand = splitmix32(params["Seed"]);
const margin = params["Margin"];
const quietZone = params["Quiet zone"];
const pixelSize = 10;
const radius = pixelSize / 2;
const qrWidth = qr.version * 4 + 17;
const matrixWidth = qrWidth + 2 * margin;
const canvasSize = matrixWidth * pixelSize;
const newMatrix = Array(matrixWidth * matrixWidth).fill(Module.SeparatorOFF);
// Copy qr to matrix with margin and randomly set pixels in margin
for (let y = 0; y < margin - quietZone; y++) {
for (let x = 0; x < matrixWidth; x++) {
if (seededRand() > 0.5) newMatrix[y * matrixWidth + x] = Module.DataON;
}
}
for (let y = margin - quietZone; y < margin + qrWidth + quietZone; y++) {
for (let x = 0; x < margin - quietZone; x++) {
if (seededRand() > 0.5) newMatrix[y * matrixWidth + x] = Module.DataON;
}
if (y >= margin && y < margin + qrWidth) {
for (let x = margin; x < matrixWidth - margin; x++) {
newMatrix[y * matrixWidth + x] =
qr.matrix[(y - margin) * qrWidth + x - margin];
}
}
for (let x = margin + qrWidth + quietZone; x < matrixWidth; x++) {
if (seededRand() > 0.5) newMatrix[y * matrixWidth + x] = Module.DataON;
}
}
for (let y = margin + qrWidth + quietZone; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
if (seededRand() > 0.5) newMatrix[y * matrixWidth + x] = Module.DataON;
}
}
const fg = "rgb(40, 70, 10)";
const bg = "rgb(200, 200, 100)";
ctx.canvas.width = canvasSize;
ctx.canvas.height = canvasSize;
ctx.fillStyle = bg;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
const xMax = matrixWidth - 1;
const yMax = matrixWidth - 1;
for (let y = 0; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
const module = newMatrix[y * matrixWidth + x];
const top = y > 0 && newMatrix[(y - 1) * matrixWidth + x] & 1;
const bottom = y < yMax && newMatrix[(y + 1) * matrixWidth + x] & 1;
const left = x > 0 && newMatrix[y * matrixWidth + x - 1] & 1;
const right = x < xMax && newMatrix[y * matrixWidth + x + 1] & 1;
ctx.fillStyle = fg;
if (module & 1) {
ctx.beginPath();
ctx.roundRect(x * pixelSize, y * pixelSize, pixelSize, pixelSize, [
(!left && !top && radius) || 0,
(!top && !right && radius) || 0,
(!right && !bottom && radius) || 0,
(!bottom && !left && radius) || 0,
]);
ctx.fill();
} else {
// Draw rounded concave corners
const topLeft =
y > 0 && x > 0 && newMatrix[(y - 1) * matrixWidth + x - 1] & 1;
const topRight =
y > 0 && x < xMax && newMatrix[(y - 1) * matrixWidth + x + 1] & 1;
const bottomRight =
y < yMax && x < xMax && newMatrix[(y + 1) * matrixWidth + x + 1] & 1;
const bottomLeft =
y < yMax && x > 0 && newMatrix[(y + 1) * matrixWidth + x - 1] & 1;
ctx.fillRect(x * pixelSize, y * pixelSize, pixelSize, pixelSize);
ctx.beginPath();
ctx.fillStyle = bg;
ctx.roundRect(x * pixelSize, y * pixelSize, pixelSize, pixelSize, [
(left && top && topLeft && radius) || 0,
(top && right && topRight && radius) || 0,
(right && bottom && bottomRight && radius) || 0,
(bottom && left && bottomLeft && radius) || 0,
]);
ctx.fill();
}
}
}
}
`;
export default {

Wyświetl plik

@ -181,7 +181,149 @@ const code = `export const paramsSchema = ${objString(paramsSchema)};
const Module = ${objString(Module)};
export ${renderCanvas.toString()}
export function renderCanvas(qr, params, ctx) {
const pixelSize = 10;
const margin = 2;
const matrixWidth = qr.version * 4 + 17;
const canvasSize = (matrixWidth + 2 * margin) * pixelSize;
ctx.canvas.width = canvasSize;
ctx.canvas.height = canvasSize;
ctx.fillStyle = "rgb(255, 255, 255)";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
const gradient = ctx.createRadialGradient(
ctx.canvas.width / 2,
ctx.canvas.height / 2,
2 * pixelSize,
ctx.canvas.width / 2,
ctx.canvas.height / 2,
20 * pixelSize
);
gradient.addColorStop(0, "red");
gradient.addColorStop(1, "blue");
ctx.fillStyle = gradient;
const radius = pixelSize / 2;
const finderPos = [
[margin, margin],
[margin + matrixWidth - 7, margin],
[margin, margin + matrixWidth - 7],
];
if (params["Circular finder pattern"]) {
for (const [x, y] of finderPos) {
ctx.beginPath();
ctx.arc(
(x + 3.5) * pixelSize,
(y + 3.5) * pixelSize,
3.5 * pixelSize,
0,
2 * Math.PI
);
ctx.fill();
ctx.fillStyle = "rgb(255, 255, 255)";
ctx.beginPath();
ctx.arc(
(x + 3.5) * pixelSize,
(y + 3.5) * pixelSize,
2.5 * pixelSize,
0,
2 * Math.PI
);
ctx.fill();
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(
(x + 3.5) * pixelSize,
(y + 3.5) * pixelSize,
1.5 * pixelSize,
0,
2 * Math.PI
);
ctx.fill();
}
}
const xMid = matrixWidth / 2;
const yMid = matrixWidth / 2;
const maxDist = Math.sqrt(xMid * xMid + yMid * yMid);
for (let y = 0; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
const module = qr.matrix[y * matrixWidth + x];
if (module & 1) {
if (params["Circular finder pattern"] && module === Module.FinderON)
continue;
if (
params["Circular alignment pattern"] &&
module === Module.AlignmentON
) {
// Find top left corner of alignment square
if (
qr.matrix[(y - 1) * matrixWidth + x] !== Module.AlignmentON &&
qr.matrix[y * matrixWidth + x - 1] !== Module.AlignmentON &&
qr.matrix[y * matrixWidth + x + 1] === Module.AlignmentON
) {
const xPos = x + 2.5 + margin;
const yPos = y + 2.5 + margin;
ctx.beginPath();
ctx.arc(
xPos * pixelSize,
yPos * pixelSize,
2.5 * pixelSize,
0,
2 * Math.PI
);
ctx.fill();
ctx.fillStyle = "rgb(255, 255, 255)";
ctx.beginPath();
ctx.arc(
xPos * pixelSize,
yPos * pixelSize,
1.5 * pixelSize,
0,
2 * Math.PI
);
ctx.fill();
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(
xPos * pixelSize,
yPos * pixelSize,
0.5 * pixelSize,
0,
2 * Math.PI
);
ctx.fill();
}
continue;
}
const xCenter = (x + margin) * pixelSize + radius;
const yCenter = (y + margin) * pixelSize + radius;
const xDist = Math.abs(xMid - x);
const yDist = Math.abs(yMid - y);
const scale =
(Math.sqrt(xDist * xDist + yDist * yDist) / maxDist) * 0.7 + 0.5;
ctx.beginPath();
ctx.arc(xCenter, yCenter, radius * scale, 0, 2 * Math.PI);
ctx.fill();
}
}
}
}
`;
export default {

Wyświetl plik

@ -203,7 +203,138 @@ const code = `export const paramsSchema = ${objString(paramsSchema)};
const Module = ${objString(Module)};
export ${renderCanvas.toString()}
export async function renderCanvas(qr, params, ctx) {
const moduleSize = 3;
const pixelSize = 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;
ctx.canvas.width = canvasSize;
ctx.canvas.height = canvasSize;
if (params["QR background"]) {
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) {
ctx.fillRect(
(x + margin) * moduleSize,
(y + margin) * moduleSize,
moduleSize,
moduleSize
);
}
}
}
}
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;
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);
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;
}
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;
for (let y = 0; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
const module = qr.matrix[y * matrixWidth + x];
if (module & 1) {
ctx.fillStyle = fg;
} else {
ctx.fillStyle = bg;
}
const type = module | 1;
if (
type === Module.FinderON ||
(alignment && type === Module.AlignmentON) ||
(timing && type === Module.TimingON)
) {
ctx.fillRect(
(x + margin) * moduleSize,
(y + margin) * moduleSize,
moduleSize,
moduleSize
);
} else {
ctx.fillRect(
(x + margin) * moduleSize + dataOffset,
(y + margin) * moduleSize + dataOffset,
pixelSize,
pixelSize
);
}
}
}
}
`;
export default {

Wyświetl plik

@ -102,7 +102,67 @@ const code = `export const paramsSchema = ${objString(paramsSchema)};
const Module = ${objString(Module)};
export ${renderSVG.toString()}
export function renderSVG(qr, params) {
const matrixWidth = qr.version * 4 + 17;
const margin = params["Margin"];
const dataSize = params["Data pixel size"];
const moduleSize = 10;
const fg = "#000";
const bg = "#fff";
const finderPos = [
[margin, margin],
[matrixWidth + margin - 7, margin],
[margin, matrixWidth + margin - 7],
];
const svgSize = (matrixWidth + 2 * margin) * moduleSize;
let svg = \`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 \${svgSize} \${svgSize}">\`;
if (params["Background"]) {
svg += \`<rect width="\${svgSize}" height="\${svgSize}" fill="\${bg}"/>\`;
}
svg += \`<path fill="\${fg}" d="\`;
for (const [x, y] of finderPos) {
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 + 2) * moduleSize},\${(y + 2) * moduleSize}h\${
moduleSize * 3
}v\${moduleSize * 3}h-\${moduleSize * 3}z\`;
}
const offset = (moduleSize - dataSize) / 2;
for (let y = 0; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
const module = qr.matrix[y * matrixWidth + x];
if ((module | 1) === Module.FinderON) {
continue;
}
if (module & 1) {
const sx = (x + margin) * moduleSize + offset;
const sy = (y + margin) * moduleSize + offset;
svg += \`M\${sx},\${sy}h\${dataSize}v\${dataSize}h-\${dataSize}z\`;
}
}
}
svg += \`"/></svg>\`;
return svg;
}
`;
export default {

Wyświetl plik

@ -47,7 +47,30 @@ function renderSVG(qr: OutputQr, params: Params<typeof paramsSchema>) {
const code = `export const paramsSchema = ${objString(paramsSchema)};
export ${renderSVG.toString()}
export function renderSVG(qr, params) {
const matrixWidth = qr.version * 4 + 17;
const margin = params["Margin"];
const fg = params["Foreground"];
const bg = params["Background"];
const size = matrixWidth + 2 * margin;
let svg = \`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 \${size} \${size}">\`;
svg += \`<rect width="\${size}" height="\${size}" fill="\${bg}"/>\`;
svg += \`<path fill="\${fg}" d="\`;
for (let y = 0; y < matrixWidth; y++) {
for (let x = 0; x < matrixWidth; x++) {
const module = qr.matrix[y * matrixWidth + x];
if (module & 1) {
svg += \`M\${x + margin},\${y + margin}h1v1h-1z\`;
}
}
}
svg += \`"/></svg>\`;
return svg;
}
`;
export default {