canvasframework 0.5.56 → 0.5.57

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,8 +1,8 @@
1
1
  import Component from '../core/Component.js';
2
2
 
3
3
  /**
4
- * Composant QRCodeGenerator simple
5
- * Génère et affiche un QR code à partir d'une chaîne de caractères
4
+ * QRCodeGenerator SANS librairie externe
5
+ * Version simplifiée qui fonctionne pour texte court et URLs
6
6
  *
7
7
  * @example
8
8
  * new QRCodeGenerator(framework, {
@@ -18,158 +18,243 @@ class QRCodeGenerator extends Component {
18
18
  super(framework, options);
19
19
 
20
20
  // Données du QR code
21
- this.data = options.data || options.text || 'https://example.com';
21
+ this.data = options.data || options.text || 'Hello';
22
22
 
23
23
  // Dimensions
24
24
  this.width = options.width || 250;
25
25
  this.height = options.height || 250;
26
-
27
- // Le QR code est toujours carré, on prend la plus petite dimension
28
26
  this.qrSize = Math.min(this.width, this.height);
29
27
 
30
- // Options du QR code
31
- this.errorCorrectionLevel = options.errorCorrectionLevel || 'M';
28
+ // Options visuelles
32
29
  this.backgroundColor = options.backgroundColor || '#ffffff';
33
30
  this.foregroundColor = options.foregroundColor || '#000000';
34
- this.margin = options.margin !== undefined ? options.margin : 1;
31
+ this.padding = options.padding || 20;
35
32
 
36
- // État interne
37
- this.qrCanvas = null;
38
- this.qrImage = null;
39
- this.isGenerating = false;
40
- this.error = null;
33
+ // État
34
+ this.qrMatrix = null;
35
+ this.moduleSize = 0;
41
36
 
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
- }
37
+ // Générer immédiatement
38
+ this.generateQRCode();
67
39
  }
68
40
 
69
41
  async _mount() {
70
42
  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();
43
+ if (!this.qrMatrix) {
44
+ this.generateQRCode();
75
45
  }
76
46
  }
77
47
 
78
48
  destroy() {
79
- if (this.qrCanvas) {
80
- this.qrCanvas = null;
81
- }
82
- if (this.qrImage) {
83
- this.qrImage = null;
84
- }
49
+ this.qrMatrix = null;
85
50
  super.destroy?.();
86
51
  }
87
52
 
88
53
  onUnmount() {
89
54
  console.log('[QRCodeGenerator] onUnmount called');
90
- if (this.qrCanvas) {
91
- this.qrCanvas = null;
92
- }
93
- if (this.qrImage) {
94
- this.qrImage = null;
95
- }
55
+ this.qrMatrix = null;
96
56
  }
97
57
 
98
58
  /**
99
- * Génère le QR code
59
+ * Génère un QR code simple (Version 1 : 21x21)
100
60
  */
