Fabric.js changes my canvas size to 300x150 after initialization
JavascriptCanvasFabricjsJavascript Problem Overview
HTML:
<div class="canvas-wrapper">
<canvas id="myCanvas"></canvas>
</div>
CSS
.canvas-wrapper {
width: 900px;
min-height: 600px;
}
#myCanvas{
border:1px solid red;
position: absolute;
top:22px;
left:0px;
height: 100%;
width: 99%;
}
JS
var myCanvas = new fabric.Canvas('myCanvas');
My canvas get resized to 300x150 after it's been initialized, why?
Javascript Solutions
Solution 1 - Javascript
in the latest version, you will have to do something like:
var canvas = new fabric.Canvas('myCanvas');
canvas.setHeight(500);
canvas.setWidth(800);
.... Your code ....
canvas.renderAll();
Works fine for me..
For dynamically changing size, this works too
Solution 2 - Javascript
When initializing canvas, Fabric reads width/height attributes on canvas element or takes width/height passed in options.
var myCanvas = new fabric.Canvas('myCanvas', { width: 900, height: 600 });
or:
<canvas width="900" height="600"></canvas>
...
var myCanvas = new fabric.Canvas('myCanvas');
Solution 3 - Javascript
A real answer to this question—not involving a new static size but actually permitting CSS to be effective—is one of the following options:
- In CSS, you can override individual properties and following them with !important; the downside to this is that any further definitions must also use !important or they will be ignored:
[width], [height], [style]
{
width: 100vw!important;
min-height: 100vh!important;
}
2. Using JQuery you can set the inline property values to an empty string. You can presumably achieve this without JQuery, but I will leave that as an exercise to you.
Javascript (JQuery):
$('[style]').attr( 'style', function(index, style){ return ''; });
$('[height]').attr( 'height', function(index, height){ return ''; });
$('[width]').attr( 'width', function(index, height){ return ''; });
CSS:
*, *:before, *:after
{
box-sizing: border-box;
}
body
{
width: 100vw;
min-height: 100vh;
padding: 0;
margin: 0;
}
.canvas-container,
canvas
{
width: inherit;
min-height: inherit;
}
canvas.lower-canvas
{
position: absolute;
top: 0;
}
After that, CSS will be applied as expected.
It is apparently also necessary to tell Fabric about the change:
function sizeCanvas()
{
var width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
canvas.setHeight( height )
canvas.setWidth( width )
}
window.addEventListener('resize', draw, false);
function initDraw()
{
// setup
}
function draw()
{
canvas.renderAll();
}
sizeCanvas();
initDraw();
This will configure Fabric to the viewport size and keep it sized accordingly if it resizes.
It's worth noting that this problem arises for two reasons:
-
Someone thought it was a good idea to use inline styles and should be severely castigated, as there is no situation where this is ever an appropriate practice.
-
Fabric changes the DOM arrangement and nests the original canvas in a new div with a second nested canvas, which may result in surprises.