canvas实现剪切蒙层

在某些特殊业务场景下我们需要多图像进行裁剪,或者创建蒙层框选出某个特定的区域,要实现这样的场景其实思路有很多,但是考虑到canvas的性能、实现复杂度的问题来讲,都有各自的不足之处。首先来看如下图需求场景。

 

如果我们要实现这样的一个框选效果,对图形或画面框选出某个特定的区域从而对这个区域做某些特定的业务操作。要实现这样一个框选效果常见的解决方案有4种:

第一种方案:

要实现这样的选框效果,我们可以配合div DOM节点来控制选框,并调整其大小。dom效果与源码实现可参考:html5 canvas 截图demo(带半透明遮罩)_Don't lost way-CSDN博客

实现思路分别有以下三个核心步骤。

第一步:在canvas画布下创建一个div元素,这个div元素就是框选的区域。

第二步:这个选框边上8个点的实现分别在这个选框div中添加8个子元素,通过定位的方式分别对这8个子元素定位到相应的位置。

第三步:通过鼠标移动事件对这个div进行缩放调整宽高大小,并获取选框在窗口上的坐标。

这种方式往往的通过div等节点元素来控制的,对dom操作依赖度很高,实现起来源码量也很大,在我看来不利于我们本节内容寻求最优的解决方案的初衷。

第二种方案: 

第二种解决方案是参考我们公司现有方案,其思路是通过在画布的背景图上创建一个矩形图层,并对此图层进行半透明效果处理,在此半透明图层下再实现框选的矩形,并记录选框矩形的坐标,通过ctx.putImageData()方法来获取到背景图对应的区域并绘制到框选矩形中去即可。实现步骤分为以下4个步骤。

第一步:在背景图上创建半透明的矩形图层,

第二步:在半透明图层下再创建一个框选矩形,并记录此矩形的坐标大小,根据此矩形的坐标计算出8个点的坐标并添加8个点定位在框选矩形的边框上。

第三步:通过鼠标移动事件实时对框选矩形的位置和大小进行调整并更新坐标。

第四步:使用记录下来的框选矩形坐标通过getImageData()方法复制一份背景图对应坐标区域图形并通过putImageData()方法绘制到框选矩形相同的坐标上来即可。

这个方案的可用性会比第一种解决方案要高,但从性能提升角度去考虑 对框选矩形会不断的重复渲染,也会造成不必要的计算开销。显然我们还在寻求探索更优的解决方案。

第三种方案:

第三种方案就是我们可以直接通过canvas提供的原生API ctx.globalCompositeOperation = 'xor'对我们创建的半透明矩形进行裁剪出空白区域,并对此区域的坐标添加边上的8个点。实现思路如下:

第一步:在背景图层上创建一个与画布大小相同的矩形,并设置成半透明状态。

第二步:用过globalCompositeOperation = 'xor'对此半透明图层进行裁剪的属性设置。

第三步:定义框选的矩形并记录其坐标,根据裁剪的坐标计算出8个点的定位位置即可。

此方案可快速解决我们简单的一些业务场景,但它存在一个问题,当我们需要同事生成多个框选矩形的时候,在某些矩形坐标出现重叠的情况下,在重叠产生交集处会出现白色区域,不利于绘制多个框选矩形的业务场景。在单个选框矩形的需求下其性能和可用性很高。

第四种方案:

本方案解决思路为创建两个canvas画布,第一个canvas画布主要用户背景图型的绘制,第二个canvas画布主要用于绘制裁剪蒙层和选框标注等操作,在第二个canvas画布中先绘制一个宽高大小与画布相同的矩形并设置半透明效果,在此基础上通过清除ctx.clearRect()方法按照给定的坐标对半透明蒙层指定区域进行清除,再绘制相同给定坐标的矩形即可,在此基础上添加边框上的8个点。具体步骤如下:

第一步:在第一个canvas中绘制背景图。

第二步:在第二个canvas中绘制相当画布大小的矩形并设置成半透明状态,记录其坐标。

第三步:根据记录的坐标绘制对应的矩形选框,在此基础上添加对应的8个点。 

例如

1. 第一个画布绘制背景图 