101
- async generateQRCode() {
102
- if (typeof QRCode === 'undefined') {
103
- this.error = 'Librairie non chargée';
61
+ generateQRCode() {
62
+ try {
63
+ // Taille fixe pour Version 1 (supporte ~25 caractères)
64
+ const size = 21;
65
+
66
+ // Créer la matrice
67
+ this.qrMatrix = this.createMatrix(size);
68
+
69
+ // Ajouter les patterns de base
70
+ this.addFinderPatterns(this.qrMatrix);
71
+ this.addTimingPatterns(this.qrMatrix);
72
+ this.addAlignmentPattern(this.qrMatrix);
73
+
74
+ // Ajouter les données (simplifié)
75
+ this.addDataSimple(this.qrMatrix);
76
+
77
+ // Calculer la taille d'un module
78
+ const availableSize = this.qrSize - (this.padding * 2);
79
+ this.moduleSize = Math.floor(availableSize / size);
80
+
81
+ console.log('[QRCodeGenerator] QR Code generated:', size + 'x' + size);
104
82
  this.markDirty();
105
- return;
83
+
84
+ } catch (err) {
85
+ console.error('[QRCodeGenerator] Error:', err);
106
86
  }
87
+ }
107
88
 
108
- if (!this.data) {
109
- this.error = 'Aucune donnée';
110
- this.markDirty();
111
- return;
89
+ /**
90
+ * Crée une matrice vide
91
+ */
92
+ createMatrix(size) {
93
+ const matrix = [];
94
+ for (let i = 0; i < size; i++) {
95
+ matrix[i] = new Array(size).fill(-1); // -1 = non défini
112
96
  }
97
+ return matrix;
98
+ }
113
99
 
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');
100
+ /**
101
+ * Ajoute les patterns de position (3 carrés dans les coins)
102
+ */
103
+ addFinderPatterns(matrix) {
104
+ const size = matrix.length;
105
+
106
+ // Pattern 7x7
107
+ const addFinder = (startX, startY) => {
108
+ for (let dy = 0; dy < 7; dy++) {
109
+ for (let dx = 0; dx < 7; dx++) {
110
+ const x = startX + dx;
111
+ const y = startY + dy;
112
+
113
+ // Carré extérieur (7x7)
114
+ if (dx === 0 || dx === 6 || dy === 0 || dy === 6) {
115
+ matrix[y][x] = 1;
116
+ }
117
+ // Carré intérieur (3x3) centré
118
+ else if (dx >= 2 && dx <= 4 && dy >= 2 && dy <= 4) {
119
+ matrix[y][x] = 1;
120
+ }
121
+ // Blanc entre les deux
122
+ else {
123
+ matrix[y][x] = 0;
124
+ }
125
+ }
126
+ }
121
127
 
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
128
+ // Séparateurs blancs (1 pixel autour)
129
+ for (let i = 0; i < 8; i++) {
130
+ if (startX === 0 && startY === 0) {
131
+ // Haut gauche
132
+ if (i < 7) matrix[7][i] = 0;
133
+ if (i < 7) matrix[i][7] = 0;
134
+ } else if (startX === size - 7 && startY === 0) {
135
+ // Haut droit
136
+ if (i < 7) matrix[7][size - 8 + i] = 0;
137
+ if (i < 7) matrix[i][size - 8] = 0;
138
+ } else if (startX === 0 && startY === size - 7) {
139
+ // Bas gauche
140
+ if (i < 7) matrix[size - 8][i] = 0;
141
+ if (i < 7) matrix[size - 8 + i][7] = 0;
130
142
  }
131
- };
143
+ }
144
+ };
145
+
146
+ // Haut gauche
147
+ addFinder(0, 0);
148
+
149
+ // Haut droit
150
+ addFinder(size - 7, 0);
151
+
152
+ // Bas gauche
153
+ addFinder(0, size - 7);
154
+ }
132
155
 
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;
156
+ /**
157
+ * Ajoute les lignes de timing
158
+ */
159
+ addTimingPatterns(matrix) {
160
+ const size = matrix.length;
161
+
162
+ // Ligne horizontale (ligne 6)
163
+ for (let i = 8; i < size - 8; i++) {
164
+ matrix[6][i] = (i % 2 === 0) ? 1 : 0;
165
+ }
166
+
167
+ // Ligne verticale (colonne 6)
168
+ for (let i = 8; i < size - 8; i++) {
169
+ matrix[i][6] = (i % 2 === 0) ? 1 : 0;
170
+ }
171
+ }
146
172
 
147
- } catch (err) {
148
- this.error = 'Erreur génération';
149
- this.isGenerating = false;
150
- console.error('[QRCodeGenerator] Error:', err);
151
- this.markDirty();
173
+ /**
174
+ * Ajoute le pattern d'alignement (pour Version 1, pas nécessaire, mais on le met quand même)
175
+ */
176
+ addAlignmentPattern(matrix) {
177
+ // Pour Version 1, pas d'alignment pattern
178
+ // On remplit juste avec le module noir obligatoire
179
+ const size = matrix.length;
180
+ matrix[size - 8][8] = 1; // Module noir fixe
181
+ }
182
+
183
+ /**
184
+ * Ajoute les données de manière simplifiée (pattern basé sur les données)
185
+ */
186
+ addDataSimple(matrix) {
187
+ const size = matrix.length;
188
+
189
+ // Convertir les données en une séquence de bits basique
190
+ let bits = '';
191
+ for (let i = 0; i < this.data.length; i++) {
192
+ const charCode = this.data.charCodeAt(i);
193
+ // Convertir en binaire sur 8 bits
194
+ bits += charCode.toString(2).padStart(8, '0');
195
+ }
196
+
197
+ // Ajouter un padding si nécessaire
198
+ while (bits.length < 100) {
199
+ bits += '0';
200
+ }
201
+
202
+ let bitIndex = 0;
203
+
204
+ // Remplir la matrice en zigzag (de droite à gauche, de bas en haut)
205
+ for (let col = size - 1; col > 0; col -= 2) {
206
+ // Sauter la colonne de timing
207
+ if (col === 6) col--;
208
+
209
+ for (let row = 0; row < size; row++) {
210
+ // Alterner direction : bas->haut puis haut->bas
211
+ const y = ((col + 1) % 4 < 2) ? (size - 1 - row) : row;
212
+
213
+ // Remplir 2 colonnes à la fois
214
+ for (let c = 0; c < 2; c++) {
215
+ const x = col - c;
216
+
217
+ // Ne pas écraser les patterns existants
218
+ if (matrix[y][x] !== -1) continue;
219
+
220
+ // Placer un bit
221
+ if (bitIndex < bits.length) {
222
+ matrix[y][x] = bits[bitIndex] === '1' ? 1 : 0;
223
+ bitIndex++;
224
+ } else {
225
+ matrix[y][x] = 0;
226
+ }
227
+ }
228
+ }
229
+ }
230
+
231
+ // Remplir les cases restantes avec 0
232
+ for (let y = 0; y < size; y++) {
233
+ for (let x = 0; x < size; x++) {
234
+ if (matrix[y][x] === -1) {
235
+ matrix[y][x] = 0;
236
+ }
237
+ }
152
238
  }
153
239
  }
154
240
 
155
241
  /**
156
- * Change les données et régénère le QR code
242
+ * Change les données et régénère
157
243
  */
158
244
  async setData(newData) {
159
245
  if (this.data === newData) return;
160
-
161
246
  this.data = newData;
162
- await this.generateQRCode();
247
+ this.generateQRCode();
163
248
  }
164
249
 
165
250
  /**
166
- * Change la taille du QR code
251
+ * Change la taille
167
252
  */
168
253
  async setSize(newSize) {
169
254
  this.width = newSize;
170
255
  this.height = newSize;
171
256
  this.qrSize = newSize;
172
- await this.generateQRCode();
257
+ this.generateQRCode();
173
258
  }
174
259
 
175
260
  draw(ctx) {
@@ -179,12 +264,8 @@ class QRCodeGenerator extends Component {
179
264
  ctx.fillStyle = this.backgroundColor;
180
265
  ctx.fillRect(this.x, this.y, this.width, this.height);
181
266
 
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) {
267
+ if (!this.qrMatrix || this.moduleSize === 0) {
268
+ // Message de chargement
188
269
  ctx.fillStyle = '#666';
189
270
  ctx.font = '14px Arial';
190
271
  ctx.textAlign = 'center';
@@ -198,30 +279,25 @@ class QRCodeGenerator extends Component {
198
279
  return;
199
280
  }
200
281
 
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
- }
282
+ // Centrer le QR code
283
+ const qrPixelSize = this.qrMatrix.length * this.moduleSize;
284
+ const offsetX = (this.width - qrPixelSize) / 2;
285
+ const offsetY = (this.height - qrPixelSize) / 2;
215
286
 
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
- );
287
+ // Dessiner les modules
288
+ ctx.fillStyle = this.foregroundColor;
289
+
290
+ for (let y = 0; y < this.qrMatrix.length; y++) {
291
+ for (let x = 0; x < this.qrMatrix[y].length; x++) {
292
+ if (this.qrMatrix[y][x] === 1) {
293
+ ctx.fillRect(
294
+ this.x + offsetX + x * this.moduleSize,
295
+ this.y + offsetY + y * this.moduleSize,
296
+ this.moduleSize,
297
+ this.moduleSize
298
+ );
299
+ }
300
+ }
225
301
  }
226
302
 
227
303
  ctx.restore();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canvasframework",
3
- "version": "0.5.56",
3
+ "version": "0.5.57",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/beyons/CanvasFramework.git"