我们都知道在canvas 可以通过clip来实现剪裁功能,其步骤一般是先设置要裁剪的区域(路径),然后通过ctx.clip()的实现裁剪,裁剪之后,后续的绘制只能在裁剪的区域显示效果,比如如下一段代码,实现了一个圆形裁剪:

ctx.beginPath();
ctx.arc(100,100,50,0,Math.PI*2);
ctx.clip();ctx.rect(0,0,200,200);
ctx.fillStyle='red';
ctx.fill();

最终效果如下:

有的时候,我们希望能够实现反向裁剪,比如上面例子中,我们希望是圆圈外面是裁剪区域,而不是圆圈内部是裁剪区域。这就是标题所说的反向裁剪。效果如下图所示:

如何实现反向裁剪呢?
笔者通过实践,发现有以下几种思路。

使用合成模式globalCompositeOperation

通过设置globalCompositeOperation的值,可以实现类似的反向裁剪的效果。大致思路是:

  • 首先绘制一个图形(比如圆形),该图形外部的区域将会是裁剪区域
  • 设置globalCompositeOperation的值为source-out
  • 然后绘制想要绘制的图形(比如矩形)

示例代码如下:

 ctx.beginPath();ctx.arc(100, 100, 50, 0, Math.PI * 2);
ctx.fillStyle = 'red';
ctx.fill();ctx.beginPath();
ctx.globalCompositeOperation = 'source-out';
ctx.rect(0, 0, 200, 200);
ctx.fillStyle = 'red';
ctx.fill();

最终效果参考上面的图形“反向裁剪”。

使用clip + clearRect方法

另外一种思路是使用clip + clearRect方法,大概的思路如下:

  • 首先绘制要绘制的图形(比如矩形)
  • 然后设置要反向裁剪的图形的路径(比如圆形)
  • 然后调用clip ,再调用clearRect方法清除圆形区域的像素。

示例代码如下:

   ctx.beginPath();ctx.rect(0, 0, 200, 200);ctx.fillStyle = 'red';ctx.fill();ctx.beginPath();ctx.arc(100, 100, 50, 0, Math.PI * 2);ctx.clip();ctx.clearRect(0, 0, 200, 200);

最终效果参考上面的图形“反向裁剪”。

利用非零环绕原则

我们知道非零环绕原则,可以通过调整路径的方向(顺时针和逆时针),来实现挖空的效果,大致思路如下:

  • 首先构建一个大的区域路径(顺时针方向),比如矩形
  • 然后构建一个小的区域路径(逆时针方向),比如圆形
  • 调用clip裁剪,然后绘制图形

示例代码如下:

ctx.beginPath();
ctx.rect(0, 0, 200, 200); //顺时针方向
ctx.arc(100, 100, 50, 0, Math.PI * 2, true); // 逆时针方向
ctx.clip();ctx.beginPath();
ctx.rect(0, 0, 200, 200);
ctx.fillStyle = 'red';
ctx.fill();

arc方法的最后一个参数可以控制顺时针(false)和逆时针(true),而rect方法没有,可以通过moveTo,lineTo,自己构建逆时针的rect方法,如下代码所示:

function counterclockwiseRect(ctx, x, y, w, h) {ctx.moveTo(x, y);ctx.lineTo(x, y + h);ctx.lineTo(x + w, y + h);ctx.lineTo(x + w, y);ctx.lineTo(x, y);
}

最终效果参考上面的图形“反向裁剪”。

参考文档

https://stackoverflow.com/que...
https://stackoverflow.com/que...
http://caibaojian.com/canvas/...(非零环绕原则 )

欢迎关注公众号“ITman彪叔”。彪叔,拥有10多年开发经验,现任公司系统架构师、技术总监、技术培训师、职业规划师。熟悉Java、JavaScript、Python语言,熟悉数据库。熟悉java、nodejs应用系统架构,大数据高并发、高可用、分布式架构。在计算机图形学、WebGL、前端可视化方面有深入研究。对程序员思维能力训练和培训、程序员职业规划有浓厚兴趣。