let image = new Image();
const canvas = document.getElementById("canvas");
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
const ctx = canvas.getContext("2d");
image.setAttribute("crossOrigin","anonymous");
image.src = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fnimg.ws.126.net%2F%3Furl%3Dhttp%3A%2F%2Fdingyue.ws.126.net%2F2021%2F0128%2F6cd17366j00qnmnle008uc000vk00xcm.jpg%26thumbnail%3D650x2147483647%26quality%3D80%26type%3Djpg&refer=http%3A%2F%2Fnimg.ws.126.net&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1643627661&t=298faa510a1783c1f8413fb8a51e7cf8";
image.onload = (event) => {
   ctx.drawImage(0,0,wdith,height);
};

2. 第二个画布创建蒙层并清除指定区域绘制相遇坐标的矩形框 

ctx.save();
// 在第二个canvas画布中添加半透明蒙层
ctx.fillStyle = "rgba(0,0,0,0.5)";
ctx.fillRect(0,0,canvas.width,canvas.height);

// 清空半透明蒙层给定区域
ctx.clearRect(50,50,100,100);
 
// 绘制给定坐标的矩形框
ctx.strokeStyle = "red";
ctx.strokeRect(80,80,100,100);
/****添加对应边框上的8个点*****/
ctx.restore()

       此方案可很好解决我们的业务需求,并可以同事绘制多个矩形选框,不会存在过大的计算量,实现复杂度极其简化。目前视为最优解决方案。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Canvas是HTML5中新增的元素,它可以用来在网页上绘制图形,制作动画等。通过JavaScript脚本,我们可以在Canvas上绘制各种图形,如线条、矩形、圆形、文字等。CanvasCanvas是HTML5中新增的元素,它可以用来在网页上绘制图形,制作动画等。通过JavaScript脚本,我们可以在Canvas上绘制各种图形,如线条、矩形、圆形、文字等。Canvas的绘图原理是在网页上创建一个画布,然后通过JavaScript脚本来控制画布上的像素,从而实现各种绘图效果。Canvas的使用非常灵活,可以通过CSS样式来设置画布的大小和位置,也可以通过JavaScript脚本来动态地改变画布的属性和内容。 下面是一个简单的Canvas绘图示例: 引用: <canvas id="tutorial" width="300" height="300"></canvas> <script type="text/javascript"> function draw(){ var canvas = document.getElementById('tutorial'); if(!canvas.getContext) return; var ctx = canvas.getContext("2d"); //开始代码 ctx.fillStyle = "red"; ctx.fillRect(10, 10, 50, 50); //结束代码 } draw(); </script> 这段代码创建了一个300x300的Canvas画布,并在画布上绘制了一个红色的矩形。其中,ctx是Canvas的上下Canvas是HTML5中新增的元素,它可以用来在网页上绘制图形,制作动画等。通过JavaScript脚本,我们可以在Canvas上绘制各种图形,如线条、矩形、圆形、文字等。Canvas的绘图原理是在网页上创建一个画布,然后通过JavaScript脚本来控制画布上的像素,从而实现各种绘图效果。Canvas的使用非常灵活,可以通过CSS样式来设置画布的大小和位置,也可以通过JavaScript脚本来动态地改变画布的属性和内容。 下面是一个简单的Canvas绘图示例: 引用: <canvas id="tutorial" width="300" height="300"></canvas> <script type="text/javascript"> function draw(){ var canvas = document.getElementById('tutorial'); if(!canvas.getContext) return; var ctx = canvas.getContext("2d"); //开始代码 ctx.fillStyle = "red"; ctx.fillRect(10, 10, 50, 50); //结束代码 } draw(); </script> 这段代码创建了一个300x300的Canvas画布,并在画布上绘制了一个红色的矩形。其中,ctx是Canvas的上下文对象,通过它可以控制画布上的像素。 另外,Canvas还可以通过JavaScript脚本来实现动态效果,如引用所示。这段代码创建了一个1000x1000的Canvas画布,并通过JavaScript脚本来实现动态效果。 引用展示了如何使用for循环来实现Canvas的绘图。在这段代码中,我们使用循环来重复绘制一条线段,从而实现了一种简单的图形效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值