Skip to content

Commit

Permalink
proper fix for mirrored qr code and all styles fixes kozakdenys#105, f…
Browse files Browse the repository at this point in the history
  • Loading branch information
KilianB committed Aug 27, 2022
1 parent 5f98595 commit 53abdbc
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 31 deletions.
3 changes: 2 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[*.{js, ts}]
indent_style = space
indent_size = 2
indent_size = 2
end_of_line = lf
3 changes: 1 addition & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ module.exports = {
env: {
node: true
},
parser: '@typescript-eslint/parser',
parser: "@typescript-eslint/parser",
extends: [
"eslint:recommended",
"plugin:prettier/recommended",
"plugin:jest/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/eslint-recommended"
],
Expand Down
1 change: 1 addition & 0 deletions lib/core/QROptions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface RequiredOptions extends Options {
color: string;
gradient?: Gradient;
};
useLegacyDotRotation: boolean;
}
declare const defaultOptions: RequiredOptions;
export default defaultOptions;
2 changes: 1 addition & 1 deletion lib/qr-code-styling.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/qr-code-styling.js.map

Large diffs are not rendered by default.

25 changes: 20 additions & 5 deletions src/core/QRCanvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ export default class QRCanvas {

this.clear();
this.drawBackground();

//Draw the dots with the given filter function
this.drawDots((i: number, j: number): boolean => {
if (this._options.imageOptions.hideBackgroundDots) {
if (
Expand Down Expand Up @@ -187,14 +189,27 @@ export default class QRCanvas {
if (!this._qr.isDark(i, j)) {
continue;
}

const x = this._options.useLegacyDotRotation ? xBeginning + i * dotSize : yBeginning + j * dotSize;
const y = this._options.useLegacyDotRotation ? yBeginning + j * dotSize : xBeginning + i * dotSize;

dot.draw(
yBeginning + j * dotSize,
xBeginning + i * dotSize,
x,
y,
dotSize,
//Get neighbor function
(xOffset: number, yOffset: number): boolean => {
if (i + xOffset < 0 || j + yOffset < 0 || i + xOffset >= count || j + yOffset >= count) return false;
if (filter && !filter(i + xOffset, j + yOffset)) return false;
return !!this._qr && this._qr.isDark(i + xOffset, j + yOffset);
//Out of bounds check

if (this._options.useLegacyDotRotation) {
if (i + xOffset < 0 || j + yOffset < 0 || i + xOffset >= count || j + yOffset >= count) return false;
if (filter && !filter(i + xOffset, j + yOffset)) return false;
return !!this._qr && this._qr.isDark(i + xOffset, j + yOffset);
} else {
if (j + xOffset < 0 || i + yOffset < 0 || j + xOffset >= count || i + yOffset >= count) return false;
if (filter && !filter(j + xOffset, i + yOffset)) return false;
return !!this._qr && this._qr.isDark(i + yOffset, j + xOffset);
}
}
);
}
Expand Down
8 changes: 4 additions & 4 deletions src/core/QRCodeStyling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,12 @@ export default class QRCodeStyling {

if (extension.toLowerCase() === "svg") {
const serializer = new XMLSerializer();
const source = serializer.serializeToString(((element as unknown) as QRSVG).getElement());
const source = serializer.serializeToString((element as unknown as QRSVG).getElement());

return new Blob(['<?xml version="1.0" standalone="no"?>\r\n' + source], { type: "image/svg+xml" });
} else {
return new Promise((resolve) =>
((element as unknown) as QRCanvas).getCanvas().toBlob(resolve, `image/${extension}`, 1)
(element as unknown as QRCanvas).getCanvas().toBlob(resolve, `image/${extension}`, 1)
);
}
}
Expand Down Expand Up @@ -153,13 +153,13 @@ export default class QRCodeStyling {

if (extension.toLowerCase() === "svg") {
const serializer = new XMLSerializer();
let source = serializer.serializeToString(((element as unknown) as QRSVG).getElement());
let source = serializer.serializeToString((element as unknown as QRSVG).getElement());

source = '<?xml version="1.0" standalone="no"?>\r\n' + source;
const url = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(source);
downloadURI(url, `${name}.svg`);
} else {
const url = ((element as unknown) as QRCanvas).getCanvas().toDataURL(`image/${extension}`);
const url = (element as unknown as QRCanvas).getCanvas().toDataURL(`image/${extension}`);
downloadURI(url, `${name}.${extension}`);
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/core/QROptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface RequiredOptions extends Options {
color: string;
gradient?: Gradient;
};
useLegacyDotRotation: boolean;
}

const defaultOptions: RequiredOptions = {
Expand All @@ -54,7 +55,8 @@ const defaultOptions: RequiredOptions = {
},
backgroundOptions: {
color: "#fff"
}
},
useLegacyDotRotation: false
};

export default defaultOptions;
16 changes: 10 additions & 6 deletions src/core/QRSVG.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,16 +219,20 @@ export default class QRSVG {
continue;
}

dot.draw(
yBeginning + j * dotSize,
xBeginning + i * dotSize,
dotSize,
(xOffset: number, yOffset: number): boolean => {
const x = this._options.useLegacyDotRotation ? xBeginning + i * dotSize : yBeginning + j * dotSize;
const y = this._options.useLegacyDotRotation ? yBeginning + j * dotSize : xBeginning + i * dotSize;

dot.draw(x, y, dotSize, (xOffset: number, yOffset: number): boolean => {
if (this._options.useLegacyDotRotation) {
if (i + xOffset < 0 || j + yOffset < 0 || i + xOffset >= count || j + yOffset >= count) return false;
if (filter && !filter(i + xOffset, j + yOffset)) return false;
return !!this._qr && this._qr.isDark(i + xOffset, j + yOffset);
} else {
if (j + xOffset < 0 || i + yOffset < 0 || j + xOffset >= count || i + yOffset >= count) return false;
if (filter && !filter(j + xOffset, i + yOffset)) return false;
return !!this._qr && this._qr.isDark(i + yOffset, j + xOffset);
}
);
});

if (dot._element && this._dotsClipPath) {
this._dotsClipPath.appendChild(dot._element);
Expand Down
2 changes: 1 addition & 1 deletion src/figures/dot/canvas/QRDot.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe("Test QRDot class", () => {
[0, 0, 0, 0, 0],
[1, 1, 0, 1, 1],
[0, 1, 0, 1, 1],
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0]
];
const imgFile = fs.readFileSync(path.resolve(__dirname, "../../../assets/test/rounded_dots.png"), "base64");
const dot = new QRDot({ context: canvasContext, type: "rounded" });
Expand Down
57 changes: 48 additions & 9 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,26 @@
<head>
<meta charset="UTF-8" />
<title>QR Code Styling</title>

<style>
div {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
</style>
</head>

<body>
<div id="canvas"></div>
<div id="canvas2"></div>
<script type="text/javascript" defer>
<div id="container"></div>
<hr />
<div id="container2"></div>

<script type="text/javascript">
//Test out dot options
const options = {
width: 500,
height: 500,
width: 300,
height: 300,
data: "https://google.com",
image: "https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg",
dotsOptions: {
Expand All @@ -27,12 +38,40 @@
margin: 30
}
};
const qrCode = new QRCodeStyling(options);

qrCode.append(document.getElementById("canvas"));
const dotOptions = ["rounded", "dots", "classy", "classy-rounded", "square", "extra-rounded"];
const color = ["#e8977d", "#d3e87d", "#7de88e", "#7ddbe8", "#867de8", "#e87de4", "#e87d7d"];

const container = document.getElementById("container");

//Draw fixed version

dotOptions.forEach((dotOption, i) => {
options["dotsOptions"] = {
type: dotOptions[i],
color: color[i]
};

const qrCode = new QRCodeStyling(options);
qrCode.append(container);
// qrCode.download({
// extension: "svg"
// });
});

//Draw original dots

const container2 = document.getElementById("container2");
options["useLegacyDotRotation"] = true;

dotOptions.forEach((dotOption, i) => {
options["dotsOptions"] = {
type: dotOptions[i],
color: color[i]
};

qrCode.download({
extension: "svg"
const qrCode = new QRCodeStyling(options);
qrCode.append(container2);
});
</script>
</body>
Expand Down

0 comments on commit 53abdbc

Please sign in to comment.