Search code examples
javascriptjquerycanvaspnghtml2canvas

How to rotate .png rendered from div with canvas 90° ccw?


Let me start off by saying that I'm new to working with the Canvas element. I've managed to get a div to render as a png with jQuery and html2canvas.js, but I'd like to rotate the png 90 degrees counter-clockwise.

I assume I need to do this in the canvas stage, before the outputting it as a png for it to be persistent even when the image is downloaded – how would I go about and accomplish that?

This is what I've got at the moment, which is working (minus the rotation)

html2canvas($("#portrait_back_div"), {
    onrendered: function (canvas) {
        //document.getElementById('canvas').appendChild(canvas);
        var data = canvas.toDataURL('image/png');

        var image = new Image();
        image.src = data;
        document.getElementById('portrait_back_png').appendChild(image);
        //$( "#portrait_back_div" ).hide();
    }
});

I appreciate any help I can get, even though this might seem like a basic question. This fiddle basically works on the same principles as my project it you want to take a look.


Solution

  • You would have to create a new canvas, then translate to center to move origin to center (here functions as pivot for rotation), rotate then draw image.

    Finally extract image from the rotated canvas.

    Example

    html2canvas($("#portrait_back_div"), {
      onrendered: function (canvas) {
    
        // create intermediate canvas
        var rotCanvas = document.createElement("canvas");
    
        // swap width and height
        rotCanvas.width = canvas.height;
        rotCanvas.height = canvas.width;
    
        // get context
        var rctx = rotCanvas.getContext("2d");
    
        // translate to center (rotation pivot)
        rctx.translate(rotCanvas.width * 0.5, rotCanvas.height * 0.5);
    
        // rotate -90° (CCW)
        rctx.rotate(-Math.PI * 0.5);
    
        // draw image offset so center of image is on top of pivot
        rctx.drawImage(canvas, -canvas.width * 0.5, -canvas.height * 0.5);
    
        // extract image from rotate canvas
        var data = rotCanvas.toDataURL('image/png');
    
        var image = new Image();
        image.src = data;
        document.getElementById('portrait_back_png').appendChild(image);
        //$( "#portrait_back_div" ).hide();
      }
    });
    

    // proof-of-concept example
    var img = new Image;
    img.onload = function() {
      var rotCanvas = document.createElement("canvas");
      var rctx = rotCanvas.getContext("2d");
      rotCanvas.width = this.height;
      rotCanvas.height = this.width;
      rctx.translate(rotCanvas.width * 0.5, rotCanvas.height * 0.5);
      rctx.rotate(-Math.PI * 0.5);
      rctx.drawImage(this, -this.width * 0.5, -this.height * 0.5);
      document.body.appendChild(this);
      document.body.appendChild(rotCanvas)
    };
    img.src = "//i.imgur.com/YqeJUhl.jpg?1";
    <h4>Original on top, rotated canvas at bottom</h4>