I am trying to create a Timer in React by using Canvas and PictureInPicture so that whenever the user closes the window it will keep running in the background or on Desktop Screen. But It's not working. Remember it should be in React.I tried in HTML Javascript and it works well but it's not happening in React.js
import { React, useState, useRef, useEffect } from "react";
import {FaPauseCircle} from 'react-icons/fa'
import {AiFillPlayCircle} from 'react-icons/ai'
import {BsFillPipFill} from 'react-icons/bs' //importing icons
import './timer.scss'
//import { render } from '@testing-library/react'
function Timer() {
const videoElement = useRef();
const [icon, setIcon] = useState(false); //setting icon state false as default
const [timerFlag, setTimerFlag] = useState(false);
const [isDisabled, setIsDisabled] = useState(false);
const [totalSeconds, setTotalSeconds] = useState(0);
const anim = (source, ctx) => { // creating a ctx as object for canvas and saving it to a variable. This is where we’ll actually be drawing on.
console.log('>>>', ctx)
// error detected
ctx.fillStyle = "black";
ctx.fillRect(0, 0, source.width, source.height);
ctx.fillStyle = "white";
ctx.fillText( output(), source.width / 2, source.height / 2 );
//window.requestAnimationFrame(anim);
}
const init = () => {
const videoElement = document.createElement('video');
const source = document.createElement('canvas');
const ctx = source.getContext('2d');
ctx.font = "50px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
console.log('>>', ctx)
anim(source, ctx);
const stream = source.captureStream();
//videoElement. srcObject= stream;
console.log('SOURRRR', source);
}
const openPictureInPicture = async (videoElement) => {
if (!videoElement.hasAttribute('isPip')) { // PictureinPicture videoElementting
await videoElement.requestPictureInPicture();
videoElement.setAttribute('isPip', true);
videoElement.addEventListener('leavepictureinpicture', event => {
videoElement.removeAttribute('isPip')
}, {
once: true
})
} else {
await document.exitPictureInPicture();
}
}
function pad(val) {
var valString = val + "";
if (valString.length < 2) {
return "0" + valString; //Timer mentionin 00:00:00))
} else {
return valString;
}
}
const buttonClick = (e, videoElement) => {
if( <videoElement className="requestPictureInPicture"></videoElement> ) {
openPictureInPicture(videoElement);
}
else { // videoElementting the PictureinPicture when we move from screen to screen
setIsDisabled(true);
}
}
function timerSwitch() {
var myDate = new Date();
console.log(myDate.toLocaleTimeString('en-US'))
setTimerFlag(!timerFlag);
if (timerFlag) {
setIcon(true);
}else {
setIcon(false); //Here the timer is getting Started when we click on Button to start the timer
}
}
function output() { //
let result = null;
if (totalSeconds === 0) { //Initially setting timer setting to 00:00:00
result = "00:00:00";
}else {
result = pad(parseInt(totalSeconds / (60 * 60))).toString() + ":" + pad(parseInt((totalSeconds % (60 * 60) / 60))).toString() + ":" + pad(totalSeconds % 60).toString();
} //Here , Calculation of timing is done where actual timer is performing
return result;
}
useEffect(() => {
init();
setInterval(function() { //Everytime timer is updated every second ..
if (timerFlag) {
setTotalSeconds(++totalSeconds);
}
}, 1000);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
return (
<div className="timer-container ">
{/* <video ref={videoElement} muted autoPlay height="100px" width="100px"></video> Here By using Video PictureInPicutre is being videoElementted to call */}
<button
className="stop-start"
onClick={() => {
timerSwitch();
}}
type="button"
>
{icon ? <AiFillPlayCircle /> : <FaPauseCircle />}
</button>
<button className="pip" disabled={isDisabled} onClick={(e) => buttonClick(e)}>
<BsFillPipFill /> {/* By Default PIP is disabled until we click to stat its functionality */}
</button>
</div>
);
}
export default Timer; ```
Here is the Output
× Unhandled Rejection (TypeError): Cannot read properties of undefined (reading 'hasAttribute')
const buttonClick = (e, videoElement) => {
if( <videoElement className="requestPictureInPicture"></videoElement> ) {
**openPictureInPicture(videoElement);**//here is the another error
}
else { // videoElementting the PictureinPicture when we move from screen to screen
setIsDisabled(true);
}
}
Aucun commentaire:
Enregistrer un commentaire