@liquid-js/qr-code-styling 1.7.1 → 1.9.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.
package/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # QR Code Styling
2
+
2
3
  [![Version](https://img.shields.io/npm/v/qr-code-styling.svg)](https://www.npmjs.org/package/qr-code-styling)
3
4
 
4
5
  JavaScript library for generating QR codes with a logo and styling.
@@ -6,7 +7,9 @@ JavaScript library for generating QR codes with a logo and styling.
6
7
  Try it here https://qr-code-styling.com
7
8
 
8
9
  If you have issues / suggestions / notes / questions, please open an issue or contact me. Let's create a cool library together.
10
+
9
11
  ### Examples
12
+
10
13
  <p float="left">
11
14
  <img style="display:inline-block" src="https://raw.githubusercontent.com/kozakdenys/qr-code-styling/master/src/assets/facebook_example_new.png" width="240" />
12
15
  <img style="display:inline-block" src="https://raw.githubusercontent.com/kozakdenys/qr-code-styling/master/src/assets/qr_code_example.png" width="240" />
@@ -55,6 +58,7 @@ npm install qr-code-styling
55
58
  </body>
56
59
  </html>
57
60
  ```
61
+
58
62
  ---
59
63
 
60
64
  [**React example (Codesandbox)**](https://codesandbox.io/s/qr-code-styling-react-example-l8rwl?file=/src/App.js)
@@ -74,72 +78,73 @@ npm install qr-code-styling
74
78
  ### API Documentation
75
79
 
76
80
  #### QRCodeStyling instance
81
+
77
82
  `new QRCodeStyling(options) => QRCodeStyling`
78
83
 
79
- Param |Type |Description
80
- -------|------|------------
81
- options|object|Init object
84
+ | Param | Type | Description |
85
+ | ------- | ------ | ----------- |
86
+ | options | object | Init object |
82
87
 
83
88
  `options` structure
84
89
 
85
- Property |Type |Default Value|Description
86
- -----------------------|-------------------------|-------------|-----------------------------------------------------
87
- data |string | |The date will be encoded to the QR code
88
- image |string | |The image will be copied to the center of the QR code
89
- qrOptions |object | |Options will be passed to `qrcode-generator` lib
90
- imageOptions |object | |Specific image options, details see below
91
- dotsOptions |object | |Dots styling options
92
- cornersSquareOptions |object | |Square in the corners styling options
93
- cornersDotOptionsHelper|object | |Dots in the corners styling options
94
- backgroundOptions |object | |QR background styling options
90
+ | Property | Type | Default Value | Description |
91
+ | ----------------------- | ------ | ------------- | ----------------------------------------------------- |
92
+ | data | string | | The date will be encoded to the QR code |
93
+ | image | string | | The image will be copied to the center of the QR code |
94
+ | qrOptions | object | | Options will be passed to `qrcode-generator` lib |
95
+ | imageOptions | object | | Specific image options, details see below |
96
+ | dotsOptions | object | | Dots styling options |
97
+ | cornersSquareOptions | object | | Square in the corners styling options |
98
+ | cornersDotOptionsHelper | object | | Dots in the corners styling options |
99
+ | backgroundOptions | object | | QR background styling options |
95
100
 
96
101
  `options.qrOptions` structure
97
102
 
98
- Property |Type |Default Value
99
- --------------------|--------------------------------------------------|-------------
100
- typeNumber |number (`0 - 40`) |`0`
101
- mode |string (`'Numeric' 'Alphanumeric' 'Byte' 'Kanji'`)|
102
- errorCorrectionLevel|string (`'L' 'M' 'Q' 'H'`) |`'Q'`
103
+ | Property | Type | Default Value |
104
+ | -------------------- | -------------------------------------------------- | ------------- |
105
+ | typeNumber | number (`0 - 40`) | `0` |
106
+ | mode | string (`'Numeric' 'Alphanumeric' 'Byte' 'Kanji'`) |
107
+ | errorCorrectionLevel | string (`'L' 'M' 'Q' 'H'`) | `'Q'` |
103
108
 
104
109
  `options.imageOptions` structure
105
110
 
106
- Property |Type |Default Value|Description
107
- ------------------|---------------------------------------|-------------|------------------------------------------------------------------------------
108
- hideBackgroundDots|boolean |`true` |Hide all dots covered by the image
109
- imageSize |number |`0.4` |Coefficient of the image size. Not recommended to use ove 0.5. Lower is better
110
- margin |number |`0` |Margin of the image in blocks
111
- crossOrigin |string(`'anonymous' 'use-credentials'`)| |Set "anonymous" if you want to download QR code from other origins.
111
+ | Property | Type | Default Value | Description |
112
+ | ------------------ | --------------------------------------- | ------------- | ------------------------------------------------------------------------------ |
113
+ | hideBackgroundDots | boolean | `true` | Hide all dots covered by the image |
114
+ | imageSize | number | `0.4` | Coefficient of the image size. Not recommended to use ove 0.5. Lower is better |
115
+ | margin | number | `0` | Margin of the image in blocks |
116
+ | crossOrigin | string(`'anonymous' 'use-credentials'`) | | Set "anonymous" if you want to download QR code from other origins. |
112
117
 
113
118
  `options.dotsOptions` structure
114
119
 
115
- Property|Type |Default Value|Description
116
- --------|------------------------------------------------------------------------------|-------------|-------------------
117
- color |string |`'#000'` |Color of QR dots
118
- gradient|object | |Gradient of QR dots
119
- type |string (`'rounded' 'dots' 'classy' 'classy-rounded' 'square' 'extra-rounded'`)|`'square'` |Style of QR dots
120
+ | Property | Type | Default Value | Description |
121
+ | -------- | ------------------------------------------------------------------------------ | ------------- | ------------------- |
122
+ | color | string | `'#000'` | Color of QR dots |
123
+ | gradient | object | | Gradient of QR dots |
124
+ | type | string (`'rounded' 'dots' 'classy' 'classy-rounded' 'square' 'extra-rounded'`) | `'square'` | Style of QR dots |
120
125
 
121
126
  `options.backgroundOptions` structure
122
127
 
123
- Property|Type |Default Value
124
- --------|------|-------------
125
- color |string|`'#fff'`
126
- gradient|object|
128
+ | Property | Type | Default Value |
129
+ | -------- | ------ | ------------- |
130
+ | color | string | `'#fff'` |
131
+ | gradient | object |
127
132
 
128
133
  `options.cornersSquareOptions` structure
129
134
 
130
- Property|Type |Default Value|Description
131
- --------|-----------------------------------------|-------------|-----------------
132
- color |string | |Color of Corners Square
133
- gradient|object | |Gradient of Corners Square
134
- type |string (`'dot' 'square' 'extra-rounded'`)| |Style of Corners Square
135
+ | Property | Type | Default Value | Description |
136
+ | -------- | ----------------------------------------- | ------------- | -------------------------- |
137
+ | color | string | | Color of Corners Square |
138
+ | gradient | object | | Gradient of Corners Square |
139
+ | type | string (`'dot' 'square' 'extra-rounded'`) | | Style of Corners Square |
135
140
 
136
141
  `options.cornersDotOptions` structure
137
142
 
138
- Property|Type |Default Value|Description
139
- --------|-------------------------|-------------|-----------------
140
- color |string | |Color of Corners Dot
141
- gradient|object | |Gradient of Corners Dot
142
- type |string (`'dot' 'square'`)| |Style of Corners Dot
143
+ | Property | Type | Default Value | Description |
144
+ | -------- | ------------------------- | ------------- | ----------------------- |
145
+ | color | string | | Color of Corners Dot |
146
+ | gradient | object | | Gradient of Corners Dot |
147
+ | type | string (`'dot' 'square'`) | | Style of Corners Dot |
143
148
 
144
149
  Gradient structure
145
150
 
@@ -151,11 +156,11 @@ Gradient structure
151
156
 
152
157
  `options.cornersDotOptions.gradient`
153
158
 
154
- Property |Type |Default Value|Description
155
- ----------|----------------------------|-------------|---------------------------------------------------------
156
- type |string (`'linear' 'radial'`)|"linear" |Type of gradient spread
157
- rotation |number |0 |Rotation of gradient in radians (Math.PI === 180 degrees)
158
- colorStops|array of objects | |Gradient colors. Example `[{ offset: 0, color: 'blue' }, { offset: 1, color: 'red' }]`
159
+ | Property | Type | Default Value | Description |
160
+ | ---------- | ---------------------------- | ------------- | --------------------------------------------------------------------------------------- |
161
+ | type | string (`'linear' 'radial'`) | "linear" | Type of gradient spread |
162
+ | rotation | number | 0 | Rotation of gradient in radians (Math.PI === 180 degrees) |
163
+ | colorStops | array of objects | | Gradient colors. Example `[{ offset: 0, color: 'blue' }, { offset: 1, color: 'red' }]` |
159
164
 
160
165
  Gradient colorStops structure
161
166
 
@@ -167,31 +172,32 @@ Gradient colorStops structure
167
172
 
168
173
  `options.cornersDotOptions.gradient.colorStops[]`
169
174
 
170
- Property|Type |Default Value|Description
171
- --------|----------------|-------------|-----------------------------------
172
- offset |number (`0 - 1`)| |Position of color in gradient range
173
- color |string | |Color of stop in gradient range
175
+ | Property | Type | Default Value | Description |
176
+ | -------- | ---------------- | ------------- | ----------------------------------- |
177
+ | offset | number (`0 - 1`) | | Position of color in gradient range |
178
+ | color | string | | Color of stop in gradient range |
174
179
 
175
180
  #### QRCodeStyling methods
181
+
176
182
  `QRCodeStyling.append(container) => void`
177
183
 
178
- Param |Type |Description
179
- ---------|-----------|-----------
180
- container|DOM element|This container will be used for appending of the QR code
184
+ | Param | Type | Description |
185
+ | --------- | ----------- | -------------------------------------------------------- |
186
+ | container | DOM element | This container will be used for appending of the QR code |
181
187
 
182
188
  `QRCodeStyling.serialize() => Promise<string>`
183
189
 
184
190
  `QRCodeStyling.update(options) => void`
185
191
 
186
- Param |Type |Description
187
- -------|------|--------------------------------------
188
- options|object|The same options as for initialization
192
+ | Param | Type | Description |
193
+ | ------- | ------ | -------------------------------------- |
194
+ | options | object | The same options as for initialization |
189
195
 
190
196
  `QRCodeStyling.applyExtension(extension) => void`
191
197
 
192
- Param |Type |Description
193
- ---------|----------------------|------------------------------------------------------------------------------------------
194
- extension|(svg, options) => void|Extension is a function that takes svg and previously applied options and modifies an svg
198
+ | Param | Type | Description |
199
+ | --------- | ---------------------- | ----------------------------------------------------------------------------------------- |
200
+ | extension | (svg, options) => void | Extension is a function that takes svg and previously applied options and modifies an svg |
195
201
 
196
202
  `applyExtension` example
197
203
 
@@ -219,8 +225,6 @@ const extension = (svg, options) => {
219
225
 
220
226
  `QRCodeStyling.deleteExtension() => void`
221
227
 
222
-
223
228
  ### License
224
229
 
225
230
  [MIT License](https://raw.githubusercontent.com/kozakdenys/qr-code-styling/master/LICENSE). Copyright (c) 2021 Denys Kozak
226
-
package/lib/index.d.ts CHANGED
@@ -1,13 +1,5 @@
1
1
  import { ErrorCorrectionPercents } from "./constants/errorCorrectionPercents";
2
2
  import { QRCodeStyling } from "./core/QRCodeStyling";
3
3
  import * as browserUtils from "./tools/browserUtils";
4
- import * as types from "./types";
5
- export * from "./tools/browserUtils";
6
4
  export * from "./types";
7
- export { ErrorCorrectionPercents, QRCodeStyling };
8
- declare const _default: {
9
- QRCodeStyling: typeof QRCodeStyling;
10
- browserUtils: typeof browserUtils;
11
- types: typeof types;
12
- };
13
- export default _default;
5
+ export { ErrorCorrectionPercents, QRCodeStyling, browserUtils };
@@ -610,7 +610,7 @@ class QRDot {
610
610
  }
611
611
  }
612
612
 
613
- function calculateImageSize({ originalHeight, originalWidth, maxHiddenDots, maxHiddenAxisDots, dotSize }) {
613
+ function calculateImageSize({ originalHeight, originalWidth, maxHiddenDots, maxHiddenAxisDots, dotSize, margin }) {
614
614
  const hideDots = { x: 0, y: 0 };
615
615
  const imageSize = { x: 0, y: 0 };
616
616
  if (originalHeight <= 0 || originalWidth <= 0 || maxHiddenDots <= 0 || dotSize <= 0) {
@@ -621,41 +621,65 @@ function calculateImageSize({ originalHeight, originalWidth, maxHiddenDots, maxH
621
621
  hideXDots: 0
622
622
  };
623
623
  }
624
- const k = originalHeight / originalWidth;
625
- //Getting the maximum possible axis hidden dots
626
- hideDots.x = Math.floor(Math.sqrt(maxHiddenDots / k));
627
- //The count of hidden dot's can't be less than 1
628
- if (hideDots.x <= 0)
629
- hideDots.x = 1;
630
- //Check the limit of the maximum allowed axis hidden dots
631
- if (maxHiddenAxisDots && maxHiddenAxisDots < hideDots.x)
632
- hideDots.x = maxHiddenAxisDots;
633
- //The count of dots should be odd
634
- if (hideDots.x % 2 === 0)
635
- hideDots.x--;
636
- imageSize.x = hideDots.x * dotSize;
637
- //Calculate opposite axis hidden dots based on axis value.
638
- //The value will be odd.
639
- //We use ceil to prevent dots covering by the image.
640
- hideDots.y = 1 + 2 * Math.ceil((hideDots.x * k - 1) / 2);
641
- imageSize.y = Math.round(imageSize.x * k);
642
- //If the result dots count is bigger than max - then decrease size and calculate again
643
- if (hideDots.y * hideDots.x > maxHiddenDots || (maxHiddenAxisDots && maxHiddenAxisDots < hideDots.y)) {
644
- if (maxHiddenAxisDots && maxHiddenAxisDots < hideDots.y) {
645
- hideDots.y = maxHiddenAxisDots;
646
- if (hideDots.y % 2 === 0)
647
- hideDots.x--;
624
+ if (maxHiddenAxisDots) {
625
+ // Adjust max size based on image aspect ratio and margin
626
+ const maxD = maxHiddenAxisDots - 2 * margin;
627
+ if (originalWidth > originalHeight) {
628
+ const newH = (maxD * originalHeight) / originalWidth + 2 * margin;
629
+ maxHiddenDots = Math.min(maxHiddenDots, maxHiddenAxisDots * newH);
648
630
  }
649
631
  else {
650
- hideDots.y -= 2;
632
+ const newW = (maxD * originalWidth) / originalHeight + 2 * margin;
633
+ maxHiddenDots = Math.min(maxHiddenDots, maxHiddenAxisDots * newW);
651
634
  }
652
- imageSize.y = hideDots.y * dotSize;
653
- hideDots.x = 1 + 2 * Math.ceil((hideDots.y / k - 1) / 2);
654
- imageSize.x = Math.round(imageSize.y / k);
635
+ }
636
+ const m2 = margin ** 2;
637
+ const w2 = originalWidth ** 2;
638
+ const h2 = originalHeight ** 2;
639
+ //Margin-adjuseted scale
640
+ const scale = (Math.sqrt(w2 * m2 + h2 * m2 + originalWidth * originalHeight * (maxHiddenDots - 2 * m2)) -
641
+ originalHeight * margin -
642
+ originalWidth * margin) /
643
+ (originalHeight * originalWidth);
644
+ hideDots.x = Math.max(1, Math.floor(originalWidth * scale + 2 * margin));
645
+ hideDots.y = Math.max(1, Math.floor(originalHeight * scale + 2 * margin));
646
+ if (hideDots.x > hideDots.y) {
647
+ //The count of dots should be odd
648
+ if (hideDots.x % 2 === 0)
649
+ hideDots.x--;
650
+ hideDots.y = Math.max(1, Math.ceil(((hideDots.x - 2 * margin) * originalHeight) / originalWidth + 2 * margin));
651
+ //The count of dots should be odd
652
+ if (hideDots.y % 2 === 0)
653
+ hideDots.y--;
654
+ }
655
+ else if (hideDots.x < hideDots.y) {
656
+ //The count of dots should be odd
657
+ if (hideDots.y % 2 === 0)
658
+ hideDots.y--;
659
+ hideDots.x = Math.max(1, Math.ceil(((hideDots.y - 2 * margin) * originalWidth) / originalHeight + 2 * margin));
660
+ //The count of dots should be odd
661
+ if (hideDots.x % 2 === 0)
662
+ hideDots.x--;
663
+ }
664
+ const maxW = (hideDots.x - 2 * margin) * dotSize;
665
+ const maxH = (hideDots.y - 2 * margin) * dotSize;
666
+ if (maxW <= 0 || maxH <= 0) {
667
+ return {
668
+ height: 0,
669
+ width: 0,
670
+ hideYDots: hideDots.y,
671
+ hideXDots: hideDots.x
672
+ };
673
+ }
674
+ imageSize.x = maxW;
675
+ imageSize.y = (maxW * originalHeight) / originalWidth;
676
+ if (imageSize.y > maxH) {
677
+ imageSize.y = maxH;
678
+ imageSize.x = (maxH * originalWidth) / originalHeight;
655
679
  }
656
680
  return {
657
- height: imageSize.y,
658
- width: imageSize.x,
681
+ height: Math.round(imageSize.y + 2 * margin * dotSize),
682
+ width: Math.round(imageSize.x + 2 * margin * dotSize),
659
683
  hideYDots: hideDots.y,
660
684
  hideXDots: hideDots.x
661
685
  };
@@ -774,7 +798,8 @@ class QRSVG {
774
798
  originalHeight: size.height,
775
799
  maxHiddenDots,
776
800
  maxHiddenAxisDots: count - 14,
777
- dotSize
801
+ dotSize,
802
+ margin: imageOptions.margin
778
803
  });
779
804
  }
780
805
  this.drawBackground();
@@ -796,7 +821,7 @@ class QRSVG {
796
821
  return true;
797
822
  });
798
823
  this.drawCorners();
799
- if (this._options.image) {
824
+ if (this._options.image && drawImageSize.width > 0 && drawImageSize.height > 0) {
800
825
  await this.drawImage({ width: drawImageSize.width, height: drawImageSize.height, count, dotSize });
801
826
  }
802
827
  }