@liquid-js/qr-code-styling 3.0.0-3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,127 +1,73 @@
1
- import { DOMImplementation, XMLSerializer as XMLSerializer$1, DOMParser as DOMParser$1 } from '@xmldom/xmldom';
2
- import { fileTypeFromBuffer } from 'file-type';
3
- import sharp from 'sharp';
4
- import qrcode from 'qrcode-generator';
1
+ import qrcode from "qrcode-generator";
5
2
 
6
- const TypeNumber = Array(41)
7
- .fill(0)
8
- .map((_, i) => i);
9
- var ErrorCorrectionLevel;
10
- (function (ErrorCorrectionLevel) {
11
- ErrorCorrectionLevel["L"] = "L";
12
- ErrorCorrectionLevel["M"] = "M";
13
- ErrorCorrectionLevel["Q"] = "Q";
14
- ErrorCorrectionLevel["H"] = "H";
15
- })(ErrorCorrectionLevel || (ErrorCorrectionLevel = {}));
16
- var Mode;
17
- (function (Mode) {
18
- Mode["numeric"] = "Numeric";
19
- Mode["alphanumeric"] = "Alphanumeric";
20
- Mode["byte"] = "Byte";
21
- Mode["kanji"] = "Kanji";
22
- Mode["unicode"] = "Unicode";
23
- })(Mode || (Mode = {}));
3
+ import sharp from "sharp";
4
+
5
+ import { fileTypeFromBuffer } from "file-type";
6
+
7
+ import { DOMImplementation, XMLSerializer as XMLSerializer$1, DOMParser as DOMParser$1 } from "@xmldom/xmldom";
8
+
9
+ let TypeNumber = Array(41).fill(0).map(((_, i) => i));
10
+
11
+ var ErrorCorrectionLevel, Mode;
12
+
13
+ (ErrorCorrectionLevel = ErrorCorrectionLevel || (ErrorCorrectionLevel = {})).L = "L",
14
+ ErrorCorrectionLevel.M = "M", ErrorCorrectionLevel.Q = "Q", ErrorCorrectionLevel.H = "H",
15
+ (Mode = Mode || (Mode = {})).numeric = "Numeric", Mode.alphanumeric = "Alphanumeric",
16
+ Mode.byte = "Byte", Mode.kanji = "Kanji", Mode.unicode = "Unicode";
17
+
18
+ let isObject = obj => !!obj && "object" == typeof obj && !Array.isArray(obj);
24
19
 
25
- const isObject = (obj) => !!obj && typeof obj === "object" && !Array.isArray(obj);
26
20
  function mergeDeep(target, ...sources) {
27
- if (!sources.length)
28
- return target;
29
- const source = sources.shift();
30
- if (source === undefined || !isObject(target) || !isObject(source))
31
- return target;
32
- target = { ...target };
33
- Object.keys(source).forEach((key) => {
34
- const targetValue = target[key];
35
- const sourceValue = source[key];
36
- if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
37
- target[key] = sourceValue;
38
- }
39
- else if (isObject(targetValue) && isObject(sourceValue)) {
40
- target[key] = mergeDeep(Object.assign({}, targetValue), sourceValue);
41
- }
42
- else {
43
- target[key] = sourceValue;
44
- }
45
- });
46
- return mergeDeep(target, ...sources);
21
+ if (!sources.length) return target;
22
+ let source = sources.shift();
23
+ return void 0 !== source && isObject(target) && isObject(source) ? (target = {
24
+ ...target
25
+ }, Object.keys(source).forEach((key => {
26
+ let targetValue = target[key], sourceValue = source[key];
27
+ Array.isArray(targetValue) && Array.isArray(sourceValue) ? target[key] = sourceValue : isObject(targetValue) && isObject(sourceValue) ? target[key] = mergeDeep(Object.assign({}, targetValue), sourceValue) : target[key] = sourceValue;
28
+ })), mergeDeep(target, ...sources)) : target;
47
29
  }
48
30
 
