Crop Image in Canvas Using JavaScript

Crop Image in Canvas Using JavaScript
Code Snippet:Crop image
Author: Gabi
Published: January 18, 2024
Last Updated: January 22, 2024
Downloads: 335
License: MIT
Edit Code online: View on CodePen
Read More

This JavaScript code helps crop images within a canvas. It allows defining and positioning cropped areas, enabling image selection. The main method, “drawImage,” facilitates displaying specific image portions, useful for customized image previews or selections.

You can use this code on websites to let users crop images interactively. It’s handy for profile picture uploads, enabling users to select and preview the desired image section before finalizing their choice. This feature can enhance user experience by providing customization options while ensuring the selected image fits perfectly.

How to Create Crop Image In Canvas Using Javascript

1. Begin by structuring the HTML file. Create a canvas for displaying the original image and another canvas for the cropped image. Include a container for these elements and a placeholder for instructions or descriptions.

<h1>Cropping an image using HTML5 Canvas</h1>
<div class="wrapper">
  
  <canvas id='c1'></canvas><!--
--><canvas id='c2'></canvas>
  <p id="output"></p>
  <p>Move the cropping bars to enclose the desired area of interest (left canvas).<br>Then you may drag to reposition the cropped image (right canvas).</p>
</div>

2. Style your elements using CSS to define the layout, canvas dimensions, and appearance of the cropping bars.

