Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show canvas in fullscreen in Fabric.js

I want my canvas-Element to always have the same size - independent of the client's screen-resolution.

If the user zooms with the browser, the canvas-element should always have the same size.

Furthermore, the aspect-ratio should always be the same - I want a coordinate-space of 1920-1080 points. (There can be a border on the side of the canvas-element, if the browser doesn't have the same ratio).

I managed to implement this with html + css:

  • with = 100% of screen
  • max. coordinates are 1920 x 1080

But when I imlemented fabric.js, it changed the size of canvas. And I cant set it back, to have a responsive design.

How can I achive this with fabric.js?

like image 832
maja Avatar asked Jan 12 '23 22:01

maja


1 Answers

After experimenting a bit, I finally found a solution where I only have to modify css-properties.

The answer is very simple, although it's very long.

This is my html-body:

<body onload='init()'>
    <div id="canvasWrapper">
    <canvas id="canvas" width="100px" height="100px"></canvas>
</div>
</body>

And this is my css:

*{
    padding: 0;
    margin: 0;
    border: 0;
}

body{
    overflow: hidden;
}

#canvasWrapper {
    background-color: red;
    display: inline-block;
}

The important parts are the "inline-block" of my canvas-wrapper, and the "overflow: hidden" of the body-element. It seems that there are some pixels below the canvas, which would make both scrollbars appear.

After some experimenting, I got the following js-code:

function init(){    
    resizeCanvas();         //resize the canvas-Element
    window.onresize = function()  { resizeCanvas(); }
}

Whenever the screen-size changes, my "resize"-Function will be called.

The whole trick is done in this resize-Function:

function resizeCanvas() {
    var w = window,
        d = document,
        e = d.documentElement,
        g = d.getElementsByTagName('body')[0],
        x = w.innerWidth || e.clientWidth || g.clientWidth,
        y = w.innerHeight|| e.clientHeight|| g.clientHeight;

    var cv = document.getElementsByTagName("canvas")[0];
    //var cc = document.getElementsByClassName("canvas-container")[0];      //In case of non-Static Canvas will be used
    var cc = document.getElementById("canvasWrapper");

    var cx,cy;                  //The size of the canvas-Element
    var cleft=0;                //Offset to the left border (to center the canvas-element, if there are borders on the left&right)
    if(x/y > sizeX/sizeY){      //x-diff > y-diff   ==> black borders left&right
        cx = (y*sizeX/sizeY);
        cy = y;
        cleft = (x-cx)/2;
    }else{                      //y-diff > x-diff   ==> black borders top&bottom
        cx = x;
        cy = (x*sizeY/sizeX);
    }
    cc.setAttribute("style", "width:"+x+"px;height:"+y+"px;");                                          //canvas-content = fullscreen
    cv.setAttribute("style", "width:"+cx+"px;height:"+cy+"px;position: relative; left:"+cleft+"px");    //canvas: 16:9, as big as possible, horizintally centered
}

This function calculates the window-width, and the biggest canvas-size that is possible without changing the ratio.

After that, I set the wrapper-div to fullscreen-size, and the size of the canvas-Element to the previously calculated size.

Everything works without the need of changing the content of the canvas element and without redrawing anything.

It's cross-browser compatible (tested on Firefox 25, Chrome 31 and Internet Explorer 11)

like image 196
maja Avatar answered Jan 14 '23 12:01

maja