NoDachi
NoDachi

Reputation: 934

JS - Center Image inside canvas element

I'm scaling the image down so it fits inside the canvas, the thing I am struggling to do is to then center it inside of the canavas element, does anyone know how this could be done please? Any help would be appreciated

https://jsfiddle.net/n7xL5c37/

var canvas = document.getElementById('canvas');
var image = new Image();
    image.src = 'http://placehold.it/300x550';
    image.onload = function () {
        var canvasContext = canvas.getContext('2d');
        var wrh = image.width / image.height;
        var newWidth = canvas.width;
        var newHeight = newWidth / wrh;
        if (newHeight > canvas.height) {
                    newHeight = canvas.height;
            newWidth = newHeight * wrh;
        }

        canvasContext.drawImage(image,0,0, newWidth , newHeight);
      };

Upvotes: 13

Views: 22781

Answers (5)

Shivʌm Singh Ʀathod
Shivʌm Singh Ʀathod

Reputation: 35

Here is an example of javascript photo editor download section code, you can understand with this example, in main.js file

let viewImage = document.querySelector(".view img");

savBtn.addEventListener("click", () => {
    let canvas = document.createElement("canvas");
    let ctx = canvas.getContext("2d");

    canvas.width = viewImage.naturalWidth;
    canvas.height = viewImage.naturalHeight;

    ctx.translate(canvas.width / 2, canvas.height / 2);
    ctx.drawImage(
        viewImage,
        -canvas.width / 2,
        -canvas.height / 2,
        canvas.width,
        canvas.height,
    );

    let link = document.createElement("a");
    link.download = `edited.jpg`;
    link.href = canvas.toDataURL();
    link.click();
})

Upvotes: 0

Alirezaarabi
Alirezaarabi

Reputation: 430

You can get the element like:

var ctx = document.getElementById('digitalrain').getContext('2d');

and set x and y of your image like:

ctx.drawImage(img, width/2-img.width/2, height/2-img.height/2);

Upvotes: -1

Sebastien Lorber
Sebastien Lorber

Reputation: 92112

Solution of Passersby works fine if you want something similar to object-fit: contain

This solution works fine if you want object-fit: cover

const fitImageToCanvas = (image,canvas) => {
  const canvasContext = canvas.getContext("2d");
  const ratio = image.width / image.height;
  let newWidth = canvas.width;
  let newHeight = newWidth / ratio;
  if (newHeight < canvas.height) {
    newHeight = canvas.height;
    newWidth = newHeight * ratio;
  }
  const xOffset = newWidth > canvas.width ? (canvas.width - newWidth) / 2 : 0;
  const yOffset =
    newHeight > canvas.height ? (canvas.height - newHeight) / 2 : 0;
  canvasContext.drawImage(image, xOffset, yOffset, newWidth, newHeight);
};

Upvotes: 5

Blindman67
Blindman67

Reputation: 54026

A solution that will work for both horizontal and vertical.

First find the scale which is the min scale to fit the width or height

var scale = Math.min(canvas.width / img.width, canvas.height / img.height);

Use that scale to get the img width and height

var w = img.width * scale;
var h = img.height * scale;

Then use that scale to calculate the top left as half the dist from the center

var left = canvas.width / 2 - w / 2;
var top = canvas.height / 2 - h / 2;

Upvotes: 7

Passersby
Passersby

Reputation: 1172

    var canvas = document.getElementById('canvas');
    var image = new Image();
    image.src = 'http://placehold.it/300x550';
    image.onload = function () {
        var canvasContext = canvas.getContext('2d');
        var wrh = image.width / image.height;
        var newWidth = canvas.width;
        var newHeight = newWidth / wrh;
        if (newHeight > canvas.height) {
					newHeight = canvas.height;
        	newWidth = newHeight * wrh;
      	}
        var xOffset = newWidth < canvas.width ? ((canvas.width - newWidth) / 2) : 0;
        var yOffset = newHeight < canvas.height ? ((canvas.height - newHeight) / 2) : 0;

      	canvasContext.drawImage(image, xOffset, yOffset, newWidth, newHeight);
      };
<canvas id="canvas" width="500" height="500" style="border: 1px solid black" />

Upvotes: 27

Related Questions