body {
  margin: 0;
  padding: 0;
  background: #eee;
  font-family: Courier, monospace;
  font-size: 16px;
  text-align: center;
  -webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

.wrapper {
  display: block;
  margin: 0 auto;
  padding: 0;
  width: 844px;
}

canvas {
  margin: 10px;
  padding: 0;
  border: 1px solid #333;
  display: inline-block;
}

p {
  text-align: left;
  margin-left: 10px;
}

h1 {
  font-size: 1.5em;
  font-family: Arial, Helvetica, sans-serif;
  padding: 1em 0 0;
}


/*#c1 {
  background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/beagle400.jpg)
}*/

3. Finally, add the following JavaScript function into your project. It handles the cropping functionality and user interactions. Replace the theImage variable in the JavaScript code with the URL of the image you want to use. Modify the variables (sx, sy, sw, sh) to specify the desired cropped area.

var proportion = .8; // you may change the proportion for the cropped image.
var theImage = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/beagle400.jpg";
/*
original image:
----------------------------
|     |                    |
|     |sy                  |
|_____|____________        |
| sx  |           |        |
|     |           |        |
|     |           | sh     |
|     |           |        |
|     |___________|        |
|          sw              |
|                          |
|                          |
|__________________________|

cropped image:
----------------------------
|     |                    |
|     |y                   |
|_____|_________           |
|  x  |        |           |
|     |        | h         |
|     |________|           |
|          w               |
|                          |
|                          |
|__________________________|

ctx.drawImage(img,sx,sy,sw,sh,x,y,w,h)

*/


var output = document.getElementById("output");
var c1 = document.getElementById("c1");
var ctx1 = c1.getContext("2d");
var c2 = document.getElementById("c2");
var ctx2 = c2.getContext("2d");

var cw = c1.width = c2.width = 400,
  cx = cw / 2;
var ch = c1.height = c2.height = 400,
  cy = ch / 2;

var isDragging1 = false;
var isDragging2 = false;

var sy = 20;
var sx = 130;
var sw = 200;
var sh = 200;

var r = 4;

var mousePos1 = {
  x: 0,
  y: 0
};
var mousePos2 = {
  x: 0,
  y: 0
};

var o = { // cropping bars
  "sx": {
    color: "white",
    x: 0,
    y: sy,
    w: cw,
    h: r,
    bool: false,
  },
  "sy": {
    color: "yellow",
    x: sx,
    y: 0,
    w: r,
    h: ch,
    bool: false,
  },
  "sw": {
    color: "orange",
    x: 0,
    y: sy + sh,
    w: cw,
    h: r,
    bool: false,
  },
  "sh": {
    color: "red",
    x: sx + sw,
    y: 0,
    w: r,
    h: ch,
    bool: false,
  }
}

function drawGuides(o) {
  for (k in o) {
    ctx1.fillStyle = o[k].color;
    ctx1.beginPath();
    ctx1.fillRect(o[k].x, o[k].y, o[k].w, o[k].h);
  }
}

function Imgo(o, d) { // an object defining the cropped image
  var imgo = {
    sx: o.sy.x,
    sy: o.sx.y,
    sw: o.sh.x - o.sy.x,
    sh: o.sw.y - o.sx.y,
    w: ~~((o.sh.x - o.sy.x) * proportion),
    h: ~~((o.sw.y - o.sx.y) * proportion),
    x: d.x,
    y: d.y
  }
  return imgo;
}

var d = {
  x: ~~(cx - sw * proportion / 2),
  y: ~~(cy - sh * proportion / 2)
}

function Output(Imgo, output) {
  output.innerHTML = "ctx.drawImage(img," + imgo.sx + "," + imgo.sy + "," + imgo.sw + "," + imgo.sh + "," + imgo.x + "," + imgo.y + "," + imgo.w + "," + imgo.h + ")";
}

function drawCroppedImage(imgo) {
  ctx2.drawImage(img, imgo.sx, imgo.sy, imgo.sw, imgo.sh, imgo.x, imgo.y, imgo.w, imgo.h);
}

function outlineImage(imgo) {
  ctx2.beginPath();
  ctx2.rect(imgo.x, imgo.y, imgo.w, imgo.h);
}

function cursorStyleC1() {
  c1.style.cursor = "default";
  for (k in o) { //o[k].bool = false;
    ctx1.beginPath();
    ctx1.rect(o[k].x - 10, o[k].y - 10, o[k].w + 20, o[k].h + 20);
    if (ctx1.isPointInPath(mousePos1.x, mousePos1.y)) {
      if (k == "sx" || k == "sw") {
        c1.style.cursor = "row-resize";
      } else {
        c1.style.cursor = "col-resize";
      }
      break;
    } else {
      c1.style.cursor = "default";
    }
  }
}

function cursorStyleC2() {
  c2.style.cursor = "default";
  outlineImage(imgo);
  if (ctx2.isPointInPath(mousePos2.x, mousePos2.y)) {
    c2.style.cursor = "move";
  } else {
    c2.style.cursor = "default";
  }
}

drawGuides(o);
var imgo = Imgo(o, d); // an object defining the cropped image
Output(Imgo, output); // text: "drawImage(img,130,10,200,220,150,145,100,110)";

var img = new Image();
img.src = theImage;
img.onload = function() {
  c1.style.backgroundImage = "url("+theImage+")";
  drawCroppedImage(imgo);
}

// mousedown ***************************

c1.addEventListener('mousedown', function(evt) {
  isDragging1 = true;

  mousePos1 = oMousePos(c1, evt);
  for (k in o) {
    ctx1.beginPath();
    ctx1.rect(o[k].x - 10, o[k].y - 10, o[k].w + 20, o[k].h + 20);
    if (ctx1.isPointInPath(mousePos1.x, mousePos1.y)) {
      o[k].bool = true;
      if (k == "sx" || k == "sw") {
        o[k].y = mousePos1.y;
      } else {
        o[k].x = mousePos1.x;
      }
      break;
    } else {
      o[k].bool = false;
    }
  }

  Output(Imgo, output);

}, false);

c2.addEventListener('mousedown', function(evt) {
  mousePos2 = oMousePos(c2, evt);
  outlineImage(imgo)
  if (ctx2.isPointInPath(mousePos2.x, mousePos2.y)) {
    isDragging2 = true;

    deltaX = mousePos2.x - imgo.x;
    deltaY = mousePos2.y - imgo.y;

    Output(Imgo, output);
  }
}, false);

// mousemove ***************************
c1.addEventListener('mousemove', function(evt) {
  mousePos1 = oMousePos(c1, evt); //console.log(mousePos)	
  cursorStyleC1();

  if (isDragging1 == true) {
    ctx1.clearRect(0, 0, cw, ch);

    for (k in o) {
      if (o[k].bool) {
        if (k == "sx" || k == "sw") {
          o[k].y = mousePos1.y;
        } else {
          o[k].x = mousePos1.x;
        }
        break;
      }
    }

    drawGuides(o);
    ctx2.clearRect(0, 0, cw, ch);
    imgo = Imgo(o, d);
    drawCroppedImage(imgo);
    Output(Imgo, output);
  }
}, false);

c2.addEventListener('mousemove', function(evt) {
  mousePos2 = oMousePos(c2, evt);

  if (isDragging2 == true) {
    ctx2.clearRect(0, 0, cw, ch);
    d.x = mousePos2.x - deltaX;
    d.y = mousePos2.y - deltaY;
    imgo = Imgo(o, d);
    drawCroppedImage(imgo);
    Output(Imgo, output);
  }
  cursorStyleC2();
}, false);

// mouseup ***************************
c1.addEventListener('mouseup', function(evt) {
  isDragging1 = false;
  for (k in o) {
    o[k].bool = false;
  }
}, false);

c2.addEventListener('mouseup', function(evt) {
  isDragging2 = false;

}, false);

// mouseout ***************************
c1.addEventListener('mouseout', function(evt) {
  isDragging1 = false;
  for (k in o) {
    o[k].bool = false;
  }
}, false);

c2.addEventListener('mouseout', function(evt) {
  isDragging2 = false;

}, false);

function oMousePos(canvas, evt) {
  var rect = canvas.getBoundingClientRect();
  return {
    x: Math.round(evt.clientX - rect.left),
    y: Math.round(evt.clientY - rect.top)
  }
}

That’s all! hopefully, you have successfully created a functionality to crop image in canvas using JavaScript. If you have any questions or suggestions, feel free to comment below.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About CodeHim

Free Web Design Code & Scripts - CodeHim is one of the BEST developer websites that provide web designers and developers with a simple way to preview and download a variety of free code & scripts. All codes published on CodeHim are open source, distributed under OSD-compliant license which grants all the rights to use, study, change and share the software in modified and unmodified form. Before publishing, we test and review each code snippet to avoid errors, but we cannot warrant the full correctness of all content. All trademarks, trade names, logos, and icons are the property of their respective owners... find out more...

Please Rel0ad/PressF5 this page if you can't click the download/preview link

X