Skip to content

Commit

Permalink
feat(qr): border-radius for finders, optimize and simplify svg genera…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
gugu committed Oct 26, 2024
1 parent 010917c commit 6f5dfdd
Show file tree
Hide file tree
Showing 47 changed files with 58 additions and 54 deletions.
72 changes: 38 additions & 34 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,40 @@ export function colorToHex(color: number | string): string {
return `#${(color >>> 8).toString(16).padStart(6, "0")}`;
}

const svgMove = (left: number, top: number) => ['M', left, top]
const svgReturn = () => ['z']
const svgDeltaArc = (borderRadius: number, dx: number, dy: number, sweep: number = 0) => borderRadius > 0 ? ['a', borderRadius, borderRadius, 0, 0, sweep, dx, dy] : [];
const svgVerticalDeltaLite = (dy: number) => ['v', dy];
const svgHorizontalDeltaLine = (dx: number) => ['h', dx];


export function getFindersSVGPath(matrix: Matrix, size: number = 0, margin: number = 0, borderRadius: number = 0) {
const matrixSize = matrix.length * size + margin * 2;
let finderSize = 8;
let finderEnd = finderSize - 1;
const sides = [[0, 0], [1, 0], [0, 1]]
const sides = [[0, 0], [1, 0], [0, 1]] as const;
const rectangles = [];
for (const side of sides) {
const signs = side.map(sidePoint => sidePoint == 0 ? 1 : -1);
const [ xSign, ySign ] = side.map(sidePoint => sidePoint == 0 ? 1 : -1);
for (const offset of [0, 1, 2]) {
let corners = [
[matrixSize * side[0] + signs[0] * (margin + size * offset), matrixSize * side[1] + signs[1] * (margin + size * offset)],
[matrixSize * side[0] + signs[0] * (margin + size * (finderEnd - offset)), matrixSize * side[1] + signs[1] * (margin + size * (finderEnd - offset))],
]
let xCorner = matrixSize * side[0] + xSign * (margin + size * offset);
let yCorner = matrixSize * side[1] + ySign * (margin + size * offset);

const xDelta = xSign * (size * (finderEnd - 2 * offset) - 2 * borderRadius);
const yDelta = ySign * (size * (finderEnd - 2 * offset) - 2 * borderRadius);
let rectangle = [
'M', corners[0][0], corners[0][1],
'L', corners[0][0], corners[1][1],
'L', corners[1][0], corners[1][1],
'L', corners[1][0], corners[0][1],
'z',
svgMove(xCorner, yCorner + borderRadius * ySign),
svgVerticalDeltaLite(yDelta),
svgDeltaArc(borderRadius, borderRadius * xSign, borderRadius * ySign, side[1] | side[0]),
svgHorizontalDeltaLine(xDelta),
svgDeltaArc(borderRadius, borderRadius * xSign, - borderRadius * ySign, (side[1] | side[0])),
svgVerticalDeltaLite(-yDelta),
svgDeltaArc(borderRadius, - borderRadius * xSign, - borderRadius * ySign, (side[1] | side[0])),
svgHorizontalDeltaLine(-xDelta),
svgDeltaArc(borderRadius, - borderRadius * xSign, borderRadius * ySign, (side[1] | side[0])),
svgReturn(),
]
rectangles.push(...rectangle)
rectangles.push(...rectangle.flat())
}
}

Expand All @@ -49,29 +61,21 @@ export function getDotsSVGPath(matrix: Matrix, size: number, margin: number = 0,
for (let y = 0; y < column.length; y++) {
if (column[y]) {
const leftX = x * size + margin;
const rightX = (x + 1) * size + margin;
const topY = y * size + margin;
const bottomY = (y + 1) * size + margin;
const rectangle = [];
rectangle.push(`M ${leftX} ${topY + borderRadius}`);
rectangle.push(`L ${leftX} ${bottomY - borderRadius}`);
if (borderRadius > 0) {
rectangle.push(`A ${borderRadius} ${borderRadius} 0 0 0 ${leftX + borderRadius} ${bottomY}`);
}
rectangle.push(`L ${rightX - borderRadius} ${bottomY}`);
if (borderRadius > 0) {
rectangle.push(`A ${borderRadius} ${borderRadius} 0 0 0 ${rightX} ${bottomY - borderRadius}`);
}
rectangle.push(`L ${rightX} ${topY + borderRadius}`);
if (borderRadius > 0) {
rectangle.push(`A ${borderRadius} ${borderRadius} 0 0 0 ${rightX - borderRadius} ${topY}`);
}
rectangle.push(`L ${leftX + borderRadius} ${topY}`);
if (borderRadius > 0) {
rectangle.push(`A ${borderRadius} ${borderRadius} 0 0 0 ${leftX} ${topY + borderRadius}`);
}
rectangle.push(`z`);
rectangles.push(rectangle.join(" "));
const delta = size - 2 * borderRadius;
const rectangle = [
svgMove(leftX, topY + borderRadius),
svgVerticalDeltaLite(delta),
svgDeltaArc(borderRadius, borderRadius, borderRadius),
svgHorizontalDeltaLine(delta),
svgDeltaArc(borderRadius, borderRadius, -borderRadius),
svgVerticalDeltaLite(-delta),
svgDeltaArc(borderRadius, -borderRadius, -borderRadius),
svgHorizontalDeltaLine(-delta),
svgDeltaArc(borderRadius, -borderRadius, borderRadius),
svgReturn(),
];
rectangles.push(...rectangle.flat());
}
}
}
Expand Down
Binary file modified test_data/golden/browser_qr.pdf
Binary file not shown.
2 changes: 1 addition & 1 deletion test_data/golden/browser_qr.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/golden/browser_qr_logo_arraybuffer.pdf
Binary file not shown.
Binary file modified test_data/golden/browser_qr_with_border_radius.pdf
Binary file not shown.
Binary file modified test_data/golden/browser_qr_with_border_radius.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test_data/golden/browser_qr_with_border_radius.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/golden/browser_qr_with_colors.pdf
Binary file not shown.
2 changes: 1 addition & 1 deletion test_data/golden/browser_qr_with_colors.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test_data/golden/browser_qr_with_colors_hex.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test_data/golden/browser_qr_with_ec_level.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test_data/golden/browser_qr_with_logo_as_arraybuffer.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test_data/golden/browser_qr_with_size.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/golden/qr.pdf
Binary file not shown.
Binary file modified test_data/golden/qr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test_data/golden/qr.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/golden/qr_excavate.pdf
Binary file not shown.
Binary file modified test_data/golden/qr_excavate.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test_data/golden/qr_excavate.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/golden/qr_large.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/golden/qr_logo_arraybuffer.pdf
Binary file not shown.
Binary file modified test_data/golden/qr_logo_arraybuffer_jpg.pdf
Binary file not shown.
Binary file modified test_data/golden/qr_noexcavate.pdf
Binary file not shown.
Binary file modified test_data/golden/qr_noexcavate.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test_data/golden/qr_noexcavate.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/golden/qr_with_border_radius.pdf
Binary file not shown.
Binary file modified test_data/golden/qr_with_border_radius.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test_data/golden/qr_with_border_radius.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/golden/qr_with_colors.pdf
Binary file not shown.
Binary file modified test_data/golden/qr_with_colors.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test_data/golden/qr_with_colors.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test_data/golden/qr_with_colors_hex.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/golden/qr_with_colors_rgba.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test_data/golden/qr_with_colors_rgba.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test_data/golden/qr_with_ec_level.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/golden/qr_with_empty_options.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/golden/qr_with_logo.pdf
Binary file not shown.
Binary file modified test_data/golden/qr_with_logo.png
2 changes: 1 addition & 1 deletion test_data/golden/qr_with_logo.svg

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test_data/golden/qr_with_logo_as_arraybuffer.svg

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test_data/golden/qr_with_logo_as_arraybuffer_jpg.svg

Large diffs are not rendered by default.

Binary file modified test_data/golden/qr_with_logo_jpg.png
Binary file modified test_data/golden/qr_with_margin.png
Binary file modified test_data/golden/qr_with_size.png
2 changes: 1 addition & 1 deletion test_data/golden/qr_with_size.svg

Large diffs are not rendered by default.

Binary file modified test_data/golden/qr_with_undefined_size.png

0 comments on commit 6f5dfdd

Please sign in to comment.