class CameraPage { constructor() { this.spinnerWeight = 10; this.spinnerColor = "#0F0FFF" this.canvas = document.getElementById("overlay-canvas"); this.ctx = this.canvas.getContext("2d"); this.video = document.getElementById("camera-video"); this.width; this.height; //calcule automatiquement en fonction de la largeur du flux vidéo this.videoWidth; this.videoHeight; this.streaming = false; this.activeEffects = []; this.images = {}; this._startup(); this._loadImages(); this._enabled = false; this.DOMElement = document.getElementById("camera"); } set enabled(val) { this._enabled = val; this.DOMElement.style.display = val ? "block" : "none"; if (val) { this._frame(); this.video.play(); }else { this.video.pause(); } } get enabled() { return this._enabled; } _startup() { navigator.mediaDevices .getUserMedia({ video: true, audio: false }) .then((stream) => { this.video.srcObject = stream; this.video.play(); }) .catch((err) => { console.error(`Erreur pendant la lecture de la camera: ${err}`); }); this.video.addEventListener( "canplay", (ev) => { if (!this.streaming) { //calcul de la taille de la vidéo en fonction de la taille de la fenêtre pour qu'elle soit toujours visible let aspectRatio = this.video.videoWidth / this.video.videoHeight; if (window.innerHeight * aspectRatio > window.innerWidth) { this.width = window.innerWidth; this.height = window.innerWidth / aspectRatio; } else { this.width = window.innerHeight * aspectRatio; this.height = window.innerHeight; } this.videoHeight = this.video.videoHeight; this.videoWidth = this.video.videoWidth; this.video.setAttribute("width", this.width); this.video.setAttribute("height", this.height); this.canvas.setAttribute("width", this.width); this.canvas.setAttribute("height", this.height); this.streaming = true; } }, false ); } _loadImages() { this.images.thumbsUp = new Image(); this.images.thumbsUp.src = "assets/img/thumbs_up.png"; this.images.thumbsDown = new Image(); this.images.thumbsDown.src = "assets/img/thumbs_down.png"; } _frame() { if (this.streaming && this.enabled && this.width && this.height) { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); this._drawEffects(); } if (this.enabled) { requestAnimationFrame(() => this._frame()); } } _scaleEffect(x, y, width, height) { let xScale = this.width / this.videoWidth; let yScale = this.height / this.videoHeight; return { x: x * xScale, y: y * yScale, width: width * xScale, height: height * yScale } } _drawEffects() { for (let effect of this.activeEffects) { let { x, y, width, height } = this._scaleEffect(effect.x, effect.y, effect.width, effect.height); width = width * this.videoWidth * 2; height = height * this.videoHeight * 2; x = x * this.videoWidth - width / 2; y = y * this.videoHeight - height / 2; console.log(width, height); if (effect.type == "thumbs_down") { this._drawThumbsDown(x, y, width, height); } if (effect.type == "thumbs_up") { this._drawThumbsUp(x, y, width, height); } if (effect.type == "loading") { this._drawLoading(x, y, width, effect.progress); } } } _drawLoading(x, y, radius, progress) { this.ctx.lineWidth = this.spinnerWeight; this.ctx.strokeStyle = this.spinnerColor; this.ctx.beginPath(); this.ctx.arc(x, y, radius, 0, progress * 2 * Math.PI); this.ctx.stroke(); } _drawThumbsDown(x, y, width, height) { this.ctx.beginPath(); this.ctx.drawImage(this.images.thumbsDown, x, y, width, height); this.ctx.stroke(); } _drawThumbsUp(x, y, width, height) { this.ctx.beginPath(); this.ctx.drawImage(this.images.thumbsUp, x, y, width, height); this.ctx.stroke(); } setEffects(effects) { this.activeEffects = effects; } }