Cropping images using Canvas
overview
In web development, we often need to crop pictures to meet different size requirements or realize partial display of pictures. This blog will give you an in-depth understanding of how to use Canvas technology to realize image cropping. We will use an example to demonstrate how to use Canvas to draw pictures, and perform cropping operations through mask layer and mouse interaction. Let's start this Canvas journey!
project structure
First, let's look at the structure of the project. We will use HTML, CSS and JavaScript to realize the Canvas crop image function, the code is as follows:
<!DOCTYPE html> <html lang="en"> <head> <!-- 省略部分代码 --> </head> <body> <!-- 省略部分代码 --> <div> <input type="file" id="imageFile" accept="image/*" /> </div> <div class="canvas-container"> <canvas id="can"></canvas> </div> <div class="canvas2-container"> <canvas id="can2"></canvas> </div> <script> // JavaScript代码 </script> </body> </html>
We will use three
div
containers, which are used to display the original image, the cropped image, and the cropped area. Among them,<input type="file" id="imageFile" accept="image/*" />
it is used to upload pictures.
Initialize Canvas
In the JavaScript part, we first get the Canvas element and its context, as follows:
const oContainer = document.querySelector('.canvas-container'); const oContainer2 = document.querySelector('.canvas2-container'); const oImageFile = document.querySelector('#imageFile'); const oCan = document.getElementById('can'); const oCan2 = document.getElementById('can2'); const ctx = oCan.getContext('2d'); const ctx2 = oCan2.getContext('2d');
We use
querySelector
the method to get the.canvas-container
and.canvas2-container
element as the image container,#imageFile
and the image upload button. Next, we get the two Canvas elements and their context.
Image loading and drawing
Next, we need to listen to the event of the image upload button and draw it on the Canvas after selecting the image:
const init = () => { bindEvent(); } function bindEvent () { oImageFile.addEventListener('change', handleFileChange, false); // ... 其他事件监听 ... } function handleFileChange (e) { const file = e.target.files[0]; const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function (e) { const data = e.target.result; oImage.src = data; oImage.onload = function () { const { width, height } = this; generateCanvas(oContainer, oCan, width, height); ctx.drawImage(oImage, 0, 0, width, height); drawImageMask(0, 0, width, height, MASK_OPACITY); } } } function generateCanvas (container, canvas, width, height) { container.style.width = width + 'px'; container.style.height = height + 'px'; canvas.width = width; canvas.height = height; container.style.display = 'block'; }
In
bindEvent
the function, we addchange
an event listener to the image upload button, and after selecting the image,FileReader
read the image file and draw it on the Canvas. We usedrawImage
the method to draw the picture on the Canvas, and callgenerateCanvas
the function to make the size of the Canvas consistent with the picture. At the same time, we calldrawImageMask
the function to draw the mask for display when cropping.
cropping operation
Next, we need to implement the clipping operation. When the user mouse clicks and drags, we can get the mouse position and then draw the clipping rectangle:
function handleCanvasMouseDown (e) { initPos = [ e.offsetX, e.offsetY ]; oCan.addEventListener('mousemove', handleCanvasMouseMove, false); oCan.addEventListener('mouseup', handleCanvasMouseUp, false); } function handleCanvasMouseMove (e) { const endX = e.offsetX; const endY = e.offsetY; const [ startX, startY ] = initPos; const rectWidth = endX - startX; const rectHeight = endY - startY; const { width, height } = oCan; screenShotData = [ startX, startY, rectWidth, rectHeight ]; ctx.clearRect(0, 0, width, height); drawImageMask(0, 0, width, height, MASK_OPACITY); drawScreenShot(width, height, rectWidth, rectHeight); } function handleCanvasMouseUp () { oCan.removeEventListener('mousemove', handleCanvasMouseMove, false); oCan.removeEventListener('mouseup', handleCanvasMouseUp, false); drawScreenShotImage(screenShotData); }
In
handleCanvasMouseDown
the function, we record the position of the mouse click. InhandleCanvasMouseMove
the function, draw the rectangle of the clipping area according to the position of the mouse movement, and draw a black translucent mask on top of the mask. InhandleCanvasMouseUp
the function, when the mouse is released, we draw the cropped image.
image cropping
Finally, we need to implement the cropping function of the image. Get the data of the clipping area through
ctx.getImageData
the method and draw it on another Canvas:function drawScreenShot (canWidth, canHeight, rectWidth, rectHeight) { ctx.globalCompositeOperation = 'destination-out'; ctx.fillStyle = '#000'; ctx.fillRect(...initPos, rectWidth, rectHeight); ctx.globalCompositeOperation = 'destination-over'; ctx.drawImage(oImage, 0, 0, canWidth, canHeight, 0, 0, canWidth, canHeight); } function drawScreenShotImage (screenShotData) { const data = ctx.getImageData(...screenShotData); generateCanvas(oContainer2, oCan2, screenShotData[2], screenShotData[3]); ctx2.clearRect(...screenShotData); ctx2.putImageData(data, 0, 0); } init();
In
drawScreenShot
the function, we useglobalCompositeOperation
attributes to control the way of drawing, first draw the clipping area and clear it on the mask, and then draw the original image. IndrawScreenShotImage
the function, we usectx.getImageData
the method to get the data of the clipping area, and then draw it on the second Canvas.
Summarize
Through the above steps, we have successfully implemented the function of using Canvas to crop images. By listening to the mouse event, we can draw the cropping area on the picture, and finally realize the cropping effect of the picture. Canvas technology is an indispensable part of Web front-end development. I hope this blog can help you better understand the application scenarios and practical skills of Canvas. Thanks for reading!
Learning from station B up - front-end Ono Sensen