canvas反向裁剪技巧相关推荐

  1. html图片自动剪裁,HTML canvas图像裁剪

    canvas drawImage方法的图像裁剪理解可能会比较耗时,记录一下,以便供人翻阅! context.drawImage(img,sx,sy,swidth,sheight,x,y,width,h ...

  2. css clip-path裁剪形状,实现绘制常用的形状和图形。反向裁剪

    效果图: 图1: 图2: 图3: 代码: <!DOCTYPE html> <html lang="en"> <head><meta cha ...

  3. 使用 canvas 居中裁剪图片

    在日常开发中,想必不少小伙伴有涉及到图片上传的功能,今天我们就来捋一捋上传图片时,如果图片大于规定尺寸,用 canvas 居中裁剪. 首先我们来熟悉一下 canvas 的 drawImage()的用法 ...

  4. html5垂直线怎么画,HTML5 Canvas画线技巧

    正统的HTML5 Canvas中如下代码 复制代码代码如下: ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(10, 100); ctx.lineTo(3 ...

  5. (H5)canvas实现裁剪图片和马赛克功能,以及又拍云上传图片

    1.核心功能 此组件功能包含: 图片裁剪(裁剪框拖动,裁剪框改变大小): 图片马赛克(绘制马赛克,清除马赛克): 图片预览.图片还原(返回原图.返回处理图): 图片上传(获取签名.上传图片). 2.核 ...

  6. canvas图片裁剪并base64转化

    一.需求 在canvas画布上,假设我们绘制了一张图片,现在需要将该图片进行裁剪,并将裁剪的区域提取成图像,并将该图像转化为base64格式返回,要求编写这样一个脚本. 二.知识储备 HTML5画布中 ...

  7. 使用canvas图片裁剪

    最近在做项目中需要裁剪图片上某一处位置的头像,这边就记录下我的实现的操作 演示效果:  直接上代码: <template><div v-if="croppingUrl&qu ...

  8. 关闭裁剪功能_4个图片裁剪技巧,瞬间看出Word大神与小白的差距!

    当我们用Word对长篇文档进行排版的时候,难免会插入一些图片,有时插入的图片大小尺寸不符合要求,就需要我们手动去裁剪调整.今天,这篇文章主要是介绍文档排版时,图片大小尺寸的设置方法,非常实用哦!Wor ...

  9. 「前端必看」这篇Nginx反向代理技巧,助你准时下班陪女神

    点击上方蓝字"大前端技术沙龙"关注我 您的关注意义重大 原创@大前端技术沙龙 最近同事小G总是闷闷不乐,让我感觉慌慌的,难道是我平时压榨小G了?我转念一想,不应该啊,工作量事先都评 ...

最新文章

  1. 业余快速学习虚幻引擎教程
  2. 【Latex】一些使用
  3. linux 清空文件内容命令
  4. 17、document的全量替换,document的强制创建,document的删除(来源网络课程中的学习笔记)
  5. parted工具详解
  6. 匈牙利命名法为何被淘汰_被称为手表中“蓝血贵族”的百达翡丽,为何会受到如此的追捧?...
  7. 华为荣耀手机指令代码大全_华为手机指令代码大全
  8. 程序员眼中的“鼠标宏”
  9. Win11控制面板里没有高清音频管理器怎么办?
  10. python词云词频分析_Python数据挖掘:WordCloud词云配置过程及词频分析
  11. 物理光学3 电磁波的折射与反射
  12. 当你对未来迷茫的时候,请打开这个锦囊
  13. Windows超级管理器
  14. krnln.fnr和shell.fne_电脑开机显示failedtoloadkernllibrary什么意思啊
  15. Mathorcup数学建模竞赛第六届-【妈妈杯】B题:小区车位分布的评价和优化模型(附特等奖获奖论文和Java代码)
  16. 产品读书《让大象飞:激进创新,让你一飞冲天的创业术》
  17. CList 简单用法
  18. 19年的桌面KDE的风雨和陪伴,没有什么能够割舍
  19. 毁灭一切还是重塑世界?AI已成为人类故事中心
  20. 批发供应系统批发订货发货管理系统开发功能

热门文章

  1. java获取u盘_实例分享java监听u盘的方法
  2. linux 设备 major 253,redhat5.5测试环境中使用udev配置raw设备
  3. 普通IO流字符输入输出流文件拷贝
  4. java 屏蔽邮箱_使用javamail发送邮件的时候如何阻止附件内容输出到控制台
  5. JDBC 连接MYSQL数据库
  6. sizeof运算符运算结果小汇
  7. C++:34---union:联合/共用体,一种节省空间的类
  8. 惠普服务器查询ilo信息,Hp服务器iLO IML硬件日志收集与远程巡检
  9. Java提高篇 —— Java关键字之final的几种用法
  10. docker-compose 使用小例