1. Use css to set your right resolution for canvas:
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
canvas.width = 800;
canvas.height = 600;
css:
/* media query 1 */
#canvas{
width: 400px;
height: 250px;
}
/* media query 2 */
#canvas{
width: 200px;
height: 120px;
}
pros:
All the resolution is given by canvas width and height (800/600)
cons:
Fit well for square canvases aspect ration (1:1), problems with output
for weird aspect ratios where you need to compute your css height
based,
original height / original width * new width = new height;
this is out of my league in css...
Read some time ago on fabric.js git issues section where, technique
(css resize) isn't recommended due to slowness and incorrect objects
transactions, this may be changed I know I tested and objects were
incorrect re-sized (random colored pixels, transactions shadows remain
in canvas , in other words a mess)
2. Re-size your canvas to exact dimension (resolution) when you need to submit, and then get the image generated
Just re-size your canvas at window re-size (responsive canvas) and when you need to export to exact dimension you need to re size your canvas to exact pixel resolution, or create another canvas hidden.
this example is for 1:1 ration canvas (you need to apply aspect ratio to canvas and objects inside):
$(window).resize(function (){
if (canvas.width != $(".container").width()) {
var scaleMultiplier = $(".container").width() / canvas.width;
var objects = canvas.getObjects();
for (var i in objects) {
objects[i].scaleX = objects[i].scaleX * scaleMultiplier;
objects[i].scaleY = objects[i].scaleY * scaleMultiplier;
objects[i].left = objects[i].left * scaleMultiplier;
objects[i].top = objects[i].top * scaleMultiplier;
objects[i].setCoords();
}
canvas.setWidth(canvas.getWidth() * scaleMultiplier);
canvas.setHeight(canvas.getHeight() * scaleMultiplier);
canvas.renderAll();
canvas.calcOffset();
}
});
At submit export canvas data re-size canvas to desired resolution, voila:
function GetCanvasAtResoution(newWidth)
{
if (canvas.width != newWidth) {
var scaleMultiplier = newWidth / canvas.width;
var objects = canvas.getObjects();
for (var i in objects) {
objects[i].scaleX = objects[i].scaleX * scaleMultiplier;
objects[i].scaleY = objects[i].scaleY * scaleMultiplier;
objects[i].left = objects[i].left * scaleMultiplier;
objects[i].top = objects[i].top * scaleMultiplier;
objects[i].setCoords();
}
canvas.setWidth(canvas.getWidth() * scaleMultiplier);
canvas.setHeight(canvas.getHeight() * scaleMultiplier);
canvas.renderAll();
canvas.calcOffset();
}
return canvas.toDataURL();
}
);
It's not a big deal with the rations different then 1:1 you need to compute scale multiplayer for height as well, easy to understand ratio: http://andrew.hedges.name/experiments/aspect_ratio/
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…