canvasframework 0.3.26 → 0.3.27

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.
@@ -280,6 +280,218 @@ class Camera extends Component {
280
280
  }
281
281
  }
282
282
 
283
+ drawContainIcon(ctx, x, y, size) {
284
+ // Icône "contain" : rectangle avec flèches vers l'intérieur
285
+ const pad = size * 0.2;
286
+ ctx.strokeStyle = '#000';
287
+ ctx.lineWidth = 2;
288
+
289
+ // Rectangle extérieur
290
+ ctx.strokeRect(x + pad, y + pad, size - pad * 2, size - pad * 2);
291
+
292
+ // Flèches pointant vers l'intérieur
293
+ const arrowSize = size * 0.15;
294
+ ctx.fillStyle = '#000';
295
+
296
+ // Flèche haut
297
+ ctx.beginPath();
298
+ ctx.moveTo(x + size/2, y + pad - 2);
299
+ ctx.lineTo(x + size/2 - arrowSize, y + pad + arrowSize);
300
+ ctx.lineTo(x + size/2 + arrowSize, y + pad + arrowSize);
301
+ ctx.fill();
302
+
303
+ // Flèche bas
304
+ ctx.beginPath();
305
+ ctx.moveTo(x + size/2, y + size - pad + 2);
306
+ ctx.lineTo(x + size/2 - arrowSize, y + size - pad - arrowSize);
307
+ ctx.lineTo(x + size/2 + arrowSize, y + size - pad - arrowSize);
308
+ ctx.fill();
309
+
310
+ // Flèche gauche
311
+ ctx.beginPath();
312
+ ctx.moveTo(x + pad - 2, y + size/2);
313
+ ctx.lineTo(x + pad + arrowSize, y + size/2 - arrowSize);
314
+ ctx.lineTo(x + pad + arrowSize, y + size/2 + arrowSize);
315
+ ctx.fill();
316
+
317
+ // Flèche droite
318
+ ctx.beginPath();
319
+ ctx.moveTo(x + size - pad + 2, y + size/2);
320
+ ctx.lineTo(x + size - pad - arrowSize, y + size/2 - arrowSize);
321
+ ctx.lineTo(x + size - pad - arrowSize, y + size/2 + arrowSize);
322
+ ctx.fill();
323
+ }
324
+
325
+ drawCoverIcon(ctx, x, y, size) {
326
+ // Icône "cover" : rectangle avec flèches vers l'extérieur
327
+ const pad = size * 0.2;
328
+ ctx.strokeStyle = '#000';
329
+ ctx.lineWidth = 2;
330
+
331
+ // Rectangle intérieur
332
+ ctx.strokeRect(x + pad, y + pad, size - pad * 2, size - pad * 2);
333
+
334
+ // Flèches pointant vers l'extérieur
335
+ const arrowSize = size * 0.15;
336
+ ctx.fillStyle = '#000';
337
+
338
+ // Flèche haut
339
+ ctx.beginPath();
340
+ ctx.moveTo(x + size/2, y + 2);
341
+ ctx.lineTo(x + size/2 - arrowSize, y + arrowSize + 2);
342
+ ctx.lineTo(x + size/2 + arrowSize, y + arrowSize + 2);
343
+ ctx.fill();
344
+
345
+ // Flèche bas
346
+ ctx.beginPath();
347
+ ctx.moveTo(x + size/2, y + size - 2);
348
+ ctx.lineTo(x + size/2 - arrowSize, y + size - arrowSize - 2);
349
+ ctx.lineTo(x + size/2 + arrowSize, y + size - arrowSize - 2);
350
+ ctx.fill();
351
+
352
+ // Flèche gauche
353
+ ctx.beginPath();
354
+ ctx.moveTo(x + 2, y + size/2);
355
+ ctx.lineTo(x + arrowSize + 2, y + size/2 - arrowSize);
356
+ ctx.lineTo(x + arrowSize + 2, y + size/2 + arrowSize);
357
+ ctx.fill();
358
+
359
+ // Flèche droite
360
+ ctx.beginPath();
361
+ ctx.moveTo(x + size - 2, y + size/2);
362
+ ctx.lineTo(x + size - arrowSize - 2, y + size/2 - arrowSize);
363
+ ctx.lineTo(x + size - arrowSize - 2, y + size/2 + arrowSize);
364
+ ctx.fill();
365
+ }
366
+
367
+ drawContainIcon(ctx, x, y, size) {
368
+ // Icône "contain" : rectangle avec flèches vers l'intérieur
369
+ const pad = size * 0.2;
370
+ ctx.strokeStyle = '#000';
371
+ ctx.lineWidth = 2;
372
+
373
+ // Rectangle extérieur
374
+ ctx.strokeRect(x + pad, y + pad, size - pad * 2, size - pad * 2);
375
+
376
+ // Flèches pointant vers l'intérieur
377
+ const arrowSize = size * 0.15;
378
+ ctx.fillStyle = '#000';
379
+
380
+ // Flèche haut
381
+ ctx.beginPath();
382
+ ctx.moveTo(x + size/2, y + pad - 2);
383
+ ctx.lineTo(x + size/2 - arrowSize, y + pad + arrowSize);
384
+ ctx.lineTo(x + size/2 + arrowSize, y + pad + arrowSize);
385
+ ctx.fill();
386
+
387
+ // Flèche bas
388
+ ctx.beginPath();
389
+ ctx.moveTo(x + size/2, y + size - pad + 2);
390
+ ctx.lineTo(x + size/2 - arrowSize, y + size - pad - arrowSize);
391
+ ctx.lineTo(x + size/2 + arrowSize, y + size - pad - arrowSize);
392
+ ctx.fill();
393
+
394
+ // Flèche gauche
395
+ ctx.beginPath();
396
+ ctx.moveTo(x + pad - 2, y + size/2);
397
+ ctx.lineTo(x + pad + arrowSize, y + size/2 - arrowSize);
398
+ ctx.lineTo(x + pad + arrowSize, y + size/2 + arrowSize);
399
+ ctx.fill();
400
+
401
+ // Flèche droite
402
+ ctx.beginPath();
403
+ ctx.moveTo(x + size - pad + 2, y + size/2);
404
+ ctx.lineTo(x + size - pad - arrowSize, y + size/2 - arrowSize);
405
+ ctx.lineTo(x + size - pad - arrowSize, y + size/2 + arrowSize);
406
+ ctx.fill();
407
+ }
408
+
409
+ drawCoverIcon(ctx, x, y, size) {
410
+ // Icône "cover" : rectangle avec flèches vers l'extérieur
411
+ const pad = size * 0.2;
412
+ ctx.strokeStyle = '#000';
413
+ ctx.lineWidth = 2;
414
+
415
+ // Rectangle intérieur
416
+ ctx.strokeRect(x + pad, y + pad, size - pad * 2, size - pad * 2);
417
+
418
+ // Flèches pointant vers l'extérieur
419
+ const arrowSize = size * 0.15;
420
+ ctx.fillStyle = '#000';
421
+
422
+ // Flèche haut
423
+ ctx.beginPath();
424
+ ctx.moveTo(x + size/2, y + 2);
425
+ ctx.lineTo(x + size/2 - arrowSize, y + arrowSize + 2);
426
+ ctx.lineTo(x + size/2 + arrowSize, y + arrowSize + 2);
427
+ ctx.fill();
428
+
429
+ // Flèche bas
430
+ ctx.beginPath();
431
+ ctx.moveTo(x + size/2, y + size - 2);
432
+ ctx.lineTo(x + size/2 - arrowSize, y + size - arrowSize - 2);
433
+ ctx.lineTo(x + size/2 + arrowSize, y + size - arrowSize - 2);
434
+ ctx.fill();
435
+
436
+ // Flèche gauche
437
+ ctx.beginPath();
438
+ ctx.moveTo(x + 2, y + size/2);
439
+ ctx.lineTo(x + arrowSize + 2, y + size/2 - arrowSize);
440
+ ctx.lineTo(x + arrowSize + 2, y + size/2 + arrowSize);
441
+ ctx.fill();
442
+
443
+ // Flèche droite
444
+ ctx.beginPath();
445
+ ctx.moveTo(x + size - 2, y + size/2);
446
+ ctx.lineTo(x + size - arrowSize - 2, y + size/2 - arrowSize);
447
+ ctx.lineTo(x + size - arrowSize - 2, y + size/2 + arrowSize);
448
+ ctx.fill();
449
+ }
450
+
451
+ drawSwitchCameraIcon(ctx, x, y, size) {
452
+ // Icône de switch caméra : deux caméras avec flèche circulaire
453
+ const centerX = x + size / 2;
454
+ const centerY = y + size / 2;
455
+ const radius = size * 0.35;
456
+
457
+ ctx.strokeStyle = '#ffffff';
458
+ ctx.lineWidth = 3;
459
+ ctx.lineCap = 'round';
460
+
461
+ // Arc circulaire (flèche de rotation)
462
+ ctx.beginPath();
463
+ ctx.arc(centerX, centerY, radius, -Math.PI * 0.7, Math.PI * 0.7);
464
+ ctx.stroke();
465
+
466
+ // Flèche en haut à droite
467
+ const arrowSize = size * 0.15;
468
+ const arrowAngle = Math.PI * 0.7;
469
+ const arrowX = centerX + radius * Math.cos(arrowAngle);
470
+ const arrowY = centerY + radius * Math.sin(arrowAngle);
471
+
472
+ ctx.fillStyle = '#ffffff';
473
+ ctx.beginPath();
474
+ ctx.moveTo(arrowX, arrowY);
475
+ ctx.lineTo(arrowX - arrowSize, arrowY - arrowSize * 0.5);
476
+ ctx.lineTo(arrowX - arrowSize * 0.5, arrowY + arrowSize);
477
+ ctx.fill();
478
+
479
+ // Mini caméra au centre
480
+ const camWidth = size * 0.25;
481
+ const camHeight = size * 0.18;
482
+ const camX = centerX - camWidth / 2;
483
+ const camY = centerY - camHeight / 2;
484
+
485
+ ctx.fillStyle = '#ffffff';
486
+ ctx.fillRect(camX, camY, camWidth, camHeight);
487
+
488
+ // Objectif
489
+ ctx.fillStyle = '#000';
490
+ ctx.beginPath();
491
+ ctx.arc(centerX, centerY, size * 0.08, 0, Math.PI * 2);
492
+ ctx.fill();
493
+ }
494
+
283
495
  draw(ctx) {
284
496
  ctx.save();
285
497
 
@@ -340,7 +552,9 @@ class Camera extends Component {
340
552
  // Mini preview dernière photo (bas droite, 3s)
341
553
  if (this.previewPhoto) {
342
554
  const previewSize = 80;
343
- ctx.drawImage(this.previewPhoto, this.x + this.width - previewSize - 10, this.y + this.height - previewSize - 10, previewSize, previewSize);
555
+ const img = new Image();
556
+ img.src = this.previewPhoto;
557
+ ctx.drawImage(img, this.x + this.width - previewSize - 10, this.y + this.height - previewSize - 10, previewSize, previewSize);
344
558
  ctx.strokeStyle = '#fff';
345
559
  ctx.lineWidth = 2;
346
560
  ctx.strokeRect(this.x + this.width - previewSize - 10, this.y + this.height - previewSize - 10, previewSize, previewSize);
@@ -363,10 +577,19 @@ class Camera extends Component {
363
577
  ctx.arc(this.x + this.width/2, this.y + this.height - 50, this.captureButtonRadius + 10, 0, Math.PI * 2);
364
578
  ctx.stroke();
365
579
 
366
- // Switch caméra
367
- ctx.fillStyle = '#ffffff';
368
- ctx.font = '28px Arial';
369
- ctx.fillText('↻', this.x + 20, this.y + 45);
580
+ // Switch caméra avec icône
581
+ const switchBtnX = this.x + 20;
582
+ const switchBtnY = this.y + 20;
583
+ const switchBtnSize = 50;
584
+
585
+ // Fond semi-transparent
586
+ ctx.fillStyle = 'rgba(0,0,0,0.5)';
587
+ ctx.beginPath();
588
+ ctx.arc(switchBtnX + switchBtnSize/2, switchBtnY + switchBtnSize/2, switchBtnSize/2, 0, Math.PI * 2);
589
+ ctx.fill();
590
+
591
+ // Icône
592
+ this.drawSwitchCameraIcon(ctx, switchBtnX, switchBtnY, switchBtnSize);
370
593
 
371
594
  // Torch
372
595
  if (this.torchSupported) {
@@ -374,16 +597,25 @@ class Camera extends Component {
374
597
  ctx.fillText('⚡', this.x + this.width - 50, this.y + 45);
375
598
  }
376
599
 
377
- // Bouton switch mode
378
- ctx.fillStyle = '#ffffff';
379
- ctx.fillRect(this.x + this.width - 80, this.y + 20, this.modeButtonSize, this.modeButtonSize);
380
- ctx.fillStyle = '#000';
381
- ctx.font = '14px Arial';
382
- ctx.textAlign = 'center';
383
- ctx.textBaseline = 'middle';
384
- ctx.fillText(this.fitMode.toUpperCase().slice(0, 4),
385
- this.x + this.width - 80 + this.modeButtonSize/2,
386
- this.y + 20 + this.modeButtonSize/2);
600
+ // Bouton switch mode avec icône
601
+ const btnX = this.x + this.width - 80;
602
+ const btnY = this.y + 20;
603
+
604
+ // Fond du bouton
605
+ ctx.fillStyle = 'rgba(255,255,255,0.9)';
606
+ ctx.fillRect(btnX, btnY, this.modeButtonSize, this.modeButtonSize);
607
+
608
+ // Bordure
609
+ ctx.strokeStyle = '#000';
610
+ ctx.lineWidth = 2;
611
+ ctx.strokeRect(btnX, btnY, this.modeButtonSize, this.modeButtonSize);
612
+
613
+ // Dessiner l'icône appropriée
614
+ if (this.fitMode === 'contain') {
615
+ this.drawContainIcon(ctx, btnX, btnY, this.modeButtonSize);
616
+ } else {
617
+ this.drawCoverIcon(ctx, btnX, btnY, this.modeButtonSize);
618
+ }
387
619
 
388
620
  ctx.restore();
389
621
  }
@@ -135,6 +135,7 @@ const FIXED_COMPONENT_TYPES = new Set([
135
135
  FAB,
136
136
  Toast,
137
137
  Banner,
138
+ Camera,
138
139
  SliverAppBar,
139
140
  BottomSheet,
140
141
  ContextMenu,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canvasframework",
3
- "version": "0.3.26",
3
+ "version": "0.3.27",
4
4
  "description": "Canvas-based cross-platform UI framework (Material & Cupertino)",
5
5
  "type": "module",
6
6
  "main": "./index.js",