canvasframework 0.5.55 → 0.5.56
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/QRCodeGenerator.js +231 -0
- package/core/CanvasFramework.js +1 -0
- package/core/UIBuilder.js +2 -0
- package/index.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import Component from '../core/Component.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Composant QRCodeGenerator simple
|
|
5
|
+
* Génère et affiche un QR code à partir d'une chaîne de caractères
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* new QRCodeGenerator(framework, {
|
|
9
|
+
* x: 50,
|
|
10
|
+
* y: 100,
|
|
11
|
+
* width: 250,
|
|
12
|
+
* height: 250,
|
|
13
|
+
* data: 'https://example.com'
|
|
14
|
+
* });
|
|
15
|
+
*/
|
|
16
|
+
class QRCodeGenerator extends Component {
|
|
17
|
+
constructor(framework, options = {}) {
|
|
18
|
+
super(framework, options);
|
|
19
|
+
|
|
20
|
+
// Données du QR code
|
|
21
|
+
this.data = options.data || options.text || 'https://example.com';
|
|
22
|
+
|
|
23
|
+
// Dimensions
|
|
24
|
+
this.width = options.width || 250;
|
|
25
|
+
this.height = options.height || 250;
|
|
26
|
+
|
|
27
|
+
// Le QR code est toujours carré, on prend la plus petite dimension
|
|
28
|
+
this.qrSize = Math.min(this.width, this.height);
|
|
29
|
+
|
|
30
|
+
// Options du QR code
|
|
31
|
+
this.errorCorrectionLevel = options.errorCorrectionLevel || 'M';
|
|
32
|
+
this.backgroundColor = options.backgroundColor || '#ffffff';
|
|
33
|
+
this.foregroundColor = options.foregroundColor || '#000000';
|
|
34
|
+
this.margin = options.margin !== undefined ? options.margin : 1;
|
|
35
|
+
|
|
36
|
+
// État interne
|
|
37
|
+
this.qrCanvas = null;
|
|
38
|
+
this.qrImage = null;
|
|
39
|
+
this.isGenerating = false;
|
|
40
|
+
this.error = null;
|
|
41
|
+
|
|
42
|
+
// Charger la librairie QRCode
|
|
43
|
+
this.loadQRCodeLibrary();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Charge la librairie qrcode.js depuis CDN
|
|
48
|
+
*/
|
|
49
|
+
loadQRCodeLibrary() {
|
|
50
|
+
if (typeof QRCode === 'undefined') {
|
|
51
|
+
const script = document.createElement('script');
|
|
52
|
+
script.src = 'https://cdn.jsdelivr.net/npm/qrcode@1.5.3/build/qrcode.min.js';
|
|
53
|
+
script.onload = () => {
|
|
54
|
+
console.log('[QRCodeGenerator] Library loaded');
|
|
55
|
+
this.generateQRCode();
|
|
56
|
+
};
|
|
57
|
+
script.onerror = () => {
|
|
58
|
+
console.error('[QRCodeGenerator] Failed to load library');
|
|
59
|
+
this.error = 'Échec du chargement';
|
|
60
|
+
this.markDirty();
|
|
61
|
+
};
|
|
62
|
+
document.head.appendChild(script);
|
|
63
|
+
} else {
|
|
64
|
+
// Librairie déjà chargée
|
|
65
|
+
this.generateQRCode();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async _mount() {
|
|
70
|
+
super._mount?.();
|
|
71
|
+
|
|
72
|
+
// Générer le QR code si les données sont définies et la lib est chargée
|
|
73
|
+
if (this.data && typeof QRCode !== 'undefined' && !this.qrCanvas) {
|
|
74
|
+
await this.generateQRCode();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
destroy() {
|
|
79
|
+
if (this.qrCanvas) {
|
|
80
|
+
this.qrCanvas = null;
|
|
81
|
+
}
|
|
82
|
+
if (this.qrImage) {
|
|
83
|
+
this.qrImage = null;
|
|
84
|
+
}
|
|
85
|
+
super.destroy?.();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
onUnmount() {
|
|
89
|
+
console.log('[QRCodeGenerator] onUnmount called');
|
|
90
|
+
if (this.qrCanvas) {
|
|
91
|
+
this.qrCanvas = null;
|
|
92
|
+
}
|
|
93
|
+
if (this.qrImage) {
|
|
94
|
+
this.qrImage = null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Génère le QR code
|
|
100
|
+
*/
|
|
101
|
+
async generateQRCode() {
|
|
102
|
+
if (typeof QRCode === 'undefined') {
|
|
103
|
+
this.error = 'Librairie non chargée';
|
|
104
|
+
this.markDirty();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (!this.data) {
|
|
109
|
+
this.error = 'Aucune donnée';
|
|
110
|
+
this.markDirty();
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
this.isGenerating = true;
|
|
115
|
+
this.error = null;
|
|
116
|
+
this.markDirty();
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
// Créer un canvas temporaire
|
|
120
|
+
const tempCanvas = document.createElement('canvas');
|
|
121
|
+
|
|
122
|
+
// Options de génération
|
|
123
|
+
const options = {
|
|
124
|
+
errorCorrectionLevel: this.errorCorrectionLevel,
|
|
125
|
+
margin: this.margin,
|
|
126
|
+
width: this.qrSize,
|
|
127
|
+
color: {
|
|
128
|
+
dark: this.foregroundColor,
|
|
129
|
+
light: this.backgroundColor
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Générer le QR code
|
|
134
|
+
await QRCode.toCanvas(tempCanvas, this.data, options);
|
|
135
|
+
|
|
136
|
+
this.qrCanvas = tempCanvas;
|
|
137
|
+
|
|
138
|
+
// Convertir en image pour le rendu
|
|
139
|
+
const dataURL = tempCanvas.toDataURL('image/png');
|
|
140
|
+
this.qrImage = new Image();
|
|
141
|
+
this.qrImage.onload = () => {
|
|
142
|
+
this.isGenerating = false;
|
|
143
|
+
this.markDirty();
|
|
144
|
+
};
|
|
145
|
+
this.qrImage.src = dataURL;
|
|
146
|
+
|
|
147
|
+
} catch (err) {
|
|
148
|
+
this.error = 'Erreur génération';
|
|
149
|
+
this.isGenerating = false;
|
|
150
|
+
console.error('[QRCodeGenerator] Error:', err);
|
|
151
|
+
this.markDirty();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Change les données et régénère le QR code
|
|
157
|
+
*/
|
|
158
|
+
async setData(newData) {
|
|
159
|
+
if (this.data === newData) return;
|
|
160
|
+
|
|
161
|
+
this.data = newData;
|
|
162
|
+
await this.generateQRCode();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Change la taille du QR code
|
|
167
|
+
*/
|
|
168
|
+
async setSize(newSize) {
|
|
169
|
+
this.width = newSize;
|
|
170
|
+
this.height = newSize;
|
|
171
|
+
this.qrSize = newSize;
|
|
172
|
+
await this.generateQRCode();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
draw(ctx) {
|
|
176
|
+
ctx.save();
|
|
177
|
+
|
|
178
|
+
// Fond
|
|
179
|
+
ctx.fillStyle = this.backgroundColor;
|
|
180
|
+
ctx.fillRect(this.x, this.y, this.width, this.height);
|
|
181
|
+
|
|
182
|
+
// Centrer le QR code dans les dimensions du composant
|
|
183
|
+
const offsetX = (this.width - this.qrSize) / 2;
|
|
184
|
+
const offsetY = (this.height - this.qrSize) / 2;
|
|
185
|
+
|
|
186
|
+
// État : Génération en cours
|
|
187
|
+
if (this.isGenerating) {
|
|
188
|
+
ctx.fillStyle = '#666';
|
|
189
|
+
ctx.font = '14px Arial';
|
|
190
|
+
ctx.textAlign = 'center';
|
|
191
|
+
ctx.textBaseline = 'middle';
|
|
192
|
+
ctx.fillText(
|
|
193
|
+
'Génération...',
|
|
194
|
+
this.x + this.width / 2,
|
|
195
|
+
this.y + this.height / 2
|
|
196
|
+
);
|
|
197
|
+
ctx.restore();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// État : Erreur
|
|
202
|
+
if (this.error) {
|
|
203
|
+
ctx.fillStyle = '#ff4444';
|
|
204
|
+
ctx.font = '12px Arial';
|
|
205
|
+
ctx.textAlign = 'center';
|
|
206
|
+
ctx.textBaseline = 'middle';
|
|
207
|
+
ctx.fillText(
|
|
208
|
+
this.error,
|
|
209
|
+
this.x + this.width / 2,
|
|
210
|
+
this.y + this.height / 2
|
|
211
|
+
);
|
|
212
|
+
ctx.restore();
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Dessiner le QR code
|
|
217
|
+
if (this.qrImage && this.qrImage.complete) {
|
|
218
|
+
ctx.drawImage(
|
|
219
|
+
this.qrImage,
|
|
220
|
+
this.x + offsetX,
|
|
221
|
+
this.y + offsetY,
|
|
222
|
+
this.qrSize,
|
|
223
|
+
this.qrSize
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
ctx.restore();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export default QRCodeGenerator;
|
package/core/CanvasFramework.js
CHANGED
|
@@ -59,6 +59,7 @@ import Camera from '../components/Camera.js';
|
|
|
59
59
|
import FloatedCamera from '../components/FloatedCamera.js';
|
|
60
60
|
import TimePicker from '../components/TimePicker.js';
|
|
61
61
|
import QRCodeReader from '../components/QRCodeReader.js';
|
|
62
|
+
import QRCodeGenerator from '../components/QRCodeGenerator.js';
|
|
62
63
|
|
|
63
64
|
// Utils
|
|
64
65
|
import SafeArea from '../utils/SafeArea.js';
|
package/core/UIBuilder.js
CHANGED
|
@@ -59,6 +59,7 @@ import Camera from '../components/Camera.js';
|
|
|
59
59
|
import FloatedCamera from '../components/FloatedCamera.js';
|
|
60
60
|
import TimePicker from '../components/TimePicker.js';
|
|
61
61
|
import QRCodeReader from '../components/QRCodeReader.js';
|
|
62
|
+
import QRCodeGenerator from '../components/QRCodeGenerator.js';
|
|
62
63
|
|
|
63
64
|
// Features
|
|
64
65
|
import PullToRefresh from '../features/PullToRefresh.js';
|
|
@@ -145,6 +146,7 @@ const Components = {
|
|
|
145
146
|
Positioned,
|
|
146
147
|
Banner,
|
|
147
148
|
Chart,
|
|
149
|
+
QRCodeGenerator,
|
|
148
150
|
Stack
|
|
149
151
|
};
|
|
150
152
|
|
package/index.js
CHANGED
|
@@ -66,6 +66,7 @@ export { default as Camera } from './components/Camera.js';
|
|
|
66
66
|
export { default as FloatedCamera } from './components/FloatedCamera.js';
|
|
67
67
|
export { default as TimePicker } from './components/TimePicker.js';
|
|
68
68
|
export { default as QRCodeReader } from './components/QRCodeReader.js';
|
|
69
|
+
export { default as QRCodeGenerator } from './components/QRCodeGenerator.js';
|
|
69
70
|
|
|
70
71
|
// Utils
|
|
71
72
|
export { default as SafeArea } from './utils/SafeArea.js';
|