49
- var GradientType;
50
- (function (GradientType) {
51
- GradientType["radial"] = "radial";
52
- GradientType["linear"] = "linear";
53
- })(GradientType || (GradientType = {}));
54
- function sanitizeGradient(gradient) {
55
- const newGradient = { ...gradient };
56
- if (!newGradient.colorStops || !newGradient.colorStops.length) {
57
- throw "Field 'colorStops' is required in gradient";
58
- }
59
- if (newGradient.rotation) {
60
- newGradient.rotation = Number(newGradient.rotation);
61
- }
62
- else {
63
- newGradient.rotation = 0;
64
- }
65
- newGradient.colorStops = newGradient.colorStops.map((colorStop) => ({
31
+ var GradientType, DotType, CornerDotType, CornerSquareType, ShapeType;
32
+
33
+ function sanitizeGradient(gradient_newGradient) {
34
+ if (!(gradient_newGradient = {
35
+ ...gradient_newGradient
36
+ }).colorStops || !gradient_newGradient.colorStops.length) throw "Field 'colorStops' is required in gradient";
37
+ return gradient_newGradient.rotation = gradient_newGradient.rotation ? Number(gradient_newGradient.rotation) : 0,
38
+ gradient_newGradient.colorStops = gradient_newGradient.colorStops.map((colorStop => ({
66
39
  ...colorStop,
67
40
  offset: Number(colorStop.offset)
68
- }));
69
- return newGradient;
41
+ }))), gradient_newGradient;
70
42
  }
71
43
 
72
- var DotType;
73
- (function (DotType) {
74
- DotType["dot"] = "dot";
75
- DotType["randomDot"] = "random-dot";
76
- DotType["rounded"] = "rounded";
77
- DotType["verticalLine"] = "vertical-line";
78
- DotType["horizontalLine"] = "horizontal-line";
79
- DotType["classy"] = "classy";
80
- DotType["classyRounded"] = "classy-rounded";
81
- DotType["square"] = "square";
82
- DotType["smallSquare"] = "small-square";
83
- DotType["extraRounded"] = "extra-rounded";
84
- DotType["diamond"] = "diamond";
85
- })(DotType || (DotType = {}));
86
- var CornerDotType;
87
- (function (CornerDotType) {
88
- CornerDotType["dot"] = "dot";
89
- CornerDotType["square"] = "square";
90
- CornerDotType["heart"] = "heart";
91
- CornerDotType["extraRounded"] = "extra-rounded";
92
- CornerDotType["classy"] = "classy";
93
- CornerDotType["outpoint"] = "outpoint";
94
- CornerDotType["inpoint"] = "inpoint";
95
- })(CornerDotType || (CornerDotType = {}));
96
- var CornerSquareType;
97
- (function (CornerSquareType) {
98
- CornerSquareType["dot"] = "dot";
99
- CornerSquareType["square"] = "square";
100
- CornerSquareType["extraRounded"] = "extra-rounded";
101
- CornerSquareType["classy"] = "classy";
102
- CornerSquareType["outpoint"] = "outpoint";
103
- CornerSquareType["inpoint"] = "inpoint";
104
- })(CornerSquareType || (CornerSquareType = {}));
105
- var ShapeType;
106
- (function (ShapeType) {
107
- ShapeType["square"] = "square";
108
- ShapeType["circle"] = "circle";
109
- })(ShapeType || (ShapeType = {}));
110
- const defaultOptions = {
111
- document: undefined,
44
+ (GradientType = GradientType || (GradientType = {})).radial = "radial", GradientType.linear = "linear",
45
+ (DotType = DotType || (DotType = {})).dot = "dot", DotType.randomDot = "random-dot",
46
+ DotType.rounded = "rounded", DotType.verticalLine = "vertical-line", DotType.horizontalLine = "horizontal-line",
47
+ DotType.classy = "classy", DotType.classyRounded = "classy-rounded", DotType.square = "square",
48
+ DotType.smallSquare = "small-square", DotType.extraRounded = "extra-rounded", DotType.diamond = "diamond",
49
+ (CornerDotType = CornerDotType || (CornerDotType = {})).dot = "dot", CornerDotType.square = "square",
50
+ CornerDotType.heart = "heart", CornerDotType.extraRounded = "extra-rounded", CornerDotType.classy = "classy",
51
+ CornerDotType.outpoint = "outpoint", CornerDotType.inpoint = "inpoint", (CornerSquareType = CornerSquareType || (CornerSquareType = {})).dot = "dot",
52
+ CornerSquareType.square = "square", CornerSquareType.extraRounded = "extra-rounded",
53
+ CornerSquareType.classy = "classy", CornerSquareType.outpoint = "outpoint", CornerSquareType.inpoint = "inpoint",
54
+ (ShapeType = ShapeType || (ShapeType = {})).square = "square", ShapeType.circle = "circle";
55
+
56
+ let defaultOptions = {
57
+ document: void 0,
112
58
  shape: ShapeType.square,
113
- width: undefined,
114
- height: undefined,
59
+ width: void 0,
60
+ height: void 0,
115
61
  data: "",
116
62
  qrOptions: {
117
63
  typeNumber: TypeNumber[0],
118
- mode: undefined,
64
+ mode: void 0,
119
65
  errorCorrectionLevel: ErrorCorrectionLevel.Q
120
66
  },
121
67
  imageOptions: {
122
- hideBackgroundDots: true,
123
- imageSize: 0.4,
124
- crossOrigin: undefined,
68
+ hideBackgroundDots: !0,
69
+ imageSize: .4,
70
+ crossOrigin: void 0,
125
71
  margin: 0
126
72
  },
127
73
  dotsOptions: {
@@ -130,69 +76,49 @@ const defaultOptions = {
130
76
  size: 10
131
77
  }
132
78
  };
133
- function sanitizeOptions(options) {
134
- const newOptions = { ...options };
135
- newOptions.imageOptions = {
136
- ...newOptions.imageOptions,
137
- hideBackgroundDots: Boolean(newOptions.imageOptions.hideBackgroundDots),
138
- imageSize: Math.min(1, Number(newOptions.imageOptions.imageSize)) || 1,
139
- margin: Number(newOptions.imageOptions.margin)
140
- };
141
- newOptions.dotsOptions = {
142
- ...newOptions.dotsOptions
143
- };
144
- if (newOptions.dotsOptions.gradient) {
145
- newOptions.dotsOptions.gradient = sanitizeGradient(newOptions.dotsOptions.gradient);
146
- }
147
- // Ensure integer dot size
148
- newOptions.dotsOptions.size = Math.round(Math.max(0, newOptions.dotsOptions.size) || 10);
149
- if (newOptions.cornersSquareOptions) {
150
- newOptions.cornersSquareOptions = {
151
- ...newOptions.cornersSquareOptions
152
- };
153
- if (newOptions.cornersSquareOptions.gradient) {
154
- newOptions.cornersSquareOptions.gradient = sanitizeGradient(newOptions.cornersSquareOptions.gradient);
155
- }
156
- }
157
- if (newOptions.cornersDotOptions) {
158
- newOptions.cornersDotOptions = {
159
- ...newOptions.cornersDotOptions
160
- };
161
- if (newOptions.cornersDotOptions.gradient) {
162
- newOptions.cornersDotOptions.gradient = sanitizeGradient(newOptions.cornersDotOptions.gradient);
163
- }
164
- }
165
- if (newOptions.backgroundOptions) {
166
- newOptions.backgroundOptions = {
167
- ...newOptions.backgroundOptions
168
- };
169
- if (newOptions.backgroundOptions.gradient) {
170
- newOptions.backgroundOptions.gradient = sanitizeGradient(newOptions.backgroundOptions.gradient);
171
- }
172
- }
173
- if (!newOptions.document)
174
- newOptions.document = document;
175
- return newOptions;
79
+
80
+ function sanitizeOptions(newOptions_options) {
81
+ return (newOptions_options = {
82
+ ...newOptions_options
83
+ }).imageOptions = {
84
+ ...newOptions_options.imageOptions,
85
+ hideBackgroundDots: !!newOptions_options.imageOptions.hideBackgroundDots,
86
+ imageSize: Math.min(1, Number(newOptions_options.imageOptions.imageSize)) || 1,
87
+ margin: Number(newOptions_options.imageOptions.margin)
88
+ }, newOptions_options.dotsOptions = {
89
+ ...newOptions_options.dotsOptions
90
+ }, newOptions_options.dotsOptions.gradient && (newOptions_options.dotsOptions.gradient = sanitizeGradient(newOptions_options.dotsOptions.gradient)),
91
+ newOptions_options.dotsOptions.size = Math.round(Math.max(0, newOptions_options.dotsOptions.size) || 10),
92
+ newOptions_options.cornersSquareOptions && (newOptions_options.cornersSquareOptions = {
93
+ ...newOptions_options.cornersSquareOptions
94
+ }, newOptions_options.cornersSquareOptions.gradient && (newOptions_options.cornersSquareOptions.gradient = sanitizeGradient(newOptions_options.cornersSquareOptions.gradient))),
95
+ newOptions_options.cornersDotOptions && (newOptions_options.cornersDotOptions = {
96
+ ...newOptions_options.cornersDotOptions
97
+ }, newOptions_options.cornersDotOptions.gradient && (newOptions_options.cornersDotOptions.gradient = sanitizeGradient(newOptions_options.cornersDotOptions.gradient))),
98
+ newOptions_options.backgroundOptions && (newOptions_options.backgroundOptions = {
99
+ ...newOptions_options.backgroundOptions
100
+ }, newOptions_options.backgroundOptions.gradient && (newOptions_options.backgroundOptions.gradient = sanitizeGradient(newOptions_options.backgroundOptions.gradient))),
101
+ newOptions_options.document || (newOptions_options.document = document), newOptions_options;
176
102
  }
177
103
 
178
- const ErrorCorrectionPercents = {
179
- [ErrorCorrectionLevel.L]: 0.07,
180
- [ErrorCorrectionLevel.M]: 0.15,
181
- [ErrorCorrectionLevel.Q]: 0.25,
182
- [ErrorCorrectionLevel.H]: 0.3
104
+ let ErrorCorrectionPercents = {
105
+ [ErrorCorrectionLevel.L]: .07,
106
+ [ErrorCorrectionLevel.M]: .15,
107
+ [ErrorCorrectionLevel.Q]: .25,
108
+ [ErrorCorrectionLevel.H]: .3
183
109
  };
184
- function getMode(data) {
185
- switch (true) {
186
- case /^[0-9]*$/.test(data):
187
- return Mode.numeric;
188
- case /^[0-9A-Z $%*+\-./:]*$/.test(data):
189
- return Mode.alphanumeric;
190
- // eslint-disable-next-line no-control-regex
191
- case /[^\u0000-\u00ff]/.test(data):
192
- return Mode.unicode;
193
- default:
194
- return Mode.byte;
195
- }
110
+
111
+ let rx = /\.?0+$/;
112
+
113
+ function numToAttr(value) {
114
+ return value.toFixed(7).replace(rx, "");
115
+ }
116
+
117
+ function svgPath(strings, ...values) {
118
+ return strings.reduce(((t, v, i) => {
119
+ let p = "";
120
+ return i && (p = values[i - 1]), "number" == typeof p && (p = numToAttr(p)), `${t}${p}${v}`;
121
+ }), "").trim().replace(/[\s\n\r]+/gim, " ");
196
122
  }
197
123
 
198
124
  class QRCornerDot {
@@ -200,278 +126,160 @@ class QRCornerDot {
200
126
  return this._element;
201
127
  }
202
128
  constructor(type, document) {
203
- this.type = type;
204
- this.document = document;
129
+ this.type = type, this.document = document;
205
130
  }
206
131
  draw(args) {
207
- const type = this.type;
208
132
  let drawFunction;
209
- switch (type) {
210
- case CornerDotType.square:
211
- drawFunction = this.drawSquare;
212
- break;
213
- case CornerDotType.heart:
214
- drawFunction = this.drawHeart;
215
- break;
216
- case CornerDotType.extraRounded:
217
- drawFunction = this.drawRounded;
218
- break;
219
- case CornerDotType.classy:
220
- drawFunction = this.drawClassy;
221
- break;
222
- case CornerDotType.inpoint:
223
- drawFunction = this.drawInpoint;
224
- break;
225
- case CornerDotType.outpoint:
226
- drawFunction = this.drawOutpoint;
227
- break;
228
- case CornerDotType.dot:
229
- default:
230
- drawFunction = this.drawDot;
133
+ switch (this.type) {
134
+ case CornerDotType.square:
135
+ drawFunction = this.drawSquare;
136
+ break;
137
+
138
+ case CornerDotType.heart:
139
+ drawFunction = this.drawHeart;
140
+ break;
141
+
142
+ case CornerDotType.extraRounded:
143
+ drawFunction = this.drawRounded;
144
+ break;
145
+
146
+ case CornerDotType.classy:
147
+ drawFunction = this.drawClassy;
148
+ break;
149
+
150
+ case CornerDotType.inpoint:
151
+ drawFunction = this.drawInpoint;
152
+ break;
153
+
154
+ case CornerDotType.outpoint:
155
+ drawFunction = this.drawOutpoint;
156
+ break;
157
+
158
+ default:
159
+ drawFunction = this.drawDot;
231
160
  }
232
161
  drawFunction.call(this, args);
233
162
  }
234
- rotateFigure({ x, y, size, rotation = 0, draw }) {
235
- const cx = x + size / 2;
236
- const cy = y + size / 2;
237
- draw();
238
- this._element?.setAttribute("transform", `rotate(${(180 * rotation) / Math.PI},${cx},${cy})`);
163
+ rotateFigure({x: cx_x, y: cy_y, size, rotation = 0, draw}) {
164
+ cx_x += size / 2, cy_y += size / 2, draw(), this._element?.setAttribute("transform", `rotate(${numToAttr(180 * rotation / Math.PI)},${cx_x},${cy_y})`);
239
165
  }
240
166
  basicDot(args) {
241
- const { size, x, y } = args;
167
+ let {size, x, y} = args;
242
168
  this.rotateFigure({
243
169
  ...args,
244
170
  draw: () => {
245
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "circle");
246
- this._element.setAttribute("cx", String(x + size / 2));
247
- this._element.setAttribute("cy", String(y + size / 2));
248
- this._element.setAttribute("r", String(size / 2));
171
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "circle"),
172
+ this._element.setAttribute("cx", numToAttr(x + size / 2)), this._element.setAttribute("cy", numToAttr(y + size / 2)),
173
+ this._element.setAttribute("r", numToAttr(size / 2));
249
174
  }
250
175
  });
251
176
  }
252
177
  basicSquare(args) {
253
- const { size, x, y } = args;
178
+ let {size, x, y} = args;
254
179
  this.rotateFigure({
255
180
  ...args,
256
181
  draw: () => {
257
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "rect");
258
- this._element.setAttribute("x", String(x));
259
- this._element.setAttribute("y", String(y));
260
- this._element.setAttribute("width", String(size));
261
- this._element.setAttribute("height", String(size));
182
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "rect"),
183
+ this._element.setAttribute("x", numToAttr(x)), this._element.setAttribute("y", numToAttr(y)),
184
+ this._element.setAttribute("width", numToAttr(size)), this._element.setAttribute("height", numToAttr(size));
262
185
  }
263
186
  });
264
187
  }
265
188
  basicHeart(args) {
266
- const { size, x, y } = args;
189
+ let {size, x, y} = args;
267
190
  this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path");
268
- const path = [
269
- "M",
270
- 0.925,
271
- 0.3538125,
272
- "c",
273
- 0,
274
- 0.0325869,
275
- -0.0054931,
276
- 0.0644619,
277
- -0.0164688,
278
- 0.095625,
279
- "S",
280
- 0.87825,
281
- 0.5147812,
282
- 0.850625,
283
- 0.5519688,
284
- "C",
285
- 0.823,
286
- 0.5891563,
287
- 0.7858125,
288
- 0.631125,
289
- 0.7390625,
290
- 0.677875,
291
- "S",
292
- 0.6331632,
293
- 0.7802256,
294
- 0.561625,
295
- 0.8446875,
296
- "L",
297
- 0.5,
298
- 0.8999375,
299
- "l",
300
- -0.061625,
301
- -0.05525,
302
- "C",
303
- 0.3668368,
304
- 0.7802256,
305
- 0.3076875,
306
- 0.724625,
307
- 0.2609375,
308
- 0.677875,
309
- "S",
310
- 0.177,
311
- 0.5891563,
312
- 0.149375,
313
- 0.5519688,
314
- "S",
315
- 0.1024444,
316
- 0.4806007,
317
- 0.0914688,
318
- 0.4494375,
319
- "S",
320
- 0.075,
321
- 0.3863994,
322
- 0.075,
323
- 0.3538125,
324
- "C",
325
- 0.075,
326
- 0.2872256,
327
- 0.0973125,
328
- 0.231625,
329
- 0.1419375,
330
- 0.187,
331
- "S",
332
- 0.2421631,
333
- 0.1200625,
334
- 0.30875,
335
- 0.1200625,
336
- "c",
337
- 0.0368369,
338
- 0,
339
- 0.0718994,
340
- 0.0077881,
341
- 0.1051875,
342
- 0.023375,
343
- "S",
344
- 0.4759131,
345
- 0.1809756,
346
- 0.5,
347
- 0.2093125,
348
- "c",
349
- 0.0240868,
350
- -0.0283369,
351
- 0.0527744,
352
- -0.0502881,
353
- 0.0860625,
354
- -0.065875,
355
- "c",
356
- 0.0332882,
357
- -0.0155869,
358
- 0.0683507,
359
- -0.023375,
360
- 0.1051875,
361
- -0.023375,
362
- "c",
363
- 0.0665869,
364
- 0,
365
- 0.1221875,
366
- 0.0223125,
367
- 0.1668125,
368
- 0.0669375,
369
- "S",
370
- 0.925,
371
- 0.2872256,
372
- 0.925,
373
- 0.3538125,
374
- "z"
375
- ];
376
- let move = false;
377
- let i = 0;
378
- this._element.setAttribute("d", path
379
- .map((v) => {
380
- if (typeof v == "string") {
381
- i = 0;
382
- move = v.toUpperCase() == v;
383
- return v;
384
- }
385
- i++;
386
- v = v * size;
387
- if (move) {
388
- v += i % 2 == 1 ? x : y;
389
- }
390
- return v.toFixed(5);
391
- })
392
- .join(" "));
191
+ let move = !1, i = 0;
192
+ this._element.setAttribute("d", [ "M", .925, .3538125, "c", 0, .0325869, -.0054931, .0644619, -.0164688, .095625, "S", .87825, .5147812, .850625, .5519688, "C", .823, .5891563, .7858125, .631125, .7390625, .677875, "S", .6331632, .7802256, .561625, .8446875, "L", .5, .8999375, "l", -.061625, -.05525, "C", .3668368, .7802256, .3076875, .724625, .2609375, .677875, "S", .177, .5891563, .149375, .5519688, "S", .1024444, .4806007, .0914688, .4494375, "S", .075, .3863994, .075, .3538125, "C", .075, .2872256, .0973125, .231625, .1419375, .187, "S", .2421631, .1200625, .30875, .1200625, "c", .0368369, 0, .0718994, .0077881, .1051875, .023375, "S", .4759131, .1809756, .5, .2093125, "c", .0240868, -.0283369, .0527744, -.0502881, .0860625, -.065875, "c", .0332882, -.0155869, .0683507, -.023375, .1051875, -.023375, "c", .0665869, 0, .1221875, .0223125, .1668125, .0669375, "S", .925, .2872256, .925, .3538125, "z" ].map((v => "string" == typeof v ? (i = 0,
193
+ move = v.toUpperCase() == v, v) : (i++, v *= size, move && (v += 1 == i % 2 ? x : y),
194
+ numToAttr(v)))).join(" "));
393
195
  }
394
196
  basicRounded(args) {
395
- const { size, x, y } = args;
197
+ let {size, x, y} = args;
396
198
  this.rotateFigure({
397
199
  ...args,
398
200
  draw: () => {
399
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "rect");
400
- this._element.setAttribute("x", String(x));
401
- this._element.setAttribute("y", String(y));
402
- this._element.setAttribute("width", String(size));
403
- this._element.setAttribute("height", String(size));
404
- this._element.setAttribute("rx", String(size / 4));
405
- this._element.setAttribute("ry", String(size / 4));
201
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "rect"),
202
+ this._element.setAttribute("x", numToAttr(x)), this._element.setAttribute("y", numToAttr(y)),
203
+ this._element.setAttribute("width", numToAttr(size)), this._element.setAttribute("height", numToAttr(size)),
204
+ this._element.setAttribute("rx", numToAttr(size / 4)), this._element.setAttribute("ry", numToAttr(size / 4));
406
205
  }
407
206
  });
408
207
  }
409
208
  basicClassy(args) {
410
- const { size, x, y } = args;
411
- const dotSize = size / 7;
209
+ let {size, x, y} = args, dotSize = size / 7;
412
210
  this.rotateFigure({
413
211
  ...args,
414
212
  draw: () => {
415
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path");
416
- this._element.setAttribute("clip-rule", "evenodd");
417
- this._element.setAttribute("d", `M ${x} ${y + 2.5 * dotSize}` +
418
- `v ${2 * dotSize}` +
419
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${dotSize * 2.5} ${dotSize * 2.5}` +
420
- `h ${4.5 * dotSize}` +
421
- `v ${-4.5 * dotSize}` +
422
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${-dotSize * 2.5} ${-dotSize * 2.5}` +
423
- `h ${-2 * dotSize}` +
424
- `H ${x}` +
425
- `z`);
213
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
214
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x} ${y + 2.5 * dotSize} v ${2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * dotSize} ${2.5 * dotSize} h ${4.5 * dotSize} v ${-4.5 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * -dotSize} ${2.5 * -dotSize} h ${-2 * dotSize} H ${x} z`);
426
215
  }
427
216
  });
428
217
  }
429
218
  basicInpoint(args) {
430
- const { size, x, y } = args;
431
- const dotSize = size;
219
+ let {size, x, y} = args;
432
220
  this.rotateFigure({
433
221
  ...args,
434
222
  draw: () => {
435
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path");
436
- this._element.setAttribute("clip-rule", "evenodd");
437
- this._element.setAttribute("d", `M ${x} ${y + dotSize / 2}` +
438
- `v ${dotSize / 4}` +
439
- `a ${dotSize / 4}, ${dotSize / 4} 0 0 0 ${dotSize / 4}, ${dotSize / 4}` +
440
- `h ${(dotSize / 4) * 3}` +
441
- `v ${(-dotSize / 4) * 3}` +
442
- `a ${dotSize / 4}, ${dotSize / 4} 0 0 0 ${-dotSize / 4}, ${-dotSize / 4}` +
443
- `h ${-dotSize / 2}` +
444
- `a ${dotSize / 4}, ${dotSize / 4} 0 0 0 ${-dotSize / 4}, ${dotSize / 4}` +
445
- `z`);
223
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
224
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x} ${y + size / 2} v ${size / 4} a ${size / 4}, ${size / 4} 0 0 0 ${size / 4}, ${size / 4} h ${size / 4 * 3} v ${-size / 4 * 3} a ${size / 4}, ${size / 4} 0 0 0 ${-size / 4}, ${-size / 4} h ${-size / 2} a ${size / 4}, ${size / 4} 0 0 0 ${-size / 4}, ${size / 4} z`);
446
225
  }
447
226
  });
448
227
  }
449
- drawDot({ x, y, size, rotation }) {
450
- this.basicDot({ x, y, size, rotation });
228
+ drawDot({x, y, size, rotation}) {
229
+ this.basicDot({
230
+ x,
231
+ y,
232
+ size,
233
+ rotation
234
+ });
451
235
  }
452
- drawSquare({ x, y, size, rotation }) {
453
- this.basicSquare({ x, y, size, rotation });
236
+ drawSquare({x, y, size, rotation}) {
237
+ this.basicSquare({
238
+ x,
239
+ y,
240
+ size,
241
+ rotation
242
+ });
454
243
  }
455
- drawHeart({ x, y, size, rotation }) {
456
- const scaleFactor = 0.2;
244
+ drawHeart({x, y, size, rotation}) {
457
245
  this.basicHeart({
458
- x: x - (scaleFactor * size) / 2,
459
- y: y - (scaleFactor * size) / 2,
460
- size: size * (1 + scaleFactor),
246
+ x: x - .2 * size / 2,
247
+ y: y - .2 * size / 2,
248
+ size: 1.2 * size,
461
249
  rotation
462
250
  });
463
251
  }
464
- drawRounded({ x, y, size, rotation }) {
465
- this.basicRounded({ x, y, size, rotation });
252
+ drawRounded({x, y, size, rotation}) {
253
+ this.basicRounded({
254
+ x,
255
+ y,
256
+ size,
257
+ rotation
258
+ });
466
259
  }
467
- drawClassy({ x, y, size, rotation }) {
468
- this.basicClassy({ x, y, size, rotation });
260
+ drawClassy({x, y, size, rotation}) {
261
+ this.basicClassy({
262
+ x,
263
+ y,
264
+ size,
265
+ rotation
266
+ });
469
267
  }
470
- drawInpoint({ x, y, size, rotation }) {
471
- this.basicInpoint({ x, y, size, rotation });
268
+ drawInpoint({x, y, size, rotation}) {
269
+ this.basicInpoint({
270
+ x,
271
+ y,
272
+ size,
273
+ rotation
274
+ });
472
275
  }
473
- drawOutpoint({ x, y, size, rotation }) {
474
- this.basicInpoint({ x, y, size, rotation: (rotation || 0) + Math.PI });
276
+ drawOutpoint({x, y, size, rotation}) {
277
+ this.basicInpoint({
278
+ x,
279
+ y,
280
+ size,
281
+ rotation: (rotation || 0) + Math.PI
282
+ });
475
283
  }
476
284
  }
477
285
 
@@ -480,184 +288,136 @@ class QRCornerSquare {
480
288
  return this._element;
481
289
  }
482
290
  constructor(type, document) {
483
- this.type = type;
484
- this.document = document;
291
+ this.type = type, this.document = document;
485
292
  }
486
293
  draw(args) {
487
- const type = this.type;
488
294
  let drawFunction;
489
- switch (type) {
490
- case CornerSquareType.square:
491
- drawFunction = this.drawSquare;
492
- break;
493
- case CornerSquareType.extraRounded:
494
- drawFunction = this.drawExtraRounded;
495
- break;
496
- case CornerSquareType.classy:
497
- drawFunction = this.drawClassy;
498
- break;
499
- case CornerSquareType.outpoint:
500
- drawFunction = this.drawOutpoint;
501
- break;
502
- case CornerSquareType.inpoint:
503
- drawFunction = this.drawInpoint;
504
- break;
505
- case CornerSquareType.dot:
506
- default:
507
- drawFunction = this.drawDot;
295
+ switch (this.type) {
296
+ case CornerSquareType.square:
297
+ drawFunction = this.drawSquare;
298
+ break;
299
+
300
+ case CornerSquareType.extraRounded:
301
+ drawFunction = this.drawExtraRounded;
302
+ break;
303
+
304
+ case CornerSquareType.classy:
305
+ drawFunction = this.drawClassy;
306
+ break;
307
+
308
+ case CornerSquareType.outpoint:
309
+ drawFunction = this.drawOutpoint;
310
+ break;
311
+
312
+ case CornerSquareType.inpoint:
313
+ drawFunction = this.drawInpoint;
314
+ break;
315
+
316
+ default:
317
+ drawFunction = this.drawDot;
508
318
  }
509
319
  drawFunction.call(this, args);
510
320
  }
511
- rotateFigure({ x, y, size, rotation = 0, draw }) {
512
- const cx = x + size / 2;
513
- const cy = y + size / 2;
514
- draw();
515
- this._element?.setAttribute("transform", `rotate(${(180 * rotation) / Math.PI},${cx},${cy})`);
321
+ rotateFigure({x: cx, y: cy, size, rotation = 0, draw}) {
322
+ cx += size / 2, cy += size / 2, draw(), this._element?.setAttribute("transform", `rotate(${numToAttr(180 * rotation / Math.PI)},${cx},${cy})`);
516
323
  }
517
324
  basicDot(args) {
518
- const { size, x, y } = args;
519
- const dotSize = size / 7;
325
+ let {size, x, y} = args, dotSize = size / 7;
520
326
  this.rotateFigure({
521
327
  ...args,
522
328
  draw: () => {
523
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path");
524
- this._element.setAttribute("clip-rule", "evenodd");
525
- this._element.setAttribute("d", `M ${x + size / 2} ${y}` + // M cx, y // Move to top of ring
526
- `a ${size / 2} ${size / 2} 0 1 0 0.1 0` + // a outerRadius, outerRadius, 0, 1, 0, 1, 0 // Draw outer arc, but don't close it
527
- `z` + // Z // Close the outer shape
528
- `m 0 ${dotSize}` + // m -1 outerRadius-innerRadius // Move to top point of inner radius
529
- `a ${size / 2 - dotSize} ${size / 2 - dotSize} 0 1 1 -0.1 0` + // a innerRadius, innerRadius, 0, 1, 1, -1, 0 // Draw inner arc, but don't close it
530
- `Z` // Z // Close the inner ring. Actually will still work without, but inner ring will have one unit missing in stroke
531
- );
329
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
330
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x + size / 2} ${y} a ${size / 2} ${size / 2} 0 1 0 0.1 0 z m 0 ${dotSize} a ${size / 2 - dotSize} ${size / 2 - dotSize} 0 1 1 -0.1 0 Z`);
532
331
  }
533
332
  });
534
333
  }
535
334
  basicSquare(args) {
536
- const { size, x, y } = args;
537
- const dotSize = size / 7;
335
+ let {size, x, y} = args, dotSize = size / 7;
538
336
  this.rotateFigure({
539
337
  ...args,
540
338
  draw: () => {
541
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path");
542
- this._element.setAttribute("clip-rule", "evenodd");
543
- this._element.setAttribute("d", `M ${x} ${y}` +
544
- `v ${size}` +
545
- `h ${size}` +
546
- `v ${-size}` +
547
- `z` +
548
- `M ${x + dotSize} ${y + dotSize}` +
549
- `h ${size - 2 * dotSize}` +
550
- `v ${size - 2 * dotSize}` +
551
- `h ${-size + 2 * dotSize}` +
552
- `z`);
339
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
340
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x} ${y} v ${size} h ${size} v ${-size} z M ${x + dotSize} ${y + dotSize} h ${size - 2 * dotSize} v ${size - 2 * dotSize} h ${2 * dotSize - size} z`);
553
341
  }
554
342
  });
555
343
  }
556
344
  basicExtraRounded(args) {
557
- const { size, x, y } = args;
558
- const dotSize = size / 7;
345
+ let {size, x, y} = args, dotSize = size / 7;
559
346
  this.rotateFigure({
560
347
  ...args,
561
348
  draw: () => {
562
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path");
563
- this._element.setAttribute("clip-rule", "evenodd");
564
- this._element.setAttribute("d", `M ${x} ${y + 2.5 * dotSize}` +
565
- `v ${2 * dotSize}` +
566
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${dotSize * 2.5} ${dotSize * 2.5}` +
567
- `h ${2 * dotSize}` +
568
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${dotSize * 2.5} ${-dotSize * 2.5}` +
569
- `v ${-2 * dotSize}` +
570
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${-dotSize * 2.5} ${-dotSize * 2.5}` +
571
- `h ${-2 * dotSize}` +
572
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${-dotSize * 2.5} ${dotSize * 2.5}` +
573
- `z` +
574
- `M ${x + 2.5 * dotSize} ${y + dotSize}` +
575
- `h ${2 * dotSize}` +
576
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${dotSize * 1.5} ${dotSize * 1.5}` +
577
- `v ${2 * dotSize}` +
578
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${-dotSize * 1.5} ${dotSize * 1.5}` +
579
- `h ${-2 * dotSize}` +
580
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${-dotSize * 1.5} ${-dotSize * 1.5}` +
581
- `v ${-2 * dotSize}` +
582
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${dotSize * 1.5} ${-dotSize * 1.5}` +
583
- `z`);
349
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
350
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x} ${y + 2.5 * dotSize} v ${2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * dotSize} ${2.5 * dotSize} h ${2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * dotSize} ${2.5 * -dotSize} v ${-2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * -dotSize} ${2.5 * -dotSize} h ${-2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * -dotSize} ${2.5 * dotSize} z M ${x + 2.5 * dotSize} ${y + dotSize} h ${2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * dotSize} ${1.5 * dotSize} v ${2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * -dotSize} ${1.5 * dotSize} h ${-2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * -dotSize} ${1.5 * -dotSize} v ${-2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * dotSize} ${1.5 * -dotSize} z`);
584
351
  }
585
352
  });
586
353
  }
587
354
  basicClassy(args) {
588
- const { size, x, y } = args;
589
- const dotSize = size / 7;
355
+ let {size, x, y} = args, dotSize = size / 7;
590
356
  this.rotateFigure({
591
357
  ...args,
592
358
  draw: () => {
593
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path");
594
- this._element.setAttribute("clip-rule", "evenodd");
595
- this._element.setAttribute("d", `M ${x} ${y + 2.5 * dotSize}` +
596
- `v ${2 * dotSize}` +
597
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${dotSize * 2.5} ${dotSize * 2.5}` +
598
- `h ${4.5 * dotSize}` +
599
- `v ${-4.5 * dotSize}` +
600
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${-dotSize * 2.5} ${-dotSize * 2.5}` +
601
- `h ${-2 * dotSize}` +
602
- `H ${x}` +
603
- `z` +
604
- `M ${x + 2.5 * dotSize} ${y + dotSize}` +
605
- `h ${2 * dotSize}` +
606
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${dotSize * 1.5} ${dotSize * 1.5}` +
607
- `v ${3.5 * dotSize}` +
608
- `h ${-3.5 * dotSize}` +
609
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${-dotSize * 1.5} ${-dotSize * 1.5}` +
610
- `v ${-3.5 * dotSize}` +
611
- `z`);
359
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
360
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x} ${y + 2.5 * dotSize} v ${2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * dotSize} ${2.5 * dotSize} h ${4.5 * dotSize} v ${-4.5 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * -dotSize} ${2.5 * -dotSize} h ${-2 * dotSize} H ${x} z M ${x + 2.5 * dotSize} ${y + dotSize} h ${2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * dotSize} ${1.5 * dotSize} v ${3.5 * dotSize} h ${-3.5 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * -dotSize} ${1.5 * -dotSize} v ${-3.5 * dotSize} z`);
612
361
  }
613
362
  });
614
363
  }
615
364
  basicInpoint(args) {
616
- const { size, x, y } = args;
617
- const dotSize = size / 7;
365
+ let {size, x, y} = args, dotSize = size / 7;
618
366
  this.rotateFigure({
619
367
  ...args,
620
368
  draw: () => {
621
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path");
622
- this._element.setAttribute("clip-rule", "evenodd");
623
- this._element.setAttribute("d", `M ${x} ${y + 2.5 * dotSize}` +
624
- `v ${2 * dotSize}` +
625
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${dotSize * 2.5} ${dotSize * 2.5}` +
626
- `h ${4.5 * dotSize}` +
627
- `v ${-4.5 * dotSize}` +
628
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${-dotSize * 2.5} ${-dotSize * 2.5}` +
629
- `h ${-2 * dotSize}` +
630
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${-dotSize * 2.5} ${dotSize * 2.5}` +
631
- "z" +
632
- `M ${x + 2.5 * dotSize} ${y + dotSize}` +
633
- `h ${2 * dotSize}` +
634
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${dotSize * 1.5} ${dotSize * 1.5}` +
635
- `v ${3.5 * dotSize}` +
636
- `h ${-3.5 * dotSize}` +
637
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${-dotSize * 1.5} ${-dotSize * 1.5}` +
638
- `v ${-2 * dotSize}` +
639
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${dotSize * 1.5} ${-dotSize * 1.5}` +
640
- `z`);
369
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
370
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x} ${y + 2.5 * dotSize} v ${2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * dotSize} ${2.5 * dotSize} h ${4.5 * dotSize} v ${-4.5 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * -dotSize} ${2.5 * -dotSize} h ${-2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * -dotSize} ${2.5 * dotSize} z M ${x + 2.5 * dotSize} ${y + dotSize} h ${2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * dotSize} ${1.5 * dotSize} v ${3.5 * dotSize} h ${-3.5 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * -dotSize} ${1.5 * -dotSize} v ${-2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * dotSize} ${1.5 * -dotSize} z`);
641
371
  }
642
372
  });
643
373
  }
644
- drawDot({ x, y, size, rotation }) {
645
- this.basicDot({ x, y, size, rotation });
374
+ drawDot({x, y, size, rotation}) {
375
+ this.basicDot({
376
+ x,
377
+ y,
378
+ size,
379
+ rotation
380
+ });
646
381
  }
647
- drawSquare({ x, y, size, rotation }) {
648
- this.basicSquare({ x, y, size, rotation });
382
+ drawSquare({x, y, size, rotation}) {
383
+ this.basicSquare({
384
+ x,
385
+ y,
386
+ size,
387
+ rotation
388
+ });
649
389
  }
650
- drawExtraRounded({ x, y, size, rotation }) {
651
- this.basicExtraRounded({ x, y, size, rotation });
390
+ drawExtraRounded({x, y, size, rotation}) {
391
+ this.basicExtraRounded({
392
+ x,
393
+ y,
394
+ size,
395
+ rotation
396
+ });
652
397
  }
653
- drawClassy({ x, y, size, rotation }) {
654
- this.basicClassy({ x, y, size, rotation });
398
+ drawClassy({x, y, size, rotation}) {
399
+ this.basicClassy({
400
+ x,
401
+ y,
402
+ size,
403
+ rotation
404
+ });
655
405
  }
656
- drawInpoint({ x, y, size, rotation }) {
657
- this.basicInpoint({ x, y, size, rotation });
406
+ drawInpoint({x, y, size, rotation}) {
407
+ this.basicInpoint({
408
+ x,
409
+ y,
410
+ size,
411
+ rotation
412
+ });
658
413
  }
659
- drawOutpoint({ x, y, size, rotation }) {
660
- this.basicInpoint({ x, y, size, rotation: (rotation || 0) + Math.PI });
414
+ drawOutpoint({x, y, size, rotation}) {
415
+ this.basicInpoint({
416
+ x,
417
+ y,
418
+ size,
419
+ rotation: (rotation || 0) + Math.PI
420
+ });
661
421
  }
662
422
  }
663
423
 
@@ -666,503 +426,356 @@ class QRDot {
666
426
  return this._element;
667
427
  }
668
428
  constructor(type, document) {
669
- this.type = type;
670
- this.document = document;
429
+ this.type = type, this.document = document;
671
430
  }
672
431
  draw(args) {
673
- const type = this.type;
674
432
  let drawFunction;
675
- switch (type) {
676
- case DotType.dot:
677
- drawFunction = this.drawDot;
678
- break;
679
- case DotType.randomDot:
680
- drawFunction = this.drawRandomDot;
681
- break;
682
- case DotType.classy:
683
- drawFunction = this.drawClassy;
684
- break;
685
- case DotType.classyRounded:
686
- drawFunction = this.drawClassyRounded;
687
- break;
688
- case DotType.rounded:
689
- drawFunction = this.drawRounded;
690
- break;
691
- case DotType.verticalLine:
692
- drawFunction = this.drawVerticalLine;
693
- break;
694
- case DotType.horizontalLine:
695
- drawFunction = this.drawHorizontalLine;
696
- break;
697
- case DotType.extraRounded:
698
- drawFunction = this.drawExtraRounded;
699
- break;
700
- case DotType.diamond:
701
- drawFunction = this.drawDiamond;
702
- break;
703
- case DotType.smallSquare:
704
- drawFunction = this.drawSmallSquare;
705
- break;
706
- case DotType.square:
707
- default:
708
- drawFunction = this.drawSquare;
433
+ switch (this.type) {
434
+ case DotType.dot:
435
+ drawFunction = this.drawDot;
436
+ break;
437
+
438
+ case DotType.randomDot:
439
+ drawFunction = this.drawRandomDot;
440
+ break;
441
+
442
+ case DotType.classy:
443
+ drawFunction = this.drawClassy;
444
+ break;
445
+
446
+ case DotType.classyRounded:
447
+ drawFunction = this.drawClassyRounded;
448
+ break;
449
+
450
+ case DotType.rounded:
451
+ drawFunction = this.drawRounded;
452
+ break;
453
+
454
+ case DotType.verticalLine:
455
+ drawFunction = this.drawVerticalLine;
456
+ break;
457
+
458
+ case DotType.horizontalLine:
459
+ drawFunction = this.drawHorizontalLine;
460
+ break;
461
+
462
+ case DotType.extraRounded:
463
+ drawFunction = this.drawExtraRounded;
464
+ break;
465
+
466
+ case DotType.diamond:
467
+ drawFunction = this.drawDiamond;
468
+ break;
469
+
470
+ case DotType.smallSquare:
471
+ drawFunction = this.drawSmallSquare;
472
+ break;
473
+
474
+ default:
475
+ drawFunction = this.drawSquare;
709
476
  }
710
477
  drawFunction.call(this, args);
711
478
  }
712
- rotateFigure({ x, y, size, rotation = 0, draw }) {
713
- const cx = x + size / 2;
714
- const cy = y + size / 2;
715
- draw();
716
- this._element?.setAttribute("transform", `rotate(${(180 * rotation) / Math.PI},${cx},${cy})`);
479
+ rotateFigure({x: cx, y: cy, size, rotation = 0, draw}) {
480
+ cx += size / 2, cy += size / 2, draw(), this._element?.setAttribute("transform", `rotate(${numToAttr(180 * rotation / Math.PI)},${cx},${cy})`);
717
481
  }
718
482
  basicDot(args) {
719
- const { size, x, y } = args;
483
+ let {size, x, y} = args;
720
484
  this.rotateFigure({
721
485
  ...args,
722
486
  draw: () => {
723
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "circle");
724
- this._element.setAttribute("cx", String(x + size / 2));
725
- this._element.setAttribute("cy", String(y + size / 2));
726
- this._element.setAttribute("r", String(size / 2));
487
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "circle"),
488
+ this._element.setAttribute("cx", numToAttr(x + size / 2)), this._element.setAttribute("cy", numToAttr(y + size / 2)),
489
+ this._element.setAttribute("r", numToAttr(size / 2));
727
490
  }
728
491
  });
729
492
  }
730
493
  basicSquare(args) {
731
- const { size, x, y } = args;
494
+ let {size, x, y} = args;
732
495
  this.rotateFigure({
733
496
  ...args,
734
497
  draw: () => {
735
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "rect");
736
- this._element.setAttribute("x", String(x));
737
- this._element.setAttribute("y", String(y));
738
- this._element.setAttribute("width", String(size));
739
- this._element.setAttribute("height", String(size));
498
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "rect"),
499
+ this._element.setAttribute("x", numToAttr(x)), this._element.setAttribute("y", numToAttr(y)),
500
+ this._element.setAttribute("width", numToAttr(size)), this._element.setAttribute("height", numToAttr(size));
740
501
  }
741
502
  });
742
503
  }
743
- //if rotation === 0 - right side is rounded
744
504
  basicSideRounded(args) {
745
- const { size, x, y } = args;
505
+ let {size, x, y} = args;
746
506
  this.rotateFigure({
747
507
  ...args,
748
508
  draw: () => {
749
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path");
750
- this._element.setAttribute("d", `M ${x} ${y}` + //go to top left position
751
- `v ${size}` + //draw line to left bottom corner
752
- `h ${size / 2}` + //draw line to left bottom corner + half of size right
753
- `a ${size / 2} ${size / 2}, 0, 0, 0, 0 ${-size}` // draw rounded corner
754
- );
509
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
510
+ this._element.setAttribute("d", svgPath`M ${x} ${y} v ${size} h ${size / 2} a ${size / 2} ${size / 2}, 0, 0, 0, 0 ${-size} z`);
755
511
  }
756
512
  });
757
513
  }
758
- //if rotation === 0 - top right corner is rounded
759
514
  basicCornerRounded(args) {
760
- const { size, x, y } = args;
515
+ let {size, x, y} = args;
761
516
  this.rotateFigure({
762
517
  ...args,
763
518
  draw: () => {
764
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path");
765
- this._element.setAttribute("d", `M ${x} ${y}` + //go to top left position
766
- `v ${size}` + //draw line to left bottom corner
767
- `h ${size}` + //draw line to right bottom corner
768
- `v ${-size / 2}` + //draw line to right bottom corner + half of size top
769
- `a ${size / 2} ${size / 2}, 0, 0, 0, ${-size / 2} ${-size / 2}` // draw rounded corner
770
- );
519
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
520
+ this._element.setAttribute("d", svgPath`M ${x} ${y} v ${size} h ${size} v ${-size / 2} a ${size / 2} ${size / 2}, 0, 0, 0, ${-size / 2} ${-size / 2} z`);
771
521
  }
772
522
  });
773
523
  }
774
- //if rotation === 0 - top right corner is rounded
775
524
  basicCornerExtraRounded(args) {
776
- const { size, x, y } = args;
525
+ let {size, x, y} = args;
777
526
  this.rotateFigure({
778
527
  ...args,
779
528
  draw: () => {
780
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path");
781
- this._element.setAttribute("d", `M ${x} ${y}` + //go to top left position
782
- `v ${size}` + //draw line to left bottom corner
783
- `h ${size}` + //draw line to right bottom corner
784
- `a ${size} ${size}, 0, 0, 0, ${-size} ${-size}` // draw rounded top right corner
785
- );
529
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
530
+ this._element.setAttribute("d", svgPath`M ${x} ${y} v ${size} h ${size} a ${size} ${size}, 0, 0, 0, ${-size} ${-size} z`);
786
531
  }
787
532
  });
788
533
  }
789
- //if rotation === 0 - left bottom and right top corners are rounded
790
534
  basicCornersRounded(args) {
791
- const { size, x, y } = args;
535
+ let {size, x, y} = args;
792
536
  this.rotateFigure({
793
537
  ...args,
794
538
  draw: () => {
795
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path");
796
- this._element.setAttribute("d", `M ${x} ${y}` + //go to left top position
797
- `v ${size / 2}` + //draw line to left top corner + half of size bottom
798
- `a ${size / 2} ${size / 2}, 0, 0, 0, ${size / 2} ${size / 2}` + // draw rounded left bottom corner
799
- `h ${size / 2}` + //draw line to right bottom corner
800
- `v ${-size / 2}` + //draw line to right bottom corner + half of size top
801
- `a ${size / 2} ${size / 2}, 0, 0, 0, ${-size / 2} ${-size / 2}` // draw rounded right top corner
802
- );
539
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
540
+ this._element.setAttribute("d", svgPath`M ${x} ${y} v ${size / 2} a ${size / 2} ${size / 2}, 0, 0, 0, ${size / 2} ${size / 2} h ${size / 2} v ${-size / 2} a ${size / 2} ${size / 2}, 0, 0, 0, ${-size / 2} ${-size / 2} z`);
803
541
  }
804
542
  });
805
543
  }
806
- drawDot({ x, y, size }) {
807
- this.basicDot({ x, y, size, rotation: 0 });
808
- }
809
- drawRandomDot({ x, y, size }) {
810
- const randomFactor = Math.random() * (1 - 0.75) + 0.75;
811
- this.basicDot({ x, y, size: size * randomFactor, rotation: 0 });
812
- }
813
- drawSquare({ x, y, size }) {
814
- this.basicSquare({ x, y, size, rotation: 0 });
815
- }
816
- drawSmallSquare({ x, y, size }) {
817
- const originalSize = size;
818
- size = originalSize * 0.7;
819
- x = x + originalSize * 0.15;
820
- y = y + originalSize * 0.15;
821
- this.basicSquare({ x, y, size, rotation: 0 });
822
- }
823
- drawDiamond({ x, y, size }) {
824
- this.basicSquare({ x, y, size, rotation: Math.PI / 4 });
825
- }
826
- drawRounded({ x, y, size, getNeighbor }) {
827
- const leftNeighbor = getNeighbor ? +getNeighbor(-1, 0) : 0;
828
- const rightNeighbor = getNeighbor ? +getNeighbor(1, 0) : 0;
829
- const topNeighbor = getNeighbor ? +getNeighbor(0, -1) : 0;
830
- const bottomNeighbor = getNeighbor ? +getNeighbor(0, 1) : 0;
831
- const neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + bottomNeighbor;
832
- if (neighborsCount === 0) {
833
- this.basicDot({ x, y, size, rotation: 0 });
834
- return;
835
- }
836
- if (neighborsCount > 2 || (leftNeighbor && rightNeighbor) || (topNeighbor && bottomNeighbor)) {
837
- this.basicSquare({ x, y, size, rotation: 0 });
838
- return;
839
- }
840
- if (neighborsCount === 2) {
841
- let rotation = 0;
842
- if (leftNeighbor && topNeighbor) {
843
- rotation = Math.PI / 2;
844
- }
845
- else if (topNeighbor && rightNeighbor) {
846
- rotation = Math.PI;
847
- }
848
- else if (rightNeighbor && bottomNeighbor) {
849
- rotation = -Math.PI / 2;
850
- }
851
- this.basicCornerRounded({ x, y, size, rotation });
852
- return;
853
- }
854
- if (neighborsCount === 1) {
855
- let rotation = 0;
856
- if (topNeighbor) {
857
- rotation = Math.PI / 2;
858
- }
859
- else if (rightNeighbor) {
860
- rotation = Math.PI;
861
- }
862
- else if (bottomNeighbor) {
863
- rotation = -Math.PI / 2;
864
- }
865
- this.basicSideRounded({ x, y, size, rotation });
866
- return;
867
- }
544
+ drawDot({x, y, size}) {
545
+ this.basicDot({
546
+ x,
547
+ y,
548
+ size,
549
+ rotation: 0
550
+ });
868
551
  }
869
- drawVerticalLine({ x, y, size, getNeighbor }) {
870
- const leftNeighbor = getNeighbor ? +getNeighbor(-1, 0) : 0;
871
- const rightNeighbor = getNeighbor ? +getNeighbor(1, 0) : 0;
872
- const topNeighbor = getNeighbor ? +getNeighbor(0, -1) : 0;
873
- const bottomNeighbor = getNeighbor ? +getNeighbor(0, 1) : 0;
874
- const neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + bottomNeighbor;
875
- if (neighborsCount === 0 ||
876
- (leftNeighbor && !(topNeighbor || bottomNeighbor)) ||
877
- (rightNeighbor && !(topNeighbor || bottomNeighbor))) {
878
- this.basicDot({ x, y, size, rotation: 0 });
879
- return;
880
- }
881
- if (topNeighbor && bottomNeighbor) {
882
- this.basicSquare({ x, y, size, rotation: 0 });
883
- return;
884
- }
885
- if (topNeighbor && !bottomNeighbor) {
886
- const rotation = Math.PI / 2;
887
- this.basicSideRounded({ x, y, size, rotation });
888
- return;
889
- }
890
- if (bottomNeighbor && !topNeighbor) {
891
- const rotation = -Math.PI / 2;
892
- this.basicSideRounded({ x, y, size, rotation });
893
- return;
894
- }
552
+ drawRandomDot({x, y, size}) {
553
+ this.basicDot({
554
+ x,
555
+ y,
556
+ size: size * (.25 * Math.random() + .75),
557
+ rotation: 0
558
+ });
895
559
  }
896
- drawHorizontalLine({ x, y, size, getNeighbor }) {
897
- const leftNeighbor = getNeighbor ? +getNeighbor(-1, 0) : 0;
898
- const rightNeighbor = getNeighbor ? +getNeighbor(1, 0) : 0;
899
- const topNeighbor = getNeighbor ? +getNeighbor(0, -1) : 0;
900
- const bottomNeighbor = getNeighbor ? +getNeighbor(0, 1) : 0;
901
- const neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + bottomNeighbor;
902
- if (neighborsCount === 0 ||
903
- (topNeighbor && !(leftNeighbor || rightNeighbor)) ||
904
- (bottomNeighbor && !(leftNeighbor || rightNeighbor))) {
905
- this.basicDot({ x, y, size, rotation: 0 });
906
- return;
907
- }
908
- if (leftNeighbor && rightNeighbor) {
909
- this.basicSquare({ x, y, size, rotation: 0 });
910
- return;
911
- }
912
- if (leftNeighbor && !rightNeighbor) {
913
- const rotation = 0;
914
- this.basicSideRounded({ x, y, size, rotation });
915
- return;
916
- }
917
- if (rightNeighbor && !leftNeighbor) {
918
- const rotation = Math.PI;
919
- this.basicSideRounded({ x, y, size, rotation });
920
- return;
921
- }
560
+ drawSquare({x, y, size}) {
561
+ this.basicSquare({
562
+ x,
563
+ y,
564
+ size,
565
+ rotation: 0
566
+ });
922
567
  }
923
- drawExtraRounded({ x, y, size, getNeighbor }) {
924
- const leftNeighbor = getNeighbor ? +getNeighbor(-1, 0) : 0;
925
- const rightNeighbor = getNeighbor ? +getNeighbor(1, 0) : 0;
926
- const topNeighbor = getNeighbor ? +getNeighbor(0, -1) : 0;
927
- const bottomNeighbor = getNeighbor ? +getNeighbor(0, 1) : 0;
928
- const neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + bottomNeighbor;
929
- if (neighborsCount === 0) {
930
- this.basicDot({ x, y, size, rotation: 0 });
931
- return;
932
- }
933
- if (neighborsCount > 2 || (leftNeighbor && rightNeighbor) || (topNeighbor && bottomNeighbor)) {
934
- this.basicSquare({ x, y, size, rotation: 0 });
935
- return;
936
- }
937
- if (neighborsCount === 2) {
938
- let rotation = 0;
939
- if (leftNeighbor && topNeighbor) {
940
- rotation = Math.PI / 2;
941
- }
942
- else if (topNeighbor && rightNeighbor) {
943
- rotation = Math.PI;
944
- }
945
- else if (rightNeighbor && bottomNeighbor) {
946
- rotation = -Math.PI / 2;
947
- }
948
- this.basicCornerExtraRounded({ x, y, size, rotation });
949
- return;
950
- }
951
- if (neighborsCount === 1) {
952
- let rotation = 0;
953
- if (topNeighbor) {
954
- rotation = Math.PI / 2;
955
- }
956
- else if (rightNeighbor) {
957
- rotation = Math.PI;
958
- }
959
- else if (bottomNeighbor) {
960
- rotation = -Math.PI / 2;
961
- }
962
- this.basicSideRounded({ x, y, size, rotation });
963
- return;
964
- }
568
+ drawSmallSquare({x, y, size}) {
569
+ this.basicSquare({
570
+ x: x + .15 * size,
571
+ y: y + .15 * size,
572
+ size: .7 * size,
573
+ rotation: 0
574
+ });
965
575
  }
966
- drawClassy({ x, y, size, getNeighbor }) {
967
- const leftNeighbor = getNeighbor ? +getNeighbor(-1, 0) : 0;
968
- const rightNeighbor = getNeighbor ? +getNeighbor(1, 0) : 0;
969
- const topNeighbor = getNeighbor ? +getNeighbor(0, -1) : 0;
970
- const bottomNeighbor = getNeighbor ? +getNeighbor(0, 1) : 0;
971
- const neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + bottomNeighbor;
972
- if (neighborsCount === 0) {
973
- this.basicCornersRounded({ x, y, size, rotation: Math.PI / 2 });
974
- return;
975
- }
976
- if (!leftNeighbor && !topNeighbor) {
977
- this.basicCornerRounded({ x, y, size, rotation: -Math.PI / 2 });
978
- return;
979
- }
980
- if (!rightNeighbor && !bottomNeighbor) {
981
- this.basicCornerRounded({ x, y, size, rotation: Math.PI / 2 });
982
- return;
983
- }
984
- this.basicSquare({ x, y, size, rotation: 0 });
985
- }
986
- drawClassyRounded({ x, y, size, getNeighbor }) {
987
- const leftNeighbor = getNeighbor ? +getNeighbor(-1, 0) : 0;
988
- const rightNeighbor = getNeighbor ? +getNeighbor(1, 0) : 0;
989
- const topNeighbor = getNeighbor ? +getNeighbor(0, -1) : 0;
990
- const bottomNeighbor = getNeighbor ? +getNeighbor(0, 1) : 0;
991
- const neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + bottomNeighbor;
992
- if (neighborsCount === 0) {
993
- this.basicCornersRounded({ x, y, size, rotation: Math.PI / 2 });
994
- return;
995
- }
996
- if (!leftNeighbor && !topNeighbor) {
997
- this.basicCornerExtraRounded({ x, y, size, rotation: -Math.PI / 2 });
998
- return;
999
- }
1000
- if (!rightNeighbor && !bottomNeighbor) {
1001
- this.basicCornerExtraRounded({ x, y, size, rotation: Math.PI / 2 });
1002
- return;
1003
- }
1004
- this.basicSquare({ x, y, size, rotation: 0 });
576
+ drawDiamond({x, y, size}) {
577
+ this.basicSquare({
578
+ x,
579
+ y,
580
+ size,
581
+ rotation: Math.PI / 4
582
+ });
1005
583
  }
1006
- }
1007
-
1008
- const browserImageTools = {
1009
- toDataURL(url) {
1010
- return new Promise((resolve, reject) => {
1011
- if (typeof url == "string") {
1012
- const xhr = new XMLHttpRequest();
1013
- xhr.onload = function () {
1014
- const reader = new FileReader();
1015
- reader.onloadend = function () {
1016
- resolve(reader.result);
1017
- };
1018
- reader.readAsDataURL(xhr.response);
1019
- };
1020
- xhr.onerror = xhr.onabort = xhr.ontimeout = reject;
1021
- xhr.open("GET", url);
1022
- xhr.responseType = "blob";
1023
- xhr.send();
1024
- }
1025
- else {
1026
- const reader = new FileReader();
1027
- reader.onloadend = function () {
1028
- resolve(reader.result);
1029
- };
1030
- reader.readAsDataURL(url);
1031
- }
584
+ drawRounded({x, y, size, getNeighbor: bottomNeighbor_getNeighbor}) {
585
+ var leftNeighbor_rotation = bottomNeighbor_getNeighbor ? +bottomNeighbor_getNeighbor(-1, 0) : 0;
586
+ let rightNeighbor = bottomNeighbor_getNeighbor ? +bottomNeighbor_getNeighbor(1, 0) : 0, topNeighbor = bottomNeighbor_getNeighbor ? +bottomNeighbor_getNeighbor(0, -1) : 0;
587
+ var neighborsCount_rotation = leftNeighbor_rotation + rightNeighbor + topNeighbor + (bottomNeighbor_getNeighbor = bottomNeighbor_getNeighbor ? +bottomNeighbor_getNeighbor(0, 1) : 0);
588
+ 0 === neighborsCount_rotation ? this.basicDot({
589
+ x,
590
+ y,
591
+ size,
592
+ rotation: 0
593
+ }) : 2 < neighborsCount_rotation || leftNeighbor_rotation && rightNeighbor || topNeighbor && bottomNeighbor_getNeighbor ? this.basicSquare({
594
+ x,
595
+ y,
596
+ size,
597
+ rotation: 0
598
+ }) : 2 === neighborsCount_rotation ? (neighborsCount_rotation = 0, leftNeighbor_rotation && topNeighbor ? neighborsCount_rotation = Math.PI / 2 : topNeighbor && rightNeighbor ? neighborsCount_rotation = Math.PI : rightNeighbor && bottomNeighbor_getNeighbor && (neighborsCount_rotation = -Math.PI / 2),
599
+ this.basicCornerRounded({
600
+ x,
601
+ y,
602
+ size,
603
+ rotation: neighborsCount_rotation
604
+ })) : 1 === neighborsCount_rotation && (leftNeighbor_rotation = 0, topNeighbor ? leftNeighbor_rotation = Math.PI / 2 : rightNeighbor ? leftNeighbor_rotation = Math.PI : bottomNeighbor_getNeighbor && (leftNeighbor_rotation = -Math.PI / 2),
605
+ this.basicSideRounded({
606
+ x,
607
+ y,
608
+ size,
609
+ rotation: leftNeighbor_rotation
610
+ }));
611
+ }
612
+ drawVerticalLine({x, y, size, getNeighbor: bottomNeighbor}) {
613
+ let leftNeighbor = bottomNeighbor ? +bottomNeighbor(-1, 0) : 0, rightNeighbor = bottomNeighbor ? +bottomNeighbor(1, 0) : 0, topNeighbor = bottomNeighbor ? +bottomNeighbor(0, -1) : 0;
614
+ 0 === leftNeighbor + rightNeighbor + topNeighbor + (bottomNeighbor = bottomNeighbor ? +bottomNeighbor(0, 1) : 0) || leftNeighbor && !topNeighbor && !bottomNeighbor || rightNeighbor && !topNeighbor && !bottomNeighbor ? this.basicDot({
615
+ x,
616
+ y,
617
+ size,
618
+ rotation: 0
619
+ }) : topNeighbor && bottomNeighbor ? this.basicSquare({
620
+ x,
621
+ y,
622
+ size,
623
+ rotation: 0
624
+ }) : topNeighbor && !bottomNeighbor ? this.basicSideRounded({
625
+ x,
626
+ y,
627
+ size,
628
+ rotation: Math.PI / 2
629
+ }) : bottomNeighbor && !topNeighbor && this.basicSideRounded({
630
+ x,
631
+ y,
632
+ size,
633
+ rotation: -Math.PI / 2
1032
634
  });
1033
- },
1034
- getSize(src, crossOrigin) {
1035
- return new Promise((resolve, reject) => {
1036
- const image = new Image();
1037
- if (crossOrigin === "string") {
1038
- image.crossOrigin = crossOrigin;
1039
- }
1040
- image.onload = () => {
1041
- resolve({ width: image.width, height: image.height });
1042
- };
1043
- image.onerror = image.onabort = reject;
1044
- if (typeof src == "string")
1045
- image.src = src;
1046
- else
1047
- browserImageTools
1048
- .toDataURL(src)
1049
- .then((url) => (image.src = url))
1050
- .catch(reject);
635
+ }
636
+ drawHorizontalLine({x, y, size, getNeighbor: bottomNeighbor}) {
637
+ let leftNeighbor = bottomNeighbor ? +bottomNeighbor(-1, 0) : 0, rightNeighbor = bottomNeighbor ? +bottomNeighbor(1, 0) : 0, topNeighbor = bottomNeighbor ? +bottomNeighbor(0, -1) : 0;
638
+ 0 === leftNeighbor + rightNeighbor + topNeighbor + (bottomNeighbor = bottomNeighbor ? +bottomNeighbor(0, 1) : 0) || topNeighbor && !leftNeighbor && !rightNeighbor || bottomNeighbor && !leftNeighbor && !rightNeighbor ? this.basicDot({
639
+ x,
640
+ y,
641
+ size,
642
+ rotation: 0
643
+ }) : leftNeighbor && rightNeighbor ? this.basicSquare({
644
+ x,
645
+ y,
646
+ size,
647
+ rotation: 0
648
+ }) : leftNeighbor && !rightNeighbor ? this.basicSideRounded({
649
+ x,
650
+ y,
651
+ size,
652
+ rotation: 0
653
+ }) : rightNeighbor && !leftNeighbor && this.basicSideRounded({
654
+ x,
655
+ y,
656
+ size,
657
+ rotation: Math.PI
1051
658
  });
1052
659
  }
1053
- };
1054
-
1055
- function calculateImageSize({ originalHeight, originalWidth, maxHiddenDots, maxHiddenAxisDots, dotSize, margin }) {
1056
- const hideDots = { x: 0, y: 0 };
1057
- const imageSize = { x: 0, y: 0 };
1058
- if (originalHeight <= 0 ||
1059
- originalWidth <= 0 ||
1060
- maxHiddenDots <= 0 ||
1061
- dotSize <= 0 ||
1062
- 4 * margin ** 2 > maxHiddenDots) {
1063
- return {
1064
- height: 0,
1065
- width: 0,
1066
- hideYDots: 0,
1067
- hideXDots: 0
1068
- };
660
+ drawExtraRounded({x, y, size, getNeighbor: bottomNeighbor}) {
661
+ var leftNeighbor = bottomNeighbor ? +bottomNeighbor(-1, 0) : 0;
662
+ let rightNeighbor = bottomNeighbor ? +bottomNeighbor(1, 0) : 0, topNeighbor = bottomNeighbor ? +bottomNeighbor(0, -1) : 0;
663
+ var neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + (bottomNeighbor = bottomNeighbor ? +bottomNeighbor(0, 1) : 0);
664
+ 0 === neighborsCount ? this.basicDot({
665
+ x,
666
+ y,
667
+ size,
668
+ rotation: 0
669
+ }) : 2 < neighborsCount || leftNeighbor && rightNeighbor || topNeighbor && bottomNeighbor ? this.basicSquare({
670
+ x,
671
+ y,
672
+ size,
673
+ rotation: 0
674
+ }) : 2 === neighborsCount ? (neighborsCount = 0, leftNeighbor && topNeighbor ? neighborsCount = Math.PI / 2 : topNeighbor && rightNeighbor ? neighborsCount = Math.PI : rightNeighbor && bottomNeighbor && (neighborsCount = -Math.PI / 2),
675
+ this.basicCornerExtraRounded({
676
+ x,
677
+ y,
678
+ size,
679
+ rotation: neighborsCount
680
+ })) : 1 === neighborsCount && (leftNeighbor = 0, topNeighbor ? leftNeighbor = Math.PI / 2 : rightNeighbor ? leftNeighbor = Math.PI : bottomNeighbor && (leftNeighbor = -Math.PI / 2),
681
+ this.basicSideRounded({
682
+ x,
683
+ y,
684
+ size,
685
+ rotation: leftNeighbor
686
+ }));
687
+ }
688
+ drawClassy({x, y, size, getNeighbor: bottomNeighbor}) {
689
+ let leftNeighbor = bottomNeighbor ? +bottomNeighbor(-1, 0) : 0, rightNeighbor = bottomNeighbor ? +bottomNeighbor(1, 0) : 0, topNeighbor = bottomNeighbor ? +bottomNeighbor(0, -1) : 0;
690
+ 0 === leftNeighbor + rightNeighbor + topNeighbor + (bottomNeighbor = bottomNeighbor ? +bottomNeighbor(0, 1) : 0) ? this.basicCornersRounded({
691
+ x,
692
+ y,
693
+ size,
694
+ rotation: Math.PI / 2
695
+ }) : leftNeighbor || topNeighbor ? rightNeighbor || bottomNeighbor ? this.basicSquare({
696
+ x,
697
+ y,
698
+ size,
699
+ rotation: 0
700
+ }) : this.basicCornerRounded({
701
+ x,
702
+ y,
703
+ size,
704
+ rotation: Math.PI / 2
705
+ }) : this.basicCornerRounded({
706
+ x,
707
+ y,
708
+ size,
709
+ rotation: -Math.PI / 2
710
+ });
711
+ }
712
+ drawClassyRounded({x, y, size, getNeighbor: bottomNeighbor}) {
713
+ let leftNeighbor = bottomNeighbor ? +bottomNeighbor(-1, 0) : 0, rightNeighbor = bottomNeighbor ? +bottomNeighbor(1, 0) : 0, topNeighbor = bottomNeighbor ? +bottomNeighbor(0, -1) : 0;
714
+ 0 === leftNeighbor + rightNeighbor + topNeighbor + (bottomNeighbor = bottomNeighbor ? +bottomNeighbor(0, 1) : 0) ? this.basicCornersRounded({
715
+ x,
716
+ y,
717
+ size,
718
+ rotation: Math.PI / 2
719
+ }) : leftNeighbor || topNeighbor ? rightNeighbor || bottomNeighbor ? this.basicSquare({
720
+ x,
721
+ y,
722
+ size,
723
+ rotation: 0
724
+ }) : this.basicCornerExtraRounded({
725
+ x,
726
+ y,
727
+ size,
728
+ rotation: Math.PI / 2
729
+ }) : this.basicCornerExtraRounded({
730
+ x,
731
+ y,
732
+ size,
733
+ rotation: -Math.PI / 2
734
+ });
1069
735
  }
1070
- //If set, ensure maxHiddenAxisDots is odd and at least 1
1071
- if (maxHiddenAxisDots && maxHiddenAxisDots % 2 == 0)
1072
- maxHiddenAxisDots = Math.max(1, maxHiddenAxisDots - 1);
1073
- //Determine the bigger and smaller image dimension
1074
- const dimMax = Math.max(originalWidth, originalHeight);
1075
- const dimMin = Math.min(originalWidth, originalHeight);
1076
- //Find max image size along the bigger dimension
1077
- let lower = 0, upper = (maxHiddenAxisDots || maxHiddenDots) - 2 * margin;
1078
- do {
1079
- const size = lower + (upper - lower) / 2;
1080
- let dotsMax = Math.max(1, Math.ceil(size + 2 * margin));
1081
- if (dotsMax % 2 == 0)
1082
- dotsMax++;
1083
- let dotsMin = Math.max(1, Math.ceil((size * dimMin) / dimMax + 2 * margin));
1084
- if (dotsMin % 2 == 0)
1085
- dotsMin++;
1086
- if (dotsMax * dotsMin > maxHiddenDots)
1087
- upper = size;
1088
- else
1089
- lower = size;
1090
- } while (Math.abs(lower - upper) > 0.001);
1091
- //Calculate how many dots the given size corresponds to
1092
- const size = lower;
1093
- let hideMax = Math.max(1, Math.ceil(size + 2 * margin));
1094
- if (hideMax % 2 == 0)
1095
- hideMax++;
1096
- let hideMin = Math.max(1, Math.ceil((size * dimMin) / dimMax + 2 * margin));
1097
- if (hideMin % 2 == 0)
1098
- hideMin++;
1099
- //Set hidden dots along bigger and smaller dimension to the right axis
1100
- if (originalWidth > originalHeight) {
1101
- hideDots.x = hideMax;
1102
- hideDots.y = hideMin;
1103
- }
1104
- else {
1105
- hideDots.x = hideMin;
1106
- hideDots.y = hideMax;
1107
- }
1108
- //Fit image to the hidden dots
1109
- const maxW = (hideDots.x - 2 * margin) * dotSize;
1110
- const maxH = (hideDots.y - 2 * margin) * dotSize;
1111
- imageSize.x = maxW;
1112
- imageSize.y = (maxW * originalHeight) / originalWidth;
1113
- if (imageSize.y > maxH) {
1114
- imageSize.y = maxH;
1115
- imageSize.x = (maxH * originalWidth) / originalHeight;
1116
- }
1117
- return {
1118
- height: Math.round(imageSize.y + 2 * margin * dotSize),
1119
- width: Math.round(imageSize.x + 2 * margin * dotSize),
1120
- hideYDots: hideDots.y,
1121
- hideXDots: hideDots.x
1122
- };
1123
736
  }
1124
737
 
1125
- const squareMask = [
1126
- [1, 1, 1, 1, 1, 1, 1],
1127
- [1, 0, 0, 0, 0, 0, 1],
1128
- [1, 0, 0, 0, 0, 0, 1],
1129
- [1, 0, 0, 0, 0, 0, 1],
1130
- [1, 0, 0, 0, 0, 0, 1],
1131
- [1, 0, 0, 0, 0, 0, 1],
1132
- [1, 1, 1, 1, 1, 1, 1]
1133
- ];
1134
- const dotMask = [
1135
- [0, 0, 0, 0, 0, 0, 0],
1136
- [0, 0, 0, 0, 0, 0, 0],
1137
- [0, 0, 1, 1, 1, 0, 0],
1138
- [0, 0, 1, 1, 1, 0, 0],
1139
- [0, 0, 1, 1, 1, 0, 0],
1140
- [0, 0, 0, 0, 0, 0, 0],
1141
- [0, 0, 0, 0, 0, 0, 0]
1142
- ];
1143
- const alignmentCount = [
1144
- [35, 49],
1145
- [28, 36],
1146
- [21, 25],
1147
- [14, 16],
1148
- [7, 9],
1149
- [2, 4],
1150
- [1, 1]
1151
- ];
738
+ let browserImageTools = {
739
+ toDataURL: url => new Promise(((resolve, reject) => {
740
+ if ("string" == typeof url) {
741
+ const xhr = new XMLHttpRequest;
742
+ xhr.onload = function() {
743
+ const reader = new FileReader;
744
+ reader.onloadend = function() {
745
+ resolve(reader.result);
746
+ }, reader.readAsDataURL(xhr.response);
747
+ }, xhr.onerror = xhr.onabort = xhr.ontimeout = reject, xhr.open("GET", url), xhr.responseType = "blob",
748
+ xhr.send();
749
+ } else {
750
+ const reader = new FileReader;
751
+ reader.onloadend = function() {
752
+ resolve(reader.result);
753
+ }, reader.readAsDataURL(url);
754
+ }
755
+ })),
756
+ getSize: (src, crossOrigin) => new Promise(((resolve, reject) => {
757
+ const image = new Image;
758
+ "string" === crossOrigin && (image.crossOrigin = crossOrigin), image.onload = () => {
759
+ resolve({
760
+ width: image.width,
761
+ height: image.height
762
+ });
763
+ }, image.onerror = image.onabort = reject, "string" == typeof src ? image.src = src : browserImageTools.toDataURL(src).then((url => image.src = url)).catch(reject);
764
+ }))
765
+ };
766
+
767
+ let squareMask = [ [ 1, 1, 1, 1, 1, 1, 1 ], [ 1, 0, 0, 0, 0, 0, 1 ], [ 1, 0, 0, 0, 0, 0, 1 ], [ 1, 0, 0, 0, 0, 0, 1 ], [ 1, 0, 0, 0, 0, 0, 1 ], [ 1, 0, 0, 0, 0, 0, 1 ], [ 1, 1, 1, 1, 1, 1, 1 ] ], dotMask = [ [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 1, 1, 0, 0 ], [ 0, 0, 1, 1, 1, 0, 0 ], [ 0, 0, 1, 1, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ] ], alignmentCount = [ [ 35, 49 ], [ 28, 36 ], [ 21, 25 ], [ 14, 16 ], [ 7, 9 ], [ 2, 4 ], [ 1, 1 ] ];
768
+
1152
769
  class QRSVG {
1153
770
  get element() {
1154
771
  return this._element;
1155
772
  }
1156
773
  constructor(options) {
1157
- this.options = options;
1158
- this.document = options.document;
1159
- this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "svg");
1160
- this._element.setAttribute("width", String(options.width));
1161
- this._element.setAttribute("height", String(options.height));
1162
- this._element.setAttribute("viewBox", `0 0 ${options.width} ${options.height}`);
1163
- this.defs = this.document.createElementNS("http://www.w3.org/2000/svg", "defs");
1164
- this._element.appendChild(this.defs);
1165
- this.imageTools = options.imageTools || browserImageTools;
774
+ this.options = options, this.document = options.document, this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "svg");
775
+ let width = numToAttr(options.width), height = numToAttr(options.height);
776
+ this._element.setAttribute("width", width), this._element.setAttribute("height", height),
777
+ this._element.setAttribute("viewBox", `0 0 ${width} ${height}`), this.defs = this.document.createElementNS("http://www.w3.org/2000/svg", "defs"),
778
+ this._element.appendChild(this.defs), this.imageTools = options.imageTools || browserImageTools;
1166
779
  }
1167
780
  get width() {
1168
781
  return this.options.width;
@@ -1170,65 +783,68 @@ class QRSVG {
1170
783
  get height() {
1171
784
  return this.options.height;
1172
785
  }
1173
- async drawQR(qr) {
1174
- const count = qr.getModuleCount();
1175
- const typeNumber = parseInt(((count - 17) / 4).toFixed(0), 10);
1176
- const dotSize = this.options.dotsOptions.size;
1177
- let drawImageSize = {
786
+ async drawQR(qr_size) {
787
+ let count = qr_size.getModuleCount(), typeNumber = parseInt(((count - 17) / 4).toFixed(0), 10), dotSize = this.options.dotsOptions.size, drawImageSize = {
1178
788
  hideXDots: 0,
1179
789
  hideYDots: 0,
1180
790
  width: 0,
1181
791
  height: 0
1182
792
  };
1183
- this.qr = qr;
1184
- if (this.options.image) {
1185
- //We need it to get image size
1186
- const size = await this.imageTools.getSize(this.options.image, this.options.imageOptions.crossOrigin);
1187
- const { imageOptions, errorCorrectionPercent } = this.options;
1188
- const coverLevel = imageOptions.imageSize * errorCorrectionPercent;
1189
- const alignment = alignmentCount.find((v) => v[0] <= typeNumber) || [0, 0];
1190
- const maxHiddenDots = Math.floor(coverLevel * (count * count - 3 * 8 * 8 - 2 * (count - 16) - alignment[1] * 25));
1191
- drawImageSize = calculateImageSize({
1192
- originalWidth: size.width,
1193
- originalHeight: size.height,
1194
- maxHiddenDots,
793
+ if (this.qr = qr_size, this.options.image) {
794
+ qr_size = await this.imageTools.getSize(this.options.image, this.options.imageOptions.crossOrigin);
795
+ let {imageOptions, errorCorrectionPercent} = this.options, coverLevel = imageOptions.imageSize * errorCorrectionPercent, alignment = alignmentCount.find((v => v[0] <= typeNumber)) || [ 0, 0 ];
796
+ drawImageSize = function({originalHeight, originalWidth, maxHiddenDots: JSCompiler_object_inline_x_18_hideMax_maxHiddenDots, maxHiddenAxisDots: JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper, dotSize, margin}) {
797
+ if (0 >= originalHeight || 0 >= originalWidth || 0 >= JSCompiler_object_inline_x_18_hideMax_maxHiddenDots || 0 >= dotSize || 4 * margin ** 2 > JSCompiler_object_inline_x_18_hideMax_maxHiddenDots) return {
798
+ height: 0,
799
+ width: 0,
800
+ hideYDots: 0,
801
+ hideXDots: 0
802
+ };
803
+ JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper && 0 == JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper % 2 && (JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper = Math.max(1, JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper - 1));
804
+ var JSCompiler_object_inline_x_16_dimMax = Math.max(originalWidth, originalHeight), JSCompiler_object_inline_y_17_dimMin_hideMin = Math.min(originalWidth, originalHeight), lower_maxH_size = 0;
805
+ JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper = (JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper || JSCompiler_object_inline_x_18_hideMax_maxHiddenDots) - 2 * margin;
806
+ do {
807
+ let size = lower_maxH_size + (JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper - lower_maxH_size) / 2, dotsMax = Math.max(1, Math.ceil(size + 2 * margin));
808
+ 0 == dotsMax % 2 && dotsMax++;
809
+ let dotsMin = Math.max(1, Math.ceil(size * JSCompiler_object_inline_y_17_dimMin_hideMin / JSCompiler_object_inline_x_16_dimMax + 2 * margin));
810
+ 0 == dotsMin % 2 && dotsMin++, dotsMax * dotsMin > JSCompiler_object_inline_x_18_hideMax_maxHiddenDots ? JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper = size : lower_maxH_size = size;
811
+ } while (.001 < Math.abs(lower_maxH_size - JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper));
812
+ return 0 == (JSCompiler_object_inline_x_18_hideMax_maxHiddenDots = Math.max(1, Math.ceil(lower_maxH_size + 2 * margin))) % 2 && JSCompiler_object_inline_x_18_hideMax_maxHiddenDots++,
813
+ 0 == (JSCompiler_object_inline_y_17_dimMin_hideMin = Math.max(1, Math.ceil(lower_maxH_size * JSCompiler_object_inline_y_17_dimMin_hideMin / JSCompiler_object_inline_x_16_dimMax + 2 * margin))) % 2 && JSCompiler_object_inline_y_17_dimMin_hideMin++,
814
+ originalWidth > originalHeight ? JSCompiler_object_inline_x_16_dimMax = JSCompiler_object_inline_x_18_hideMax_maxHiddenDots : (JSCompiler_object_inline_x_16_dimMax = JSCompiler_object_inline_y_17_dimMin_hideMin,
815
+ JSCompiler_object_inline_y_17_dimMin_hideMin = JSCompiler_object_inline_x_18_hideMax_maxHiddenDots),
816
+ JSCompiler_object_inline_x_18_hideMax_maxHiddenDots = JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper = (JSCompiler_object_inline_x_16_dimMax - 2 * margin) * dotSize,
817
+ (JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper = JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper * originalHeight / originalWidth) > (lower_maxH_size = (JSCompiler_object_inline_y_17_dimMin_hideMin - 2 * margin) * dotSize) && (JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper = lower_maxH_size,
818
+ JSCompiler_object_inline_x_18_hideMax_maxHiddenDots = lower_maxH_size * originalWidth / originalHeight),
819
+ {
820
+ height: Math.round(JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper + 2 * margin * dotSize),
821
+ width: Math.round(JSCompiler_object_inline_x_18_hideMax_maxHiddenDots + 2 * margin * dotSize),
822
+ hideYDots: JSCompiler_object_inline_y_17_dimMin_hideMin,
823
+ hideXDots: JSCompiler_object_inline_x_16_dimMax
824
+ };
825
+ }({
826
+ originalWidth: qr_size.width,
827
+ originalHeight: qr_size.height,
828
+ maxHiddenDots: Math.floor(coverLevel * (count * count - 192 - 2 * (count - 16) - 25 * alignment[1])),
1195
829
  maxHiddenAxisDots: count - 14,
1196
830
  dotSize,
1197
831
  margin: imageOptions.margin
1198
832
  });
1199
833
  }
1200
- this.drawBackground();
1201
- this.drawDots((i, j) => {
1202
- if (this.options.imageOptions.hideBackgroundDots) {
1203
- if (i >= (count - drawImageSize.hideXDots) / 2 &&
1204
- i < (count + drawImageSize.hideXDots) / 2 &&
1205
- j >= (count - drawImageSize.hideYDots) / 2 &&
1206
- j < (count + drawImageSize.hideYDots) / 2) {
1207
- return false;
1208
- }
1209
- }
1210
- if (squareMask[i]?.[j] || squareMask[i - count + 7]?.[j] || squareMask[i]?.[j - count + 7]) {
1211
- return false;
1212
- }
1213
- if (dotMask[i]?.[j] || dotMask[i - count + 7]?.[j] || dotMask[i]?.[j - count + 7]) {
1214
- return false;
1215
- }
1216
- return true;
834
+ this.drawBackground(), this.drawDots(((i, j) => !(this.options.imageOptions.hideBackgroundDots && i >= (count - drawImageSize.hideXDots) / 2 && i < (count + drawImageSize.hideXDots) / 2 && j >= (count - drawImageSize.hideYDots) / 2 && j < (count + drawImageSize.hideYDots) / 2 || squareMask[i]?.[j] || squareMask[i - count + 7]?.[j] || squareMask[i]?.[j - count + 7] || dotMask[i]?.[j] || dotMask[i - count + 7]?.[j] || dotMask[i]?.[j - count + 7]))),
835
+ this.drawCorners(), this.options.image && 0 < drawImageSize.width && 0 < drawImageSize.height && await this.drawImage({
836
+ width: drawImageSize.width,
837
+ height: drawImageSize.height,
838
+ count,
839
+ dotSize
1217
840
  });
1218
- this.drawCorners();
1219
- if (this.options.image && drawImageSize.width > 0 && drawImageSize.height > 0) {
1220
- await this.drawImage({ width: drawImageSize.width, height: drawImageSize.height, count, dotSize });
1221
- }
1222
841
  }
1223
842
  drawBackground() {
1224
- const element = this._element;
1225
- const options = this.options;
1226
- if (element && options.backgroundOptions) {
1227
- const gradientOptions = options.backgroundOptions.gradient;
1228
- const color = options.backgroundOptions.color;
843
+ let options = this.options;
844
+ if (this._element && options.backgroundOptions) {
1229
845
  this.createColor({
1230
- options: gradientOptions,
1231
- color: color,
846
+ options: options.backgroundOptions.gradient,
847
+ color: options.backgroundOptions.color,
1232
848
  additionalRotation: 0,
1233
849
  x: 0,
1234
850
  y: 0,
@@ -1236,110 +852,46 @@ class QRSVG {
1236
852
  width: options.width,
1237
853
  name: "background-color"
1238
854
  });
1239
- const size = Math.min(options.width, options.height);
1240
- const element = this.document.createElementNS("http://www.w3.org/2000/svg", "rect");
1241
- [this.backgroundMask, this.backgroundMaskGroup] = this.createMask("mask-background-color");
1242
- this.defs.appendChild(this.backgroundMask);
1243
- element.setAttribute("x", String((options.width - size) / 2));
1244
- element.setAttribute("y", String((options.height - size) / 2));
1245
- element.setAttribute("width", String(size));
1246
- element.setAttribute("height", String(size));
1247
- element.setAttribute("rx", String((size / 2) * (options.backgroundOptions.round || 0)));
855
+ let size = Math.min(options.width, options.height), element = this.document.createElementNS("http://www.w3.org/2000/svg", "rect");
856
+ [this.backgroundMask, this.backgroundMaskGroup] = this.createMask("mask-background-color"),
857
+ this.defs.appendChild(this.backgroundMask), element.setAttribute("x", numToAttr((options.width - size) / 2)),
858
+ element.setAttribute("y", numToAttr((options.height - size) / 2)), element.setAttribute("width", numToAttr(size)),
859
+ element.setAttribute("height", numToAttr(size)), element.setAttribute("rx", numToAttr(size / 2 * (options.backgroundOptions.round || 0))),
1248
860
  this.backgroundMaskGroup.appendChild(element);
1249
861
  }
1250
862
  }
1251
863
  drawDots(filter) {
1252
- if (!this.qr) {
1253
- throw "QR code is not defined";
1254
- }
1255
- const options = this.options;
1256
- const count = this.qr.getModuleCount();
1257
- if (count > options.width || count > options.height) {
1258
- throw "The canvas is too small.";
1259
- }
1260
- const minSize = Math.min(options.width, options.height);
1261
- const dotSize = this.options.dotsOptions.size;
1262
- const xBeginning = Math.floor((options.width - count * dotSize) / 2);
1263
- const yBeginning = Math.floor((options.height - count * dotSize) / 2);
1264
- const dot = new QRDot(options.dotsOptions.type, this.document);
1265
- [this.dotsMask, this.dotsMaskGroup] = this.createMask("mask-dot-color");
1266
- this.defs.appendChild(this.dotsMask);
1267
- for (let i = 0; i < count; i++) {
1268
- for (let j = 0; j < count; j++) {
1269
- if (filter && !filter(i, j)) {
1270
- continue;
1271
- }
1272
- if (!this.qr?.isDark(j, i)) {
1273
- continue;
1274
- }
1275
- dot.draw({
1276
- x: xBeginning + i * dotSize,
1277
- y: yBeginning + j * dotSize,
1278
- size: dotSize,
1279
- getNeighbor: (xOffset, yOffset) => {
1280
- if (i + xOffset < 0 || j + yOffset < 0 || i + xOffset >= count || j + yOffset >= count)
1281
- return false;
1282
- if (filter && !filter(i + xOffset, j + yOffset))
1283
- return false;
1284
- return !!this.qr && this.qr.isDark(j + yOffset, i + xOffset);
1285
- }
1286
- });
1287
- if (dot.element && this.dotsMask) {
1288
- this.dotsMaskGroup.appendChild(dot.element);
1289
- }
1290
- }
1291
- }
1292
- let colorX = xBeginning;
1293
- let colorY = yBeginning;
1294
- let colorCount = count;
864
+ if (!this.qr) throw "QR code is not defined";
865
+ let options = this.options, count = this.qr.getModuleCount();
866
+ if (count > options.width || count > options.height) throw "The canvas is too small.";
867
+ var additionalDots_minSize = Math.min(options.width, options.height);
868
+ let dotSize = this.options.dotsOptions.size;
869
+ var xBeginning_xFakeBeginning = Math.floor((options.width - count * dotSize) / 2), yBeginning_yFakeBeginning = Math.floor((options.height - count * dotSize) / 2);
870
+ let dot = new QRDot(options.dotsOptions.type, this.document);
871
+ [this.dotsMask, this.dotsMaskGroup] = this.createMask("mask-dot-color"), this.defs.appendChild(this.dotsMask);
872
+ for (let i = 0; i < count; i++) for (let j = 0; j < count; j++) filter && !filter(i, j) || !this.qr?.isDark(j, i) || (dot.draw({
873
+ x: xBeginning_xFakeBeginning + i * dotSize,
874
+ y: yBeginning_yFakeBeginning + j * dotSize,
875
+ size: dotSize,
876
+ getNeighbor: (xOffset, yOffset) => !(0 > i + xOffset || 0 > j + yOffset || i + xOffset >= count || j + yOffset >= count || filter && !filter(i + xOffset, j + yOffset)) && (!!this.qr && this.qr.isDark(j + yOffset, i + xOffset))
877
+ }), dot.element && this.dotsMask && this.dotsMaskGroup.appendChild(dot.element));
878
+ let colorX = xBeginning_xFakeBeginning, colorY = yBeginning_yFakeBeginning, colorCount = count;
1295
879
  if (options.shape === ShapeType.circle) {
1296
- const margin = (this.options.backgroundOptions && this.options.backgroundOptions.margin) || 0;
1297
- const additionalDots = Math.floor((minSize / dotSize - count - 2 * margin) / 2);
1298
- const fakeCount = count + additionalDots * 2;
1299
- const xFakeBeginning = xBeginning - additionalDots * dotSize;
1300
- const yFakeBeginning = yBeginning - additionalDots * dotSize;
1301
- colorX = xFakeBeginning;
1302
- colorY = yFakeBeginning;
1303
- colorCount = count + additionalDots * 2;
1304
- const fakeMatrix = [];
1305
- const center = Math.floor(fakeCount / 2);
880
+ additionalDots_minSize = Math.floor((additionalDots_minSize / dotSize - count - 2 * (this.options.backgroundOptions && this.options.backgroundOptions.margin || 0)) / 2);
881
+ let fakeCount = count + 2 * additionalDots_minSize;
882
+ colorX = xBeginning_xFakeBeginning -= additionalDots_minSize * dotSize, colorY = yBeginning_yFakeBeginning -= additionalDots_minSize * dotSize,
883
+ colorCount = count + 2 * additionalDots_minSize;
884
+ let fakeMatrix = [], center = Math.floor(fakeCount / 2);
1306
885
  for (let i = 0; i < fakeCount; i++) {
1307
886
  fakeMatrix[i] = [];
1308
- for (let j = 0; j < fakeCount; j++) {
1309
- if (i >= additionalDots - 1 &&
1310
- i <= fakeCount - additionalDots &&
1311
- j >= additionalDots - 1 &&
1312
- j <= fakeCount - additionalDots) {
1313
- fakeMatrix[i][j] = 0;
1314
- continue;
1315
- }
1316
- if (Math.sqrt((i - center) * (i - center) + (j - center) * (j - center)) > center) {
1317
- fakeMatrix[i][j] = 0;
1318
- continue;
1319
- }
1320
- //Get random dots from QR code to show it outside of QR code
1321
- fakeMatrix[i][j] = this.qr.isDark(j - 2 * additionalDots < 0 ? j : j >= count ? j - 2 * additionalDots : j - additionalDots, i - 2 * additionalDots < 0 ? i : i >= count ? i - 2 * additionalDots : i - additionalDots)
1322
- ? 1
1323
- : 0;
1324
- }
1325
- }
1326
- for (let i = 0; i < fakeCount; i++) {
1327
- for (let j = 0; j < fakeCount; j++) {
1328
- if (!fakeMatrix[i][j])
1329
- continue;
1330
- dot.draw({
1331
- x: xFakeBeginning + i * dotSize,
1332
- y: yFakeBeginning + j * dotSize,
1333
- size: dotSize,
1334
- getNeighbor: (xOffset, yOffset) => {
1335
- return !!fakeMatrix[i + xOffset]?.[j + yOffset];
1336
- }
1337
- });
1338
- if (dot.element && this.dotsMask) {
1339
- this.dotsMaskGroup.appendChild(dot.element);
1340
- }
1341
- }
887
+ for (let j = 0; j < fakeCount; j++) fakeMatrix[i][j] = i >= additionalDots_minSize - 1 && i <= fakeCount - additionalDots_minSize && j >= additionalDots_minSize - 1 && j <= fakeCount - additionalDots_minSize || Math.sqrt((i - center) * (i - center) + (j - center) * (j - center)) > center ? 0 : this.qr.isDark(0 > j - 2 * additionalDots_minSize ? j : j >= count ? j - 2 * additionalDots_minSize : j - additionalDots_minSize, 0 > i - 2 * additionalDots_minSize ? i : i >= count ? i - 2 * additionalDots_minSize : i - additionalDots_minSize) ? 1 : 0;
1342
888
  }
889
+ for (let i = 0; i < fakeCount; i++) for (let j = 0; j < fakeCount; j++) fakeMatrix[i][j] && (dot.draw({
890
+ x: xBeginning_xFakeBeginning + i * dotSize,
891
+ y: yBeginning_yFakeBeginning + j * dotSize,
892
+ size: dotSize,
893
+ getNeighbor: (xOffset, yOffset) => !!fakeMatrix[i + xOffset]?.[j + yOffset]
894
+ }), dot.element && this.dotsMask && this.dotsMaskGroup.appendChild(dot.element));
1343
895
  }
1344
896
  this.createColor({
1345
897
  options: options.dotsOptions?.gradient,
@@ -1353,437 +905,227 @@ class QRSVG {
1353
905
  });
1354
906
  }
1355
907
  drawCorners() {
1356
- if (!this.qr) {
1357
- throw "QR code is not defined";
1358
- }
1359
- const element = this._element;
1360
- const options = this.options;
1361
- if (!element) {
1362
- throw "Element code is not defined";
1363
- }
1364
- const count = this.qr.getModuleCount();
1365
- const dotSize = this.options.dotsOptions.size;
1366
- const cornersSquareSize = dotSize * 7;
1367
- const cornersDotSize = dotSize * 3;
1368
- const xBeginning = Math.floor((options.width - count * dotSize) / 2);
1369
- const yBeginning = Math.floor((options.height - count * dotSize) / 2);
1370
- [
1371
- [0, 0, 0],
1372
- [1, 0, Math.PI / 2],
1373
- [0, 1, -Math.PI / 2]
1374
- ].forEach(([column, row, rotation]) => {
1375
- const x = xBeginning + column * dotSize * (count - 7);
1376
- const y = yBeginning + row * dotSize * (count - 7);
1377
- let cornersSquareMask = this.dotsMask;
908
+ if (!this.qr) throw "QR code is not defined";
909
+ let options = this.options;
910
+ if (!this._element) throw "Element code is not defined";
911
+ let count = this.qr.getModuleCount(), dotSize = this.options.dotsOptions.size, cornersSquareSize = 7 * dotSize, cornersDotSize = 3 * dotSize, xBeginning = Math.floor((options.width - count * dotSize) / 2), yBeginning = Math.floor((options.height - count * dotSize) / 2);
912
+ [ [ 0, 0, 0 ], [ 1, 0, Math.PI / 2 ], [ 0, 1, -Math.PI / 2 ] ].forEach((([column_cornersDot, row, dot]) => {
913
+ let x = xBeginning + column_cornersDot * dotSize * (count - 7), y = yBeginning + row * dotSize * (count - 7);
914
+ var cornersDotMaskGroup_cornersSquareMask = this.dotsMask;
1378
915
  let cornersSquareMaskGroup = this.dotsMaskGroup;
1379
- let cornersDotMask = this.dotsMask;
1380
- let cornersDotMaskGroup = this.dotsMaskGroup;
1381
- if (options.cornersSquareOptions?.gradient || options.cornersSquareOptions?.color) {
1382
- [cornersSquareMask, cornersSquareMaskGroup] = this.createMask(`mask-corners-square-color-${column}-${row}`);
1383
- this.defs.appendChild(cornersSquareMask);
1384
- cornersDotMask = cornersSquareMask;
1385
- cornersDotMaskGroup = cornersSquareMaskGroup;
1386
- this.createColor({
1387
- options: options.cornersSquareOptions?.gradient,
1388
- color: options.cornersSquareOptions?.color,
1389
- additionalRotation: rotation,
1390
- x,
1391
- y,
1392
- height: cornersSquareSize,
1393
- width: cornersSquareSize,
1394
- name: `corners-square-color-${column}-${row}`
1395
- });
1396
- }
1397
- if (options.cornersSquareOptions?.type) {
1398
- const cornersSquare = new QRCornerSquare(options.cornersSquareOptions.type, this.document);
1399
- cornersSquare.draw({
1400
- x,
1401
- y,
1402
- size: cornersSquareSize,
1403
- rotation
1404
- });
1405
- if (cornersSquare.element && cornersSquareMaskGroup) {
1406
- cornersSquareMaskGroup.appendChild(cornersSquare.element);
1407
- }
1408
- }
1409
- else {
1410
- const dot = new QRDot(options.dotsOptions.type, this.document);
1411
- for (let i = 0; i < squareMask.length; i++) {
1412
- for (let j = 0; j < squareMask[i].length; j++) {
1413
- if (!squareMask[i]?.[j]) {
1414
- continue;
1415
- }
1416
- dot.draw({
1417
- x: x + i * dotSize,
1418
- y: y + j * dotSize,
1419
- size: dotSize,
1420
- getNeighbor: (xOffset, yOffset) => !!squareMask[i + xOffset]?.[j + yOffset]
1421
- });
1422
- if (dot.element && cornersSquareMaskGroup) {
1423
- cornersSquareMaskGroup.appendChild(dot.element);
1424
- }
1425
- }
1426
- }
1427
- }
1428
- if (options.cornersDotOptions?.gradient || options.cornersDotOptions?.color) {
1429
- [cornersDotMask, cornersDotMaskGroup] = this.createMask(`mask-corners-dot-color-${column}-${row}`);
1430
- this.defs.appendChild(cornersDotMask);
1431
- this.createColor({
1432
- options: options.cornersDotOptions?.gradient,
1433
- color: options.cornersDotOptions?.color,
1434
- additionalRotation: rotation,
1435
- x: x + dotSize * 2,
1436
- y: y + dotSize * 2,
1437
- height: cornersDotSize,
1438
- width: cornersDotSize,
1439
- name: `corners-dot-color-${column}-${row}`
1440
- });
1441
- }
1442
- if (options.cornersDotOptions?.type) {
1443
- const cornersDot = new QRCornerDot(options.cornersDotOptions.type, this.document);
1444
- cornersDot.draw({
1445
- x: x + dotSize * 2,
1446
- y: y + dotSize * 2,
1447
- size: cornersDotSize,
1448
- rotation
1449
- });
1450
- if (cornersDot.element && cornersDotMaskGroup) {
1451
- cornersDotMaskGroup.appendChild(cornersDot.element);
1452
- }
1453
- }
1454
- else {
1455
- const dot = new QRDot(options.dotsOptions.type, this.document);
1456
- for (let i = 0; i < dotMask.length; i++) {
1457
- for (let j = 0; j < dotMask[i].length; j++) {
1458
- if (!dotMask[i]?.[j]) {
1459
- continue;
1460
- }
1461
- dot.draw({
1462
- x: x + i * dotSize,
1463
- y: y + j * dotSize,
1464
- size: dotSize,
1465
- getNeighbor: (xOffset, yOffset) => !!dotMask[i + xOffset]?.[j + yOffset]
1466
- });
1467
- if (dot.element && cornersDotMaskGroup) {
1468
- cornersDotMaskGroup.appendChild(dot.element);
1469
- }
1470
- }
1471
- }
1472
- }
1473
- });
1474
- }
1475
- async drawImage({ width, height, count, dotSize }) {
1476
- const options = this.options;
1477
- const xBeginning = Math.floor((options.width - count * dotSize) / 2);
1478
- const yBeginning = Math.floor((options.height - count * dotSize) / 2);
1479
- const margin = options.imageOptions.margin * dotSize;
1480
- const dx = xBeginning + margin + (count * dotSize - width) / 2;
1481
- const dy = yBeginning + margin + (count * dotSize - height) / 2;
1482
- const dw = width - margin * 2;
1483
- const dh = height - margin * 2;
1484
- const imageUrl = await this.imageTools.toDataURL(options.image || "");
1485
- let image = this.document.createElementNS("http://www.w3.org/2000/svg", "image");
1486
- image.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", imageUrl || "");
1487
- if (imageUrl.startsWith("data:image/svg+xml;")) {
1488
- let data = imageUrl.substring(19);
1489
- const i = data.indexOf(",");
1490
- const encoding = data.substring(0, i);
1491
- data = data.substring(i + 1);
1492
- switch (encoding) {
1493
- case "base64":
1494
- data = typeof atob == "function" ? atob(data) : Buffer.from(data, "base64").toString("utf8");
1495
- break;
1496
- default:
1497
- data = "";
1498
- break;
916
+ var cornersDotMask_cornersSquare_dot = this.dotsMask;
917
+ if (cornersDotMaskGroup_cornersSquareMask = this.dotsMaskGroup, (options.cornersSquareOptions?.gradient || options.cornersSquareOptions?.color) && ([cornersDotMaskGroup_cornersSquareMask, cornersSquareMaskGroup] = this.createMask(`mask-corners-square-color-${column_cornersDot}-${row}`),
918
+ this.defs.appendChild(cornersDotMaskGroup_cornersSquareMask), cornersDotMask_cornersSquare_dot = cornersDotMaskGroup_cornersSquareMask,
919
+ cornersDotMaskGroup_cornersSquareMask = cornersSquareMaskGroup, this.createColor({
920
+ options: options.cornersSquareOptions?.gradient,
921
+ color: options.cornersSquareOptions?.color,
922
+ additionalRotation: dot,
923
+ x,
924
+ y,
925
+ height: cornersSquareSize,
926
+ width: cornersSquareSize,
927
+ name: `corners-square-color-${column_cornersDot}-${row}`
928
+ })), options.cornersSquareOptions?.type) (cornersDotMask_cornersSquare_dot = new QRCornerSquare(options.cornersSquareOptions.type, this.document)).draw({
929
+ x,
930
+ y,
931
+ size: cornersSquareSize,
932
+ rotation: dot
933
+ }), cornersDotMask_cornersSquare_dot.element && cornersSquareMaskGroup && cornersSquareMaskGroup.appendChild(cornersDotMask_cornersSquare_dot.element); else {
934
+ cornersDotMask_cornersSquare_dot = new QRDot(options.dotsOptions.type, this.document);
935
+ for (let i = 0; i < squareMask.length; i++) for (let j = 0; j < squareMask[i].length; j++) squareMask[i]?.[j] && (cornersDotMask_cornersSquare_dot.draw({
936
+ x: x + i * dotSize,
937
+ y: y + j * dotSize,
938
+ size: dotSize,
939
+ getNeighbor: (xOffset, yOffset) => !!squareMask[i + xOffset]?.[j + yOffset]
940
+ }), cornersDotMask_cornersSquare_dot.element && cornersSquareMaskGroup && cornersSquareMaskGroup.appendChild(cornersDotMask_cornersSquare_dot.element));
1499
941
  }
1500
- if (data) {
1501
- const container = new DOMParser().parseFromString(data, "text/xml");
1502
- const rootEl = Array.from(container.getElementsByTagName("svg"));
1503
- if (rootEl.length)
1504
- image = rootEl[0];
942
+ if ((options.cornersDotOptions?.gradient || options.cornersDotOptions?.color) && ([cornersDotMask_cornersSquare_dot, cornersDotMaskGroup_cornersSquareMask] = this.createMask(`mask-corners-dot-color-${column_cornersDot}-${row}`),
943
+ this.defs.appendChild(cornersDotMask_cornersSquare_dot), this.createColor({
944
+ options: options.cornersDotOptions?.gradient,
945
+ color: options.cornersDotOptions?.color,
946
+ additionalRotation: dot,
947
+ x: x + 2 * dotSize,
948
+ y: y + 2 * dotSize,
949
+ height: cornersDotSize,
950
+ width: cornersDotSize,
951
+ name: `corners-dot-color-${column_cornersDot}-${row}`
952
+ })), options.cornersDotOptions?.type) (column_cornersDot = new QRCornerDot(options.cornersDotOptions.type, this.document)).draw({
953
+ x: x + 2 * dotSize,
954
+ y: y + 2 * dotSize,
955
+ size: cornersDotSize,
956
+ rotation: dot
957
+ }), column_cornersDot.element && cornersDotMaskGroup_cornersSquareMask && cornersDotMaskGroup_cornersSquareMask.appendChild(column_cornersDot.element); else {
958
+ dot = new QRDot(options.dotsOptions.type, this.document);
959
+ for (let i = 0; i < dotMask.length; i++) for (let j = 0; j < dotMask[i].length; j++) dotMask[i]?.[j] && (dot.draw({
960
+ x: x + i * dotSize,
961
+ y: y + j * dotSize,
962
+ size: dotSize,
963
+ getNeighbor: (xOffset, yOffset) => !!dotMask[i + xOffset]?.[j + yOffset]
964
+ }), dot.element && cornersDotMaskGroup_cornersSquareMask && cornersDotMaskGroup_cornersSquareMask.appendChild(dot.element));
1505
965
  }
966
+ }));
967
+ }
968
+ async drawImage({width: dw_width, height: dh_height, count, dotSize}) {
969
+ var image = this.options, container_data = image.imageOptions.margin * dotSize;
970
+ let dx = Math.floor((image.width - count * dotSize) / 2) + container_data + (count * dotSize - dw_width) / 2;
971
+ if (count = Math.floor((image.height - count * dotSize) / 2) + container_data + (count * dotSize - dh_height) / 2,
972
+ dw_width -= 2 * container_data, dh_height -= 2 * container_data, container_data = await this.imageTools.toDataURL(image.image || ""),
973
+ (image = this.document.createElementNS("http://www.w3.org/2000/svg", "image")).setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", container_data || ""),
974
+ container_data.startsWith("data:image/svg+xml;")) {
975
+ dotSize = (container_data = container_data.substring(19)).indexOf(",");
976
+ let encoding = container_data.substring(0, dotSize);
977
+ if (container_data = container_data.substring(dotSize + 1), "base64" === encoding) container_data = "function" == typeof atob ? atob(container_data) : Buffer.from(container_data, "base64").toString("utf8"); else container_data = "";
978
+ container_data && (container_data = (new DOMParser).parseFromString(container_data, "text/xml"),
979
+ (container_data = Array.from(container_data.getElementsByTagName("svg"))).length && (image = container_data[0]));
1506
980
  }
1507
- image.setAttribute("x", String(dx));
1508
- image.setAttribute("y", String(dy));
1509
- image.setAttribute("width", `${dw}px`);
1510
- image.setAttribute("height", `${dh}px`);
981
+ image.setAttribute("x", numToAttr(dx)), image.setAttribute("y", numToAttr(count)),
982
+ image.setAttribute("width", `${numToAttr(dw_width)}px`), image.setAttribute("height", `${numToAttr(dh_height)}px`),
1511
983
  this._element.appendChild(image);
1512
984
  }
1513
- createColor({ options, color, additionalRotation, x, y, height, width, name }) {
1514
- const size = width > height ? width : height;
1515
- const rect = this.document.createElementNS("http://www.w3.org/2000/svg", "rect");
1516
- rect.setAttribute("x", String(x));
1517
- rect.setAttribute("y", String(y));
1518
- rect.setAttribute("height", String(height));
1519
- rect.setAttribute("width", String(width));
1520
- rect.setAttribute("style", `mask:url(#mask-${name})`);
1521
- if (options) {
985
+ createColor({options, color, additionalRotation: additionalRotation_positiveRotation, x, y, height, width, name}) {
986
+ var size = width > height ? width : height;
987
+ let rect = this.document.createElementNS("http://www.w3.org/2000/svg", "rect");
988
+ if (rect.setAttribute("x", numToAttr(x)), rect.setAttribute("y", numToAttr(y)),
989
+ rect.setAttribute("height", numToAttr(height)), rect.setAttribute("width", numToAttr(width)),
990
+ rect.setAttribute("style", `mask:url(#mask-${name})`), options) {
1522
991
  let gradient;
1523
- if (options.type === GradientType.radial) {
1524
- gradient = this.document.createElementNS("http://www.w3.org/2000/svg", "radialGradient");
1525
- gradient.setAttribute("id", name);
1526
- gradient.setAttribute("gradientUnits", "userSpaceOnUse");
1527
- gradient.setAttribute("fx", String(x + width / 2));
1528
- gradient.setAttribute("fy", String(y + height / 2));
1529
- gradient.setAttribute("cx", String(x + width / 2));
1530
- gradient.setAttribute("cy", String(y + height / 2));
1531
- gradient.setAttribute("r", String(size / 2));
1532
- }
1533
- else {
1534
- const rotation = ((options.rotation || 0) + additionalRotation) % (2 * Math.PI);
1535
- const positiveRotation = (rotation + 2 * Math.PI) % (2 * Math.PI);
1536
- let x0 = x + width / 2;
992
+ if (options.type === GradientType.radial) gradient = this.document.createElementNS("http://www.w3.org/2000/svg", "radialGradient"),
993
+ gradient.setAttribute("id", name), gradient.setAttribute("gradientUnits", "userSpaceOnUse"),
994
+ gradient.setAttribute("fx", numToAttr(x + width / 2)), gradient.setAttribute("fy", numToAttr(y + height / 2)),
995
+ gradient.setAttribute("cx", numToAttr(x + width / 2)), gradient.setAttribute("cy", numToAttr(y + height / 2)),
996
+ gradient.setAttribute("r", numToAttr(size / 2)); else {
997
+ size = x + width / 2;
1537
998
  let y0 = y + height / 2;
1538
- let x1 = x + width / 2;
1539
- let y1 = y + height / 2;
1540
- if ((positiveRotation >= 0 && positiveRotation <= 0.25 * Math.PI) ||
1541
- (positiveRotation > 1.75 * Math.PI && positiveRotation <= 2 * Math.PI)) {
1542
- x0 = x0 - width / 2;
1543
- y0 = y0 - (height / 2) * Math.tan(rotation);
1544
- x1 = x1 + width / 2;
1545
- y1 = y1 + (height / 2) * Math.tan(rotation);
1546
- }
1547
- else if (positiveRotation > 0.25 * Math.PI && positiveRotation <= 0.75 * Math.PI) {
1548
- y0 = y0 - height / 2;
1549
- x0 = x0 - width / 2 / Math.tan(rotation);
1550
- y1 = y1 + height / 2;
1551
- x1 = x1 + width / 2 / Math.tan(rotation);
1552
- }
1553
- else if (positiveRotation > 0.75 * Math.PI && positiveRotation <= 1.25 * Math.PI) {
1554
- x0 = x0 + width / 2;
1555
- y0 = y0 + (height / 2) * Math.tan(rotation);
1556
- x1 = x1 - width / 2;
1557
- y1 = y1 - (height / 2) * Math.tan(rotation);
1558
- }
1559
- else if (positiveRotation > 1.25 * Math.PI && positiveRotation <= 1.75 * Math.PI) {
1560
- y0 = y0 + height / 2;
1561
- x0 = x0 + width / 2 / Math.tan(rotation);
1562
- y1 = y1 - height / 2;
1563
- x1 = x1 - width / 2 / Math.tan(rotation);
1564
- }
1565
- gradient = this.document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
1566
- gradient.setAttribute("id", name);
1567
- gradient.setAttribute("gradientUnits", "userSpaceOnUse");
1568
- gradient.setAttribute("x1", String(Math.round(x0)));
1569
- gradient.setAttribute("y1", String(Math.round(y0)));
1570
- gradient.setAttribute("x2", String(Math.round(x1)));
1571
- gradient.setAttribute("y2", String(Math.round(y1)));
999
+ x += width / 2, y += height / 2, 0 <= (additionalRotation_positiveRotation = ((color = ((options.rotation || 0) + additionalRotation_positiveRotation) % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI)) && additionalRotation_positiveRotation <= .25 * Math.PI || additionalRotation_positiveRotation > 1.75 * Math.PI && additionalRotation_positiveRotation <= 2 * Math.PI ? (size -= width / 2,
1000
+ y0 -= height / 2 * Math.tan(color), x += width / 2, y += height / 2 * Math.tan(color)) : additionalRotation_positiveRotation > .25 * Math.PI && additionalRotation_positiveRotation <= .75 * Math.PI ? (y0 -= height / 2,
1001
+ size -= width / 2 / Math.tan(color), y += height / 2, x += width / 2 / Math.tan(color)) : additionalRotation_positiveRotation > .75 * Math.PI && additionalRotation_positiveRotation <= 1.25 * Math.PI ? (size += width / 2,
1002
+ y0 += height / 2 * Math.tan(color), x -= width / 2, y -= height / 2 * Math.tan(color)) : additionalRotation_positiveRotation > 1.25 * Math.PI && additionalRotation_positiveRotation <= 1.75 * Math.PI && (y0 += height / 2,
1003
+ size += width / 2 / Math.tan(color), y -= height / 2, x -= width / 2 / Math.tan(color)),
1004
+ gradient = this.document.createElementNS("http://www.w3.org/2000/svg", "linearGradient"),
1005
+ gradient.setAttribute("id", name), gradient.setAttribute("gradientUnits", "userSpaceOnUse"),
1006
+ gradient.setAttribute("x1", numToAttr(size)), gradient.setAttribute("y1", numToAttr(y0)),
1007
+ gradient.setAttribute("x2", numToAttr(x)), gradient.setAttribute("y2", numToAttr(y));
1572
1008
  }
1573
- options.colorStops.forEach(({ offset, color }) => {
1574
- const stop = this.document.createElementNS("http://www.w3.org/2000/svg", "stop");
1575
- stop.setAttribute("offset", `${100 * offset}%`);
1576
- stop.setAttribute("stop-color", color);
1009
+ options.colorStops.forEach((({offset, color}) => {
1010
+ let stop = this.document.createElementNS("http://www.w3.org/2000/svg", "stop");
1011
+ stop.setAttribute("offset", `${numToAttr(100 * offset)}%`), stop.setAttribute("stop-color", color),
1577
1012
  gradient.appendChild(stop);
1578
- });
1579
- rect.setAttribute("fill", `url(#${name})`);
1580
- this.defs.appendChild(gradient);
1581
- }
1582
- else if (color) {
1583
- rect.setAttribute("fill", color);
1584
- }
1013
+ })), rect.setAttribute("fill", `url(#${name})`), this.defs.appendChild(gradient);
1014
+ } else color && rect.setAttribute("fill", color);
1585
1015
  this._element.appendChild(rect);
1586
1016
  }
1587
- createMask(id) {
1588
- const options = this.options;
1589
- const mask = this.document.createElementNS("http://www.w3.org/2000/svg", "mask");
1590
- mask.setAttribute("id", id);
1591
- mask.setAttribute("maskUnits", "userSpaceOnUse");
1592
- mask.setAttribute("x", "0");
1593
- mask.setAttribute("y", "0");
1594
- mask.setAttribute("width", String(options.width));
1595
- mask.setAttribute("height", String(options.height));
1596
- const group = this.document.createElementNS("http://www.w3.org/2000/svg", "g");
1597
- group.setAttribute("fill", "#fff");
1598
- mask.appendChild(group);
1599
- return [mask, group];
1017
+ createMask(group_id) {
1018
+ let options = this.options, mask = this.document.createElementNS("http://www.w3.org/2000/svg", "mask");
1019
+ return mask.setAttribute("id", group_id), mask.setAttribute("maskUnits", "userSpaceOnUse"),
1020
+ mask.setAttribute("x", "0"), mask.setAttribute("y", "0"), mask.setAttribute("width", numToAttr(options.width)),
1021
+ mask.setAttribute("height", numToAttr(options.height)), (group_id = this.document.createElementNS("http://www.w3.org/2000/svg", "g")).setAttribute("fill", "#fff"),
1022
+ mask.appendChild(group_id), [ mask, group_id ];
1600
1023
  }
1601
1024
  }
1602
1025
 
1603
- let QRCodeStyling$1 = class QRCodeStyling {
1026
+ let QRCodeStyling$1 = class {
1604
1027
  get size() {
1605
- if (this.qrSVG)
1606
- return {
1607
- width: this.qrSVG.width,
1608
- height: this.qrSVG.height
1609
- };
1610
- return undefined;
1028
+ if (this.qrSVG) return {
1029
+ width: this.qrSVG.width,
1030
+ height: this.qrSVG.height
1031
+ };
1611
1032
  }
1612
1033
  constructor(options) {
1613
- this.options = options ? sanitizeOptions(mergeDeep(defaultOptions, options)) : defaultOptions;
1034
+ this.options = options ? sanitizeOptions(mergeDeep(defaultOptions, options)) : defaultOptions,
1614
1035
  this.update();
1615
1036
  }
1616
- update(
1617
- /** The same options as for initialization */
1618
- options) {
1619
- if (this.container)
1620
- this.container.innerHTML = "";
1621
- this.options = options ? sanitizeOptions(mergeDeep(this.options, options)) : this.options;
1622
- if (!this.options.data) {
1623
- return;
1624
- }
1625
- if (this.options.stringToBytesFuncs) {
1626
- Object.assign(qrcode.stringToBytesFuncs, this.options.stringToBytesFuncs);
1627
- delete this.options.stringToBytesFuncs;
1628
- }
1629
- this.qr = qrcode(this.options.qrOptions.typeNumber, this.options.qrOptions.errorCorrectionLevel);
1630
- let mode = this.options.qrOptions.mode || getMode(this.options.data);
1631
- if (mode == Mode.unicode) {
1632
- qrcode.stringToBytes = qrcode.stringToBytesFuncs["UTF-8"];
1633
- mode = Mode.byte;
1634
- }
1635
- else {
1636
- qrcode.stringToBytes = qrcode.stringToBytesFuncs["default"];
1637
- }
1638
- this.qr.addData(this.options.data, mode);
1639
- this.qr.make();
1640
- this.setupSvg();
1641
- this.append(this.container);
1642
- }
1643
- append(
1644
- /** This container will be used for appending of the QR code */
1645
- container) {
1646
- if (!container) {
1647
- return;
1648
- }
1649
- if (this.qrSVG?.element) {
1650
- container.appendChild(this.qrSVG.element);
1651
- }
1652
- this.container = container;
1653
- }
1654
- /**
1655
- *
1656
- * @example
1657
- *
1658
- * ```js
1659
- * const extension = (svg, options) => {
1660
- * const { width, height } = options;
1661
- * const size = Math.min(width, height);
1662
- * const border = options.document.createElementNS("http://www.w3.org/2000/svg", "rect");
1663
- * const borderAttributes = {
1664
- * fill: "none",
1665
- * x: (width - size + 40) / 2,
1666
- * y: (height - size + 40) / 2,
1667
- * width: size - 40,
1668
- * height: size - 40,
1669
- * stroke: "black",
1670
- * "stroke-width": 40,
1671
- * rx: 100
1672
- * };
1673
- * Object.keys(borderAttributes).forEach((attribute) => {
1674
- * border.setAttribute(attribute, borderAttributes[attribute]);
1675
- * });
1676
- * svg.appendChild(border);
1677
- * };
1678
- * ```
1679
- */
1680
- applyExtension(
1681
- /** Extension is a function that takes svg and previously applied options and modifies an svg */
1682
- extension) {
1683
- if (!extension) {
1684
- throw "Extension function should be defined.";
1685
- }
1686
- this.extension = extension;
1687
- this.update();
1037
+ update(mode) {
1038
+ this.container && (this.container.innerHTML = ""), this.options = mode ? sanitizeOptions(mergeDeep(this.options, mode)) : this.options,
1039
+ this.options.data && (this.options.stringToBytesFuncs && (Object.assign(qrcode.stringToBytesFuncs, this.options.stringToBytesFuncs),
1040
+ delete this.options.stringToBytesFuncs), this.qr = qrcode(this.options.qrOptions.typeNumber, this.options.qrOptions.errorCorrectionLevel),
1041
+ (mode = this.options.qrOptions.mode || function(data) {
1042
+ switch (!0) {
1043
+ case /^[0-9]*$/.test(data):
1044
+ return Mode.numeric;
1045
+
1046
+ case /^[0-9A-Z $%*+\-./:]*$/.test(data):
1047
+ return Mode.alphanumeric;
1048
+
1049
+ case /[^\u0000-\u00ff]/.test(data):
1050
+ return Mode.unicode;
1051
+
1052
+ default:
1053
+ return Mode.byte;
1054
+ }
1055
+ }(this.options.data)) == Mode.unicode ? (qrcode.stringToBytes = qrcode.stringToBytesFuncs["UTF-8"],
1056
+ mode = Mode.byte) : qrcode.stringToBytes = qrcode.stringToBytesFuncs.default, this.qr.addData(this.options.data, mode),
1057
+ this.qr.make(), this.setupSvg(), this.append(this.container));
1058
+ }
1059
+ append(container) {
1060
+ container && (this.qrSVG?.element && container.appendChild(this.qrSVG.element),
1061
+ this.container = container);
1062
+ }
1063
+ applyExtension(extension) {
1064
+ if (!extension) throw "Extension function should be defined.";
1065
+ this.extension = extension, this.update();
1688
1066
  }
1689
1067
  deleteExtension() {
1690
- this.extension = undefined;
1691
- this.update();
1068
+ this.extension = void 0, this.update();
1692
1069
  }
1693
1070
  async serialize() {
1694
- if (!this.qr)
1695
- throw "QR code is empty";
1696
- if (!this.qrSVG?.element || !this.svgDrawingPromise) {
1697
- this.setupSvg();
1698
- }
1699
- await this.svgDrawingPromise;
1700
- if (!this.qrSVG?.element) {
1701
- return;
1702
- }
1703
- const serializer = new XMLSerializer();
1704
- let source = serializer.serializeToString(this.qrSVG.element);
1705
- source = '<?xml version="1.0" standalone="no"?>\r\n' + source;
1706
- return source;
1071
+ if (!this.qr) throw "QR code is empty";
1072
+ if (this.qrSVG?.element && this.svgDrawingPromise || this.setupSvg(), await this.svgDrawingPromise,
1073
+ this.qrSVG?.element) return '<?xml version="1.0" standalone="no"?>\r\n' + (new XMLSerializer).serializeToString(this.qrSVG.element);
1707
1074
  }
1708
1075
  setupSvg() {
1709
- if (!this.qr) {
1710
- return;
1076
+ if (this.qr) {
1077
+ var count = Math.ceil((this.options.shape == ShapeType.circle ? Math.sqrt(2) : 1) * this.qr.getModuleCount());
1078
+ count = Math.ceil(this.options.dotsOptions.size * (count + 2 * (this.options.backgroundOptions && this.options.backgroundOptions.margin || 0))),
1079
+ this.qrSVG = new QRSVG({
1080
+ ...this.options,
1081
+ width: count,
1082
+ height: count,
1083
+ errorCorrectionPercent: ErrorCorrectionPercents[this.options.qrOptions.errorCorrectionLevel]
1084
+ }), this.svgDrawingPromise = this.qrSVG.drawQR(this.qr).then((() => {
1085
+ this.qrSVG?.element && this.extension?.(this.qrSVG.element, this.options);
1086
+ }));
1711
1087
  }
1712
- const count = Math.ceil((this.options.shape == ShapeType.circle ? Math.sqrt(2) : 1) * this.qr.getModuleCount());
1713
- const margin = (this.options.backgroundOptions && this.options.backgroundOptions.margin) || 0;
1714
- const size = Math.ceil(this.options.dotsOptions.size * (count + 2 * margin));
1715
- this.qrSVG = new QRSVG({
1716
- ...this.options,
1717
- width: size,
1718
- height: size,
1719
- errorCorrectionPercent: ErrorCorrectionPercents[this.options.qrOptions.errorCorrectionLevel]
1720
- });
1721
- this.svgDrawingPromise = this.qrSVG.drawQR(this.qr).then(() => {
1722
- if (!this.qrSVG?.element)
1723
- return;
1724
- this.extension?.(this.qrSVG.element, this.options);
1725
- });
1726
1088
  }
1727
1089
  };
1728
1090
 
1729
1091
  var FileExtension;
1730
- (function (FileExtension) {
1731
- FileExtension["svg"] = "svg";
1732
- FileExtension["png"] = "png";
1733
- FileExtension["jpeg"] = "jpeg";
1734
- FileExtension["webp"] = "webp";
1735
- })(FileExtension || (FileExtension = {}));
1736
1092
 
1737
- const browserUtils = undefined;
1093
+ (FileExtension = FileExtension || (FileExtension = {})).svg = "svg", FileExtension.png = "png",
1094
+ FileExtension.jpeg = "jpeg", FileExtension.webp = "webp";
1095
+
1738
1096
  class QRCodeStyling extends QRCodeStyling$1 {
1739
1097
  constructor(options) {
1740
- const dom = new DOMImplementation().createDocument(null, null);
1741
- const imageCache = new Map();
1742
- const loadImage = async function (url) {
1743
- if (typeof url == "string") {
1744
- let pr = imageCache.get(url);
1745
- if (pr)
1746
- return pr;
1747
- pr = fetch(url).then((res) => res
1748
- .arrayBuffer()
1749
- .then((buff) => Buffer.from(buff))
1750
- .then(async (data) => ({
1751
- contentType: res.headers.get("Content-Type") || (await fileTypeFromBuffer(data).then((r) => r?.mime)),
1098
+ async function loadImage(buff) {
1099
+ if ("string" == typeof buff) {
1100
+ let pr = imageCache.get(buff);
1101
+ return pr || (pr = fetch(buff).then((res => res.arrayBuffer().then((buff => Buffer.from(buff))).then((async data => ({
1102
+ contentType: res.headers.get("Content-Type") || await fileTypeFromBuffer(data).then((r => r?.mime)),
1752
1103
  data
1753
- })));
1754
- imageCache.set(url, pr);
1755
- return pr;
1104
+ }))))), imageCache.set(buff, pr), pr);
1756
1105
  }
1757
- else {
1758
- const buff = Buffer.from(url);
1759
- const mime = await fileTypeFromBuffer(buff).then((r) => r?.mime);
1760
- return {
1761
- contentType: mime,
1762
- data: buff
1763
- };
1764
- }
1765
- };
1766
- global.XMLSerializer = XMLSerializer$1;
1767
- global.DOMParser = DOMParser$1;
1768
- super({
1106
+ return buff = Buffer.from(buff), {
1107
+ contentType: await fileTypeFromBuffer(buff).then((r => r?.mime)),
1108
+ data: buff
1109
+ };
1110
+ }
1111
+ let dom = (new DOMImplementation).createDocument(null, null), imageCache = new Map;
1112
+ global.XMLSerializer = XMLSerializer$1, global.DOMParser = DOMParser$1, super({
1769
1113
  ...options,
1770
1114
  document: options.document || dom,
1771
1115
  imageTools: options.imageTools || {
1772
- toDataURL: (url) => loadImage(url).then(({ contentType, data }) => `data:${contentType?.replace("application/xml", "image/svg+xml")};base64,${data.toString("base64")}`),
1773
- getSize: async (src) => {
1774
- const { data } = Buffer.isBuffer(options.image) ? { data: options.image } : await loadImage(src);
1775
- const meta = await sharp(data).metadata();
1776
- return {
1777
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1778
- width: meta.width,
1779
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1780
- height: meta.height
1781
- };
1782
- }
1116
+ toDataURL: url => loadImage(url).then((({contentType, data}) => `data:${contentType?.replace("application/xml", "image/svg+xml")};base64,${data.toString("base64")}`)),
1117
+ getSize: async data => (({data} = Buffer.isBuffer(options.image) ? {
1118
+ data: options.image
1119
+ } : await loadImage(data)), {
1120
+ width: (data = await sharp(data).metadata()).width,
1121
+ height: data.height
1122
+ })
1783
1123
  }
1784
1124
  });
1785
1125
  }
1786
1126
  }
1787
1127
 
1128
+ var browserUtils = void 0;
1129
+
1788
1130
  export { CornerDotType, CornerSquareType, DotType, ErrorCorrectionLevel, ErrorCorrectionPercents, FileExtension, GradientType, Mode, QRCodeStyling, ShapeType, TypeNumber, browserUtils };
1789
1131
  //# sourceMappingURL=qr-code-styling-node.js.map