fabric.js resize canvas to fit screen

前端 未结 2 2011
谎友^
谎友^ 2020-12-13 16:33

I\'m currently developping an application on mobile device (android and iPhone) with ionic and cordova. I would like to edit a picture. I use fabric.js library to do that. F

相关标签:
2条回答
  • 2020-12-13 17:02

    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/

    0 讨论(0)
  • 2020-12-13 17:08

    I have found a trick to do that without having to copy the canvas. This solution is really close to css zoom property but events are handle correctly.

    This is an example to display the canvas half its size:

    -webkit-transform : scale(0.5);
    -webkit-transform-origin : 0 0;
    
    0 讨论(0)
提交回复
热议问题