Building off of Konva
documentation on how to render a video to the canvas, I would like to play the video by accessing the video reference directly from the Konva.Image
instance. Below is a contrived example to simulate my goal of playing the video dynamically from outside the component. The below does not play the video as expected, even though imageRef.current.image()
returns the video element reference. Any suggestions on how I can access the video reference alternatively?
import React, { useEffect, useContext, useState } from 'react'
import { Image } from "react-konva";
import Konva from 'konva'
export const MainVideo = ({ shape, dispatch }) => {
const imageRef = React.useRef(null);
const video = document.createElement('video');
video.setAttribute('src',shape.url);
useEffect(() => {
if(imageRef) {
imageRef.current.image().play();
const layer = imageRef.current.getLayer();
const anim = new Konva.Animation(() => {
}, layer);
anim.start()
}
}, [imageRef])
return (
<Image
ref={imageRef}
opacity={shape.o}
id={shape.id}
image={video}
x={shape.x}
y={shape.y}
zIndex={0}
height={360}
width={640} />
)
}
You can do this:
const Video = ({ src }) => {
const imageRef = React.useRef(null);
const [size, setSize] = React.useState({ width: 50, height: 50 });
// we need to use "useMemo" here, so we don't create new video elment on any render
const videoElement = React.useMemo(() => {
const element = document.createElement("video");
element.src = src;
return element;
}, [src]);
// when video is loaded, we should read it size
React.useEffect(() => {
const onload = function() {
setSize({
width: videoElement.videoWidth,
height: videoElement.videoHeight
});
};
videoElement.addEventListener("loadedmetadata", onload);
return () => {
videoElement.removeEventListener("loadedmetadata", onload);
};
}, [videoElement]);
// use Konva.Animation to redraw a layer
React.useEffect(() => {
videoElement.play();
const layer = imageRef.current.getLayer();
const anim = new Konva.Animation(() => {}, layer);
anim.start();
return () => anim.stop();
}, [videoElement]);
return (
<Image
ref={imageRef}
image={videoElement}
x={20}
y={20}
stroke="red"
width={size.width}
height={size.height}
draggable
/>
);
};
Demo: https://codesandbox.io/s/react-konva-video-on-canvas-oygvf