TypeError: Cannot read property ‘canvas’ of undefined / React / Typescript

  canvas, javascript, reactjs, webrtc

I’m trying to change to gray the colors of the video on the canvas, this appears, when I update the code, but then it works, but after i push the button to change to gray, I get the same message and the gray color doesn’t work.

It has anything to be with the lifecycle? Also I need to do it in a class component. But I’m open to suggestions.

TypeError: Cannot read property ‘canvas’ of undefined

export default class Video extends React.Component {
    private video = React.createRef<HTMLVideoElement>();
    private canvas = React.createRef<HTMLCanvasElement>();
    public constraints = {
        Audio: true,
        video: true
    };

    constructor(props: any) {
        super(props);
        // this.streamVideo = this.streamVideo.bind(this);
        // this.playVideo = this.playVideo.bind(this);
        // this.pauseVideo = this.pauseVideo.bind(this);
    }


    streamVideo = () => {
        let dimensions = window.innerWidth;
        let dimensions2 = window.innerHeight;
        this.canvas.current!.width = dimensions;
        this.canvas.current!.height = dimensions2;
        this.canvas.current!.getContext('2d')!.drawImage(this.video.current!, 0, 0, dimensions, dimensions2);
        requestAnimationFrame(this.streamVideo);
    }

    videoGray() {
        let dimensions = window.innerWidth;
        let dimensions2 = window.innerHeight;
        console.log('this is the canvas: ',this.canvas.current);
        this.canvas.current!.width = dimensions;
        this.canvas.current!.height = dimensions2;
        requestAnimationFrame(this.videoGray);
        this.canvas.current!.getContext('2d')!.drawImage(this.video.current!, 0, 0, dimensions, dimensions2);
        let pixelData = this.canvas.current!.getContext('2d')!.getImageData(0, 0, dimensions, dimensions2);
        for (var i = 0; i < pixelData.data.length; i += 4) {
            var r = pixelData.data[i];
            var g = pixelData.data[i + 1];
            var b = pixelData.data[i + 2];
            var averageColour = (r + g + b) / 3;
            pixelData.data[i] = averageColour;
            pixelData.data[i + 1] = averageColour;
            pixelData.data[i + 2] = averageColour;
        }
        this.canvas.current!.getContext('2d')!.putImageData(pixelData, 0, 0);
    }

    playVideo = () => {
        this.video.current!.play();
        // startTimer();
    }

    pauseVideo  = () => {
        this.video.current!.pause();
        // stopTimer();
    }

    componentDidMount() {
        navigator.mediaDevices.getUserMedia(this.constraints)
            .then((stream: MediaStream): void => {
                this.video.current!.srcObject = stream;
                this.streamVideo();
            })
            .catch((err: Object): void => {
                console.log(err)
            })
    }
    

    render() {

        return (
            <section className="videoContainer">
                <video ref={this.video} playsInline autoPlay></video>
                <canvas ref={this.canvas}></canvas>
                <div id="controls">
                    <button data-color="gray" onClick={this.videoGray}>Convert to black and white</button>
                    <button id="play-button" onClick={this.playVideo}>Play</button>
                    <button id="pause-button" onClick={this.pauseVideo}>Pause</button>
                    <button id="color-button" data-invert="normal">Invert Colors</button>
                    <p id="timer">00:00:00</p>
                </div>
            </section>
        )
    }
}



export { Video }

Source: Ask Javascript Questions

LEAVE A COMMENT