canvasframework 0.5.55 → 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.
@@ -0,0 +1,307 @@
1
+ import Component from '../core/Component.js';
2
+
3
+ /**
4
+ * QRCodeGenerator SANS librairie externe
5
+ * Version simplifiée qui fonctionne pour texte court et URLs
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 || 'Hello';
22
+
23
+ // Dimensions
24
+ this.width = options.width || 250;
25
+ this.height = options.height || 250;
26
+ this.qrSize = Math.min(this.width, this.height);
27
+
28
+ // Options visuelles
29
+ this.backgroundColor = options.backgroundColor || '#ffffff';
30
+ this.foregroundColor = options.foregroundColor || '#000000';
31
+ this.padding = options.padding || 20;
32
+
33
+ // État
34
+ this.qrMatrix = null;
35
+ this.moduleSize = 0;
36
+
37
+ // Générer immédiatement
38
+ this.generateQRCode();
39
+ }
40
+
41
+ async _mount() {
42
+ super._mount?.();
43
+ if (!this.qrMatrix) {
44
+ this.generateQRCode();
45
+ }
46
+ }
47
+
48
+ destroy() {
49
+ this.qrMatrix = null;
50
+ super.destroy?.();
51
+ }
52
+
53
+ onUnmount() {
54
+ console.log('[QRCodeGenerator] onUnmount called');
55
+ this.qrMatrix = null;
56
+ }
57
+
58
+ /**
59
+ * Génère un QR code simple (Version 1 : 21x21)
60
+ */
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);
82
+ this.markDirty();
83
+
84
+ } catch (err) {
85
+ console.error('[QRCodeGenerator] Error:', err);
86
+ }
87
+ }
88
+
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
96
+ }
97
+ return matrix;
98
+ }
99
+
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
+ }
127
+
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;
142
+ }
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
+ }
155
+
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
+ }
172
+
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
+ }
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Change les données et régénère
243
+ */
244
+ async setData(newData) {
245
+ if (this.data === newData) return;
246
+ this.data = newData;
247
+ this.generateQRCode();
248
+ }
249
+
250
+ /**
251
+ * Change la taille
252
+ */
253
+ async setSize(newSize) {
254
+ this.width = newSize;
255
+ this.height = newSize;
256
+ this.qrSize = newSize;
257
+ this.generateQRCode();
258
+ }
259
+
260
+ draw(ctx) {
261
+ ctx.save();
262
+
263
+ // Fond
264
+ ctx.fillStyle = this.backgroundColor;
265
+ ctx.fillRect(this.x, this.y, this.width, this.height);
266
+
267
+ if (!this.qrMatrix || this.moduleSize === 0) {
268
+ // Message de chargement
269
+ ctx.fillStyle = '#666';
270
+ ctx.font = '14px Arial';
271
+ ctx.textAlign = 'center';
272
+ ctx.textBaseline = 'middle';
273
+ ctx.fillText(
274
+ 'Génération...',
275
+ this.x + this.width / 2,
276
+ this.y + this.height / 2
277
+ );
278
+ ctx.restore();
279
+ return;
280
+ }
281
+
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;
286
+
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
+ }
301
+ }
302
+
303
+ ctx.restore();
304
+ }
305
+ }
306
+
307
+ export default QRCodeGenerator;
@@ -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';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canvasframework",
3
- "version": "0.5.55",
3
+ "version": "0.5.57",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/beyons/CanvasFramework.git"