canvasframework 0.5.60 → 0.5.62

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,35 +280,34 @@ class Camera extends Component {
280
280
  }
281
281
 
282
282
  handlePress(relX, relY) {
283
-
284
- // Capture centrale
285
- const captureX = this.width / 2;
286
- const captureY = this.height - 60;
287
- if (Math.hypot(relX - captureX, relY - captureY) < this.captureButtonRadius + 10) {
288
- this.capturePhoto();
289
- return;
290
- }
291
-
292
- // Switch caméra
293
- if (relX < 60 && relY < 60) {
294
- this.switchCamera();
295
- return;
296
- }
297
-
298
- // Torch
299
- if (this.torchSupported && relX > this.width - 60 && relY < 60) {
300
- this.toggleTorch();
301
- return;
302
- }
303
-
304
- // Switch mode
305
- const modeButtonX = this.width - 80;
306
- const modeButtonY = 20;
307
- if (relX > modeButtonX && relX < modeButtonX + this.modeButtonSize &&
308
- relY > modeButtonY && relY < modeButtonY + this.modeButtonSize) {
309
- this.switchFitMode();
310
- return;
311
- }
283
+ // Capture centrale
284
+ const captureX = this.width / 2;
285
+ const captureY = this.height - 60;
286
+ if (Math.hypot(relX - captureX, relY - captureY) < this.captureButtonRadius + 10) {
287
+ this.capturePhoto();
288
+ return;
289
+ }
290
+
291
+ // Switch caméra (haut gauche)
292
+ if (relX < 70 && relY < 70) {
293
+ this.switchCamera();
294
+ return;
295
+ }
296
+
297
+ // Torch (haut droite) - zone précise
298
+ if (this.torchSupported && relX > this.width - 75 && relX < this.width - 25 && relY > 20 && relY < 70) {
299
+ this.toggleTorch();
300
+ return;
301
+ }
302
+
303
+ // Switch mode (haut droite, décalé à gauche de la torche)
304
+ const modeButtonX = this.width - 130;
305
+ const modeButtonY = 20;
306
+ if (relX > modeButtonX && relX < modeButtonX + this.modeButtonSize &&
307
+ relY > modeButtonY && relY < modeButtonY + this.modeButtonSize) {
308
+ this.switchFitMode();
309
+ return;
310
+ }
312
311
  }
313
312
 
