fabricjs/fabricjs.com

Setting Video as Background, Width and Height Not Scaling Properly

ITOUTLAW opened this issue · 1 comments

Adding a video element as the background image, the width and height are represented properly in the JSON but it is not scaling properly in the browser window.

I have tried using the scaleToHeight and scaleToWidth methods as well.

    function addVideoBackground(el, url){
        console.log(el);
        let bgv = new fabric.Image(el, {
            objectCaching: false,
            selectable: false,
        });
        canvas.setBackgroundImage(bgv, canvas.renderAll.bind(canvas), {
            crossOrigin: 'anonymous',
            originX: 'left',
            originY: 'top',
            src: url,
            height: canvas.getHeight(),
            width: canvas.getWidth(),
        });
        canvas.video = true;
        canvas.videoUrl = url;
        bgv.getElement().play();
        fabric.util.requestAnimFrame(function render() {
            canvas.renderAll();
            fabric.util.requestAnimFrame(render);
        });
    }

I was able to resolve the issue.
I created a function to wait for the video to load into the DOM, then grab the original dimensions of the video. I pass those into the addVideoBackground function, then determine the x and y scaling factor based on the current canvas size. I set the video background size to be the original size of the video, and pass the x y scaling factor in as the scaleX and scaleY properties respectively. Here is the code for anyone who needs help with it.

First I create a <video> tag with the correct src, loop, and some other data with display: none;. Wait for the metadata to load and grab the width and height.
Pass that element to the below function.
The canvas.video = true; and canvas.videoUrl are properties that I use for processing on the backend when saving the canvas.

function addVideoBackground(el, url, width, height){
        let cW = canvas.getWidth();
        let cH = canvas.getHeight();
        let xsf = cW / width;
        let ysf = cH / height;
        let bgv = new fabric.Image(el, {
            objectCaching: false,
            selectable: false,
        });
        canvas.setBackgroundImage(bgv, canvas.renderAll.bind(canvas), {
            crossOrigin: 'anonymous',
            originX: 'left',
            originY: 'top',
            scaleX: xsf,
            scaleY: ysf,
            width: width,
            height: height,
        });
        canvas.video = true;
        canvas.videoUrl = url;
        bgv.getElement().play();
        fabric.util.requestAnimFrame(function render() {
            canvas.renderAll();
            fabric.util.requestAnimFrame(render);
        });
    }