使用Canvas裁剪图片
概述
在Web开发中,我们经常需要对图片进行裁剪,以满足不同尺寸需求或者实现图片的局部展示。本篇博客将带您深入了解如何使用Canvas技术来实现图片的裁剪功能。我们将通过一个实例来演示如何利用Canvas绘制图片,并通过蒙层和鼠标交互来进行裁剪操作。让我们开始这个Canvas之旅吧!
项目结构
首先,让我们来看一下项目的结构。我们将使用HTML、CSS和JavaScript来实现Canvas裁剪图片功能,代码如下所示:
<!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>
我们将使用三个
div
容器,分别用于显示原图、裁剪后的图和裁剪区域。其中,<input type="file" id="imageFile" accept="image/*" />
用于上传图片。
初始化Canvas
在JavaScript部分,我们先获取Canvas元素和其上下文,如下所示:
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');
我们使用
querySelector
方法获取了.canvas-container
和.canvas2-container
元素作为图片容器,#imageFile
为图片上传按钮。接着,我们获取了两个Canvas元素及其上下文。
图片加载与绘制
接下来,我们需要监听图片上传按钮的事件,并在选择图片后将其绘制在Canvas上:
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'; }
在
bindEvent
函数中,我们为图片上传按钮添加了change
事件监听,并在选择图片后,通过FileReader
读取图片文件,并将其绘制在Canvas上。我们使用drawImage
方法将图片绘制在Canvas上,并调用generateCanvas
函数,使Canvas的大小与图片保持一致。同时,我们调用drawImageMask
函数绘制蒙层,用于裁剪时的显示。
裁剪操作
接下来,我们需要实现裁剪操作。当用户鼠标点击并拖动时,我们可以获取鼠标位置,然后绘制裁剪区域的矩形:
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); }
在
handleCanvasMouseDown
函数中,我们记录鼠标点击时的位置。在handleCanvasMouseMove
函数中,根据鼠标移动的位置绘制裁剪区域的矩形,并在蒙层上绘制黑色的半透明蒙层。在handleCanvasMouseUp
函数中,当鼠标松开后,我们绘制裁剪后的图片。
图片裁剪
最后,我们需要实现图片的裁剪功能。通过
ctx.getImageData
方法获取裁剪区域的数据,并绘制在另一个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();
在
drawScreenShot
函数中,我们使用globalCompositeOperation
属性来控制绘制的方式,先绘制裁剪区域并在蒙层上清除,然后再绘制原图。在drawScreenShotImage
函数中,我们使用ctx.getImageData
方法获取裁剪区域的数据,然后绘制在第二个Canvas上。
总结
通过以上步骤,我们已经成功实现了使用Canvas来裁剪图片的功能。通过监听鼠标事件,我们可以在图片上绘制裁剪区域,并最终实现图片的裁剪效果。Canvas技术是Web前端开发中不可或缺的一部分,希望本篇博客能够帮助您更好地了解Canvas的应用场景和实践技巧。感谢您的阅读!
学习自B站up——前端小野森森