Search code examples
javascripthtmlhtml5-canvas

HTML 5 - how to zoom canvas background image


I am a beginner in HTML 5,

I have written a code for canvas zoom but I dont want to zoom actual canvas but the background image of canvas like in the http://www.customink.com/lab

following is the code which I have written :

var canvas = new fabric.Canvas('canvas');

canvas.setBackgroundImage('images/1front.png', function() {

    canvas.backgroundImageStretch = true;
    canvas.renderAll();
});

var canvasScale = 1;
var SCALE_FACTOR = 1.2;
function zoomIn() {
    // TODO limit the max canvas zoom in

    canvasScale = canvasScale * SCALE_FACTOR;

    canvas.setHeight(canvas.getHeight() * SCALE_FACTOR);
    canvas.setWidth(canvas.getWidth() * SCALE_FACTOR);

    var objects = canvas.getObjects();
    for (var i in objects) {
        var scaleX = objects[i].scaleX;
        var scaleY = objects[i].scaleY;
        var left = objects[i].left;
        var top = objects[i].top;

        var tempScaleX = scaleX * SCALE_FACTOR;
        var tempScaleY = scaleY * SCALE_FACTOR;
        var tempLeft = left * SCALE_FACTOR;
        var tempTop = top * SCALE_FACTOR;

        objects[i].scaleX = tempScaleX;
        objects[i].scaleY = tempScaleY;
        objects[i].left = tempLeft;
        objects[i].top = tempTop;

        objects[i].setCoords();
    }

    canvas.renderAll();
}

// Zoom Out
function zoomOut() {
    // TODO limit max cavas zoom out

    canvasScale = canvasScale / SCALE_FACTOR;

    canvas.setHeight(canvas.getHeight() * (1 / SCALE_FACTOR));
    canvas.setWidth(canvas.getWidth() * (1 / SCALE_FACTOR));

    var objects = canvas.getObjects();
    for (var i in objects) {
        var scaleX = objects[i].scaleX;
        var scaleY = objects[i].scaleY;
        var left = objects[i].left;
        var top = objects[i].top;

        var tempScaleX = scaleX * (1 / SCALE_FACTOR);
        var tempScaleY = scaleY * (1 / SCALE_FACTOR);
        var tempLeft = left * (1 / SCALE_FACTOR);
        var tempTop = top * (1 / SCALE_FACTOR);

        objects[i].scaleX = tempScaleX;
        objects[i].scaleY = tempScaleY;
        objects[i].left = tempLeft;
        objects[i].top = tempTop;

        objects[i].setCoords();
    }

    canvas.renderAll();        
}

Solution

  • You can use drawImage as user2422324 suggests, but you must use additional arguments to scale the image while drawing it.

    In addition, you must scale the background image to a temporary canvas because fabricjs expects an imageURL when setting it's background

    Here's how the scaling works:

    First, create a temporary canvas and set it's size to the zoom size you desire. For example to scale the background image to 200% you would do this:

    tempCanvas.width=myBackgroundImage.width*2.0;
    tempCanvas.height=myBackgroundImage.height*2.0;
    

    Now use drawImage to both draw the background image to the tempCanvas. By supplying the last 4 arguments, the image will be scaled to the desired zoom (which is the current tempCanvas size).

    tempContext.drawImage(myBackgroundImage,
    
        // the source of the draw will be the full background image
        0,0, myBackgroundImage.width, myBackgroundImage.height,
    
        // and this causes the full image to be scaled to fit the resized tempCanvas
        0,0, tempCanvas.width, tempCanvas.height
    );
    

    Then use fabricJS's setBackgroundImage to apply the scaled background. We can create the imageURL that fabric expects by using tempCanvas.toDataURL():

    canvas.setBackgroundImage( tempCanvas.toDataURL(), function(){
        canvas.backgroundImageStretch=true;
        canvas.renderAll();
    });
    

    Note that backgroundImageStretch=true may cause the image to proportionally distort. Instead, you might want to set backgroundImageStretch=false and set backgroundImageLeft/backgroundImageTop to offset the background image.

    Here is a fairly complete, but totally untested starting code:

    // this is the current scaling factor of the background image
    // hint: originally set it at less than full size
    //       so it doesn't pixelate when scaled up.
    var scaleFactor=.50;
    
    // create a background image object we can later scale
    var fullBk=document.createElement("img");
    fullBk.onload=function(){
        setBkZoom(scaleFactor);
    }
    fullBk.src="images/1front.png";
    
    // create a temp canvas used to scale the bk image
    var zoomCanvas=document.createElement("canvas");
    var zoomCtx=zoomCanvas.getContext("2d");
    
    // scale the bk image and set it as the fabric background
    function setBkZoom(scaleFactor){
        // scale the temp zoomCanvas to desired bk size
        // note: changing canvas width automatically clears it
        zoomCanvas.width=fullBk.width*scaleFactor;
        zoomCanvas.height=fullBk.height*scaleFactor;
        // draw a scaled version of fullBk to zoomCanvas
        zoomCtx.drawImage(fullBk,
            0,0,fullBk.width,fullBk.height,
            0,0,zoomCanvas.width,zoomCanvas.height);
        // now use the scaled zoomCanvas to set the fabric background
        canvas.setBackgroundImage(zoomCanvas.toDataURL(),function(){
            // stretch=true may cause your image to distort proportions
            // instead you might want to set backgroundImageLeft/backgroundImageTop 
            // to offset the scaled image
            canvas.backgroundImageStretch=true;
            canvas.renderAll();
        }
    }