Ojay
Ojay

Reputation: 703

I want to draw (using html5 canvas) inside video in react

I have two functionality in my simple React app, a video tag that plays a video source, and a pen tool made with html5 canvas. I want to be able to draw inside my video using that pen tool. I've been Googling around a bit for an answer and haven't found a definite way of doing it.

Take a look at my code

function App(props) {
    const canvasRef = useRef(null);
    const contextRef = useRef(null);
    const [isDrawing, setIsDrawing] = useState(false);

    useEffect(() => {
        const canvas = canvasRef.current;
        canvas.width = window.innerWidth * 2;
        canvas.height = window.innerHeight * 2;
        canvas.style.width = `${window.innerWidth}px`;
        canvas.style.height = `${window.innerHeight}px`;

        const context = canvas.getContext('2d');
        context.scale(2, 2);
        context.lineCap = 'round';
        context.strokeStyle = 'black';
        context.lineWidth = 5;
        contextRef.current = context;
    }, []);

    const startDrawing = ({ nativeEvent }) => {
        const { offsetX, offsetY } = nativeEvent;
        contextRef.current.beginPath();
        contextRef.current.moveTo(offsetX, offsetY);
        setIsDrawing(true);
    };

    const finishDrawing = () => {
        contextRef.current.closePath();
        setIsDrawing(false);
    };

    const draw = ({ nativeEvent }) => {
        if (!isDrawing) {
            return;
        }
        const { offsetX, offsetY } = nativeEvent;
        contextRef.current.lineTo(offsetX, offsetY);
        contextRef.current.stroke();
    };

    // return <canvas onMouseDown={startDrawing} onMouseUp={finishDrawing} onMouseMove={draw} ref={canvasRef} />;
    return (
   <div>
      <canvas onMouseDown={startDrawing} onMouseUp={finishDrawing} onMouseMove={draw} ref={canvasRef} />
        <video id="v" controls loop width="500">
            <source src={video} type="video/mp4" />
        </video>
   </div>
    );
}

Upvotes: 1

Views: 2660

Answers (2)

Austin Peterson
Austin Peterson

Reputation: 123

use position absolute and a container of relative

https://codesandbox.io/s/elated-sun-36eno?file=/src/styles.css

Upvotes: 1

web-sudo
web-sudo

Reputation: 686

It's possible. First of all, you need to apply some styles to the canvas like this : position: absolute;z-index: 999;.

And then you can apply another styles to the video like this : z-index: 11;

If so, the canvas and the video will be overlapped and canvas will be placed on top of the video like this : enter image description here

Here, you would have one problem... for instance, in some cases you might want to control the video. Meaning, you want to pause/play/stop the video whenever. To do this, you also need to put custom pause, play and stop buttons for the video. But those buttons' z-index should be higher than 999 since the canvas's z-index is 999.

Thanks

Upvotes: 1

Related Questions