@thinkpixellab-public/px-vue 4.1.28 → 4.1.30
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/components/PxQrCode.vue
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<div
|
|
11
11
|
class="px-qr-code"
|
|
12
12
|
ref="qrCode"
|
|
13
|
-
:style="{ width: size + 'px', height: size + 'px' }"
|
|
13
|
+
:style="{ width: size + 'px', height: size + 'px', opacity: isRendered ? 1 : 0 }"
|
|
14
14
|
role="img"
|
|
15
15
|
:aria-label="label || content"
|
|
16
16
|
></div>
|
|
@@ -20,8 +20,6 @@
|
|
|
20
20
|
<script>
|
|
21
21
|
import QRCodeStyling from 'qr-code-styling';
|
|
22
22
|
|
|
23
|
-
// test
|
|
24
|
-
|
|
25
23
|
export default {
|
|
26
24
|
name: 'px-qr-code',
|
|
27
25
|
props: {
|
|
@@ -32,11 +30,54 @@ export default {
|
|
|
32
30
|
qrCodeConfig: { type: Object, default: null },
|
|
33
31
|
},
|
|
34
32
|
data() {
|
|
35
|
-
return { size: 0 };
|
|
33
|
+
return { size: 0, isRendered: false, percentageMargin: 0 };
|
|
34
|
+
},
|
|
35
|
+
methods: {
|
|
36
|
+
setScale(retryCount = 0) {
|
|
37
|
+
if (!this.percentageMargin) {
|
|
38
|
+
this.isRendered = true;
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const MAX_RETRIES = 10;
|
|
43
|
+
|
|
44
|
+
const svg = this.$refs.qrCode?.querySelector('svg');
|
|
45
|
+
const rectEls = svg?.querySelectorAll(':scope > rect');
|
|
46
|
+
const imageEls = svg?.querySelectorAll(':scope > image');
|
|
47
|
+
|
|
48
|
+
const marginPx = (this.percentageMargin / 100) * svg.clientWidth;
|
|
49
|
+
const scale = (svg.clientWidth - marginPx * 2) / svg.clientWidth;
|
|
50
|
+
|
|
51
|
+
// the second rect is the qrcode
|
|
52
|
+
const qrRect = rectEls?.[1];
|
|
53
|
+
const qrImage = imageEls?.[0];
|
|
54
|
+
|
|
55
|
+
if (!qrRect || !qrImage) {
|
|
56
|
+
if (retryCount < MAX_RETRIES) {
|
|
57
|
+
setTimeout(() => {
|
|
58
|
+
this.setScale(retryCount + 1);
|
|
59
|
+
}, 25);
|
|
60
|
+
} else {
|
|
61
|
+
// Optionally, log a warning or handle the error
|
|
62
|
+
// console.warn('QR rect or image not found after maximum retries.');
|
|
63
|
+
}
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
this.isRendered = true;
|
|
68
|
+
|
|
69
|
+
qrRect.style.transform = `scale(${scale})`;
|
|
70
|
+
qrImage.style.transform = `scale(${scale})`;
|
|
71
|
+
},
|
|
36
72
|
},
|
|
37
73
|
mounted() {
|
|
38
74
|
this.size = Math.min(this.$el.clientWidth, this.$el.clientHeight);
|
|
39
75
|
|
|
76
|
+
const { margin, ...rest } = this.qrCodeConfig || {};
|
|
77
|
+
|
|
78
|
+
// margin is a percentage of the svg width
|
|
79
|
+
this.percentageMargin = margin ? Math.min(Math.max(0, margin), 100) : 0;
|
|
80
|
+
|
|
40
81
|
const options = {
|
|
41
82
|
width: this.size,
|
|
42
83
|
height: this.size,
|
|
@@ -48,10 +89,14 @@ export default {
|
|
|
48
89
|
crossOrigin: 'anonymous',
|
|
49
90
|
},
|
|
50
91
|
data: this.content,
|
|
51
|
-
...
|
|
92
|
+
...rest,
|
|
52
93
|
type: 'svg',
|
|
53
94
|
};
|
|
54
95
|
|
|
96
|
+
if (!this.percentageMargin) {
|
|
97
|
+
this.isRendered = true;
|
|
98
|
+
}
|
|
99
|
+
|
|
55
100
|
this.qrCode = new QRCodeStyling(options);
|
|
56
101
|
|
|
57
102
|
this.onSizeChange = () => {
|
|
@@ -78,6 +123,10 @@ export default {
|
|
|
78
123
|
options.height = qrSize;
|
|
79
124
|
|
|
80
125
|
this.qrCode.update(options);
|
|
126
|
+
|
|
127
|
+
this.$nextTick(() => {
|
|
128
|
+
this.setScale();
|
|
129
|
+
});
|
|
81
130
|
};
|
|
82
131
|
|
|
83
132
|
this.resizeObserver = new ResizeObserver(this.onSizeChange);
|
|
@@ -87,6 +136,15 @@ export default {
|
|
|
87
136
|
this.qrCode.append(this.$refs.qrCode);
|
|
88
137
|
|
|
89
138
|
this.onSizeChange();
|
|
139
|
+
|
|
140
|
+
if (this.percentageMargin) {
|
|
141
|
+
this.qrCode.getRawData('svg').then(() => {
|
|
142
|
+
// QR code has been rendered
|
|
143
|
+
this.$nextTick(() => {
|
|
144
|
+
this.setScale();
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
}
|
|
90
148
|
});
|
|
91
149
|
},
|
|
92
150
|
beforeUnmount() {
|
|
@@ -100,6 +158,11 @@ export default {
|
|
|
100
158
|
svg {
|
|
101
159
|
width: 100%;
|
|
102
160
|
height: 100%;
|
|
161
|
+
|
|
162
|
+
rect,
|
|
163
|
+
image {
|
|
164
|
+
transform-origin: center;
|
|
165
|
+
}
|
|
103
166
|
}
|
|
104
167
|
}
|
|
105
168
|
</style>
|