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.
- package/components/Camera.js +146 -140
- package/components/FloatedCamera.js +173 -228
- package/components/PDFViewer.js +1069 -0
- package/core/CanvasFramework.js +1 -0
- package/core/UIBuilder.js +2 -0
- package/index.js +1 -0
- package/package.json +1 -1
package/components/Camera.js
CHANGED
|
@@ -280,35 +280,34 @@ class Camera extends Component {
|
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
handlePress(relX, relY) {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
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
|
-
|
|
526
|
+
ctx.save();
|
|
528
527
|
|
|
529
|
-
|
|
530
|
-
|
|
528
|
+
ctx.fillStyle = '#000';
|
|
529
|
+
ctx.fillRect(this.x, this.y, this.width, this.height);
|
|
531
530
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
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
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
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
|
-
|
|
596
|
-
|
|
597
|
-
|
|
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
|
-
|
|
600
|
-
|
|
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(
|
|
630
|
+
ctx.arc(torchBtnX + torchBtnSize/2, torchBtnY + torchBtnSize/2, torchBtnSize/2, 0, Math.PI * 2);
|
|
603
631
|
ctx.fill();
|
|
604
632
|
|
|
605
|
-
ctx.
|
|
606
|
-
ctx.
|
|
607
|
-
ctx.
|
|
608
|
-
ctx.
|
|
609
|
-
ctx.
|
|
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
|
-
|
|
612
|
-
|
|
613
|
-
|
|
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
|
-
|
|
626
|
-
|
|
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
|
-
|
|
632
|
-
|
|
633
|
-
|
|
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
|
-
|
|
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;
|