314
313
  drawContainIcon(ctx, x, y, size) {
@@ -524,132 +523,139 @@ class Camera extends Component {
524
523
  }
525
524
 
526
525
  draw(ctx) {
527
- ctx.save();
526
+ ctx.save();
528
527
 
529
- ctx.fillStyle = '#000';
530
- ctx.fillRect(this.x, this.y, this.width, this.height);
528
+ ctx.fillStyle = '#000';
529
+ ctx.fillRect(this.x, this.y, this.width, this.height);
531
530
 
532
- // Flash blanc après capture
533
- if (this.flashTimer) {
534
- ctx.fillStyle = 'rgba(255,255,255,0.6)';
535
- ctx.fillRect(this.x, this.y, this.width, this.height);
536
- }
531
+ // Flash blanc après capture
532
+ if (this.flashTimer) {
533
+ ctx.fillStyle = 'rgba(255,255,255,0.6)';
534
+ ctx.fillRect(this.x, this.y, this.width, this.height);
535
+ }
537
536
 
538
- if (this.error) {
539
- ctx.fillStyle = '#ff4444';
540
- ctx.font = '16px Arial';
541
- ctx.textAlign = 'center';
542
- ctx.textBaseline = 'middle';
543
- ctx.fillText(this.error, this.x + this.width/2, this.y + this.height/2);
544
- } else if (!this.loaded) {
545
- ctx.fillStyle = '#fff';
546
- ctx.font = '16px Arial';
547
- ctx.textAlign = 'center';
548
- ctx.textBaseline = 'middle';
549
- ctx.fillText('Démarrage caméra...', this.x + this.width/2, this.y + this.height/2);
550
- } else if (this.video && this.loaded) {
551
- const videoRatio = this.video.videoWidth / this.video.videoHeight;
552
- const canvasRatio = this.width / this.height;
553
-
554
- let drawWidth = this.width;
555
- let drawHeight = this.height;
556
- let offsetX = 0;
557
- let offsetY = 0;
558
-
559
- if (this.fitMode === 'cover') {
560
- if (videoRatio > canvasRatio) {
561
- drawHeight = this.height;
562
- drawWidth = drawHeight * videoRatio;
563
- offsetX = (this.width - drawWidth) / 2;
564
- } else {
565
- drawWidth = this.width;
566
- drawHeight = drawWidth / videoRatio;
567
- offsetY = (this.height - drawHeight) / 2;
568
- }
569
- } else if (this.fitMode === 'contain') {
570
- if (videoRatio > canvasRatio) {
571
- drawWidth = this.width;
572
- drawHeight = drawWidth / videoRatio;
573
- offsetY = (this.height - drawHeight) / 2;
574
- } else {
575
- drawHeight = this.height;
576
- drawWidth = drawHeight * videoRatio;
577
- offsetX = (this.width - drawWidth) / 2;
578
- }
579
- }
580
-
581
- ctx.drawImage(this.video, this.x + offsetX, this.y + offsetY, drawWidth, drawHeight);
582
-
583
- // Mini preview dernière photo (bas droite, 3s)
584
- if (this.previewPhoto) {
585
- const previewSize = 80;
586
- const img = new Image();
587
- img.src = this.previewPhoto;
588
- ctx.drawImage(img, this.x + this.width - previewSize - 10, this.y + this.height - previewSize - 10, previewSize, previewSize);
589
- ctx.strokeStyle = '#fff';
590
- ctx.lineWidth = 2;
591
- ctx.strokeRect(this.x + this.width - previewSize - 10, this.y + this.height - previewSize - 10, previewSize, previewSize);
537
+ if (this.error) {
538
+ ctx.fillStyle = '#ff4444';
539
+ ctx.font = '16px Arial';
540
+ ctx.textAlign = 'center';
541
+ ctx.textBaseline = 'middle';
542
+ ctx.fillText(this.error, this.x + this.width/2, this.y + this.height/2);
543
+ } else if (!this.loaded) {
544
+ ctx.fillStyle = '#fff';
545
+ ctx.font = '16px Arial';
546
+ ctx.textAlign = 'center';
547
+ ctx.textBaseline = 'middle';
548
+ ctx.fillText('Démarrage caméra...', this.x + this.width/2, this.y + this.height/2);
549
+ } else if (this.video && this.loaded) {
550
+ const videoRatio = this.video.videoWidth / this.video.videoHeight;
551
+ const canvasRatio = this.width / this.height;
552
+
553
+ let drawWidth = this.width;
554
+ let drawHeight = this.height;
555
+ let offsetX = 0;
556
+ let offsetY = 0;
557
+
558
+ if (this.fitMode === 'cover') {
559
+ if (videoRatio > canvasRatio) {
560
+ drawHeight = this.height;
561
+ drawWidth = drawHeight * videoRatio;
562
+ offsetX = (this.width - drawWidth) / 2;
563
+ } else {
564
+ drawWidth = this.width;
565
+ drawHeight = drawWidth / videoRatio;
566
+ offsetY = (this.height - drawHeight) / 2;
567
+ }
568
+ } else if (this.fitMode === 'contain') {
569
+ if (videoRatio > canvasRatio) {
570
+ drawWidth = this.width;
571
+ drawHeight = drawWidth / videoRatio;
572
+ offsetY = (this.height - drawHeight) / 2;
573
+ } else {
574
+ drawHeight = this.height;
575
+ drawWidth = drawHeight * videoRatio;
576
+ offsetX = (this.width - drawWidth) / 2;
592
577
  }
593
578
  }
594
579
 
595
- // Contrôles bas
596
- ctx.fillStyle = 'rgba(0,0,0,0.5)';
597
- ctx.fillRect(this.x, this.y + this.height - 100, this.width, 100);
580
+ ctx.drawImage(this.video, this.x + offsetX, this.y + offsetY, drawWidth, drawHeight);
581
+
582
+ // Mini preview dernière photo (bas droite, 3s)
583
+ if (this.previewPhoto) {
584
+ const previewSize = 80;
585
+ const img = new Image();
586
+ img.src = this.previewPhoto;
587
+ ctx.drawImage(img, this.x + this.width - previewSize - 10, this.y + this.height - previewSize - 10, previewSize, previewSize);
588
+ ctx.strokeStyle = '#fff';
589
+ ctx.lineWidth = 2;
590
+ ctx.strokeRect(this.x + this.width - previewSize - 10, this.y + this.height - previewSize - 10, previewSize, previewSize);
591
+ }
592
+ }
598
593
 
599
- // Bouton capture
600
- ctx.fillStyle = '#ffffff';
594
+ // Contrôles bas
595
+ ctx.fillStyle = 'rgba(0,0,0,0.5)';
596
+ ctx.fillRect(this.x, this.y + this.height - 100, this.width, 100);
597
+
598
+ // Bouton capture
599
+ ctx.fillStyle = '#ffffff';
600
+ ctx.beginPath();
601
+ ctx.arc(this.x + this.width/2, this.y + this.height - 50, this.captureButtonRadius, 0, Math.PI * 2);
602
+ ctx.fill();
603
+
604
+ ctx.strokeStyle = '#ff4444';
605
+ ctx.lineWidth = 6;
606
+ ctx.beginPath();
607
+ ctx.arc(this.x + this.width/2, this.y + this.height - 50, this.captureButtonRadius + 10, 0, Math.PI * 2);
608
+ ctx.stroke();
609
+
610
+ // Switch caméra avec icône
611
+ const switchBtnX = this.x + 20;
612
+ const switchBtnY = this.y + 20;
613
+ const switchBtnSize = 50;
614
+
615
+ ctx.fillStyle = 'rgba(0,0,0,0.5)';
616
+ ctx.beginPath();
617
+ ctx.arc(switchBtnX + switchBtnSize/2, switchBtnY + switchBtnSize/2, switchBtnSize/2, 0, Math.PI * 2);
618
+ ctx.fill();
619
+
620
+ this.drawSwitchCameraIcon(ctx, switchBtnX, switchBtnY, switchBtnSize);
621
+
622
+ // Bouton torche (haut droite)
623
+ if (this.torchSupported) {
624
+ const torchBtnX = this.x + this.width - 75;
625
+ const torchBtnY = this.y + 20;
626
+ const torchBtnSize = 50;
627
+
628
+ ctx.fillStyle = this.torchOn ? 'rgba(255,235,59,0.8)' : 'rgba(0,0,0,0.5)';
601
629
  ctx.beginPath();
602
- ctx.arc(this.x + this.width/2, this.y + this.height - 50, this.captureButtonRadius, 0, Math.PI * 2);
630
+ ctx.arc(torchBtnX + torchBtnSize/2, torchBtnY + torchBtnSize/2, torchBtnSize/2, 0, Math.PI * 2);
603
631
  ctx.fill();
604
632
 
605
- ctx.strokeStyle = '#ff4444';
606
- ctx.lineWidth = 6;
607
- ctx.beginPath();
608
- ctx.arc(this.x + this.width/2, this.y + this.height - 50, this.captureButtonRadius + 10, 0, Math.PI * 2);
609
- ctx.stroke();
633
+ ctx.fillStyle = '#fff';
634
+ ctx.font = '24px Arial';
635
+ ctx.textAlign = 'center';
636
+ ctx.textBaseline = 'middle';
637
+ ctx.fillText('⚡', torchBtnX + torchBtnSize/2, torchBtnY + torchBtnSize/2);
638
+ }
610
639
 
611
- // Switch caméra avec icône
612
- const switchBtnX = this.x + 20;
613
- const switchBtnY = this.y + 20;
614
- const switchBtnSize = 50;
615
-
616
- // Fond semi-transparent
617
- ctx.fillStyle = 'rgba(0,0,0,0.5)';
618
- ctx.beginPath();
619
- ctx.arc(switchBtnX + switchBtnSize/2, switchBtnY + switchBtnSize/2, switchBtnSize/2, 0, Math.PI * 2);
620
- ctx.fill();
621
-
622
- // Icône
623
- this.drawSwitchCameraIcon(ctx, switchBtnX, switchBtnY, switchBtnSize);
640
+ // Bouton switch mode (décalé à gauche de la torche)
641
+ const btnX = this.x + this.width - 130;
642
+ const btnY = this.y + 20;
624
643
 
625
- // Torch
626
- if (this.torchSupported) {
627
- ctx.fillStyle = this.torchOn ? '#ffeb3b' : '#ffffff';
628
- ctx.fillText('⚡', this.x + this.width - 50, this.y + 45);
629
- }
644
+ ctx.fillStyle = 'rgba(255,255,255,0.9)';
645
+ ctx.fillRect(btnX, btnY, this.modeButtonSize, this.modeButtonSize);
630
646
 
631
- // Bouton switch mode avec icône
632
- const btnX = this.x + this.width - 80;
633
- const btnY = this.y + 20;
634
-
635
- // Fond du bouton
636
- ctx.fillStyle = 'rgba(255,255,255,0.9)';
637
- ctx.fillRect(btnX, btnY, this.modeButtonSize, this.modeButtonSize);
638
-
639
- // Bordure
640
- ctx.strokeStyle = '#000';
641
- ctx.lineWidth = 2;
642
- ctx.strokeRect(btnX, btnY, this.modeButtonSize, this.modeButtonSize);
643
-
644
- // Dessiner l'icône appropriée
645
- if (this.fitMode === 'contain') {
646
- this.drawContainIcon(ctx, btnX, btnY, this.modeButtonSize);
647
- } else {
648
- this.drawCoverIcon(ctx, btnX, btnY, this.modeButtonSize);
649
- }
647
+ ctx.strokeStyle = '#000';
648
+ ctx.lineWidth = 2;
649
+ ctx.strokeRect(btnX, btnY, this.modeButtonSize, this.modeButtonSize);
650
650
 
651
- ctx.restore();
651
+ if (this.fitMode === 'contain') {
652
+ this.drawContainIcon(ctx, btnX, btnY, this.modeButtonSize);
653
+ } else {
654
+ this.drawCoverIcon(ctx, btnX, btnY, this.modeButtonSize);
652
655
  }
656
+
657
+ ctx.restore();
658
+ }
653
659
  }
654
660
 
655
661
  export default Camera;