`
flyfox1982
  • 浏览: 81350 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

canvas反向裁剪技巧

阅读更多

我们都知道在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/questions/22168619/reverse-clipping-in-canvas
https://stackoverflow.com/questions/18988118/how-can-i-clip-inside-a-shape-in-html5-canvas
http://caibaojian.com/canvas/21.html(非零环绕原则 )

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

 

 
ITman彪叔公众号

 

分享到:
评论

相关推荐

    使用JavaScript+canvas实现图片裁剪

    好了,canvas的介绍就先到这里,下面我们来看看javascript结合canvas实现图片的裁剪代码: 代码如下: var selectObj = null; function ImageCrop(canvasId, imageSource, x, y, width, height) {  var c

    原生js+canvas实现图片裁剪

    在这个函数中,我们创建了一个新的canvas,设置其尺寸为裁剪区域的大小,然后在新canvas上绘制裁剪后的图像。 总结,利用原生JavaScript和canvas,我们可以实现完整的图片裁剪功能。关键在于理解canvas的绘图操作,...

    canvas裁剪

    "canvas裁剪"是Canvas API中的一个重要功能,它允许开发者选取图像的一部分并进行操作,例如保存、显示或者进一步处理。在本文中,我们将深入探讨Canvas裁剪的原理、方法和实际应用。 首先,裁剪Canvas的基础在于`...

    HTML5 canvas 图片裁剪 图片裁切

    5. **创建新canvas**:为了保存裁剪后的图片,创建一个新的canvas元素,其大小等于裁剪区域的宽高。 6. **绘制裁剪图片**:在这个新canvas上,调用`putImageData()`,传入之前获取的像素数据,这样就得到了裁剪后的...

    使用HTML5 canvas 标签进行图片裁剪、旋转、缩放示例代码

    在这个示例中,我们将深入探讨如何利用canvas进行图片的裁剪、旋转和缩放操作。 首先,我们需要在HTML文件中创建一个canvas元素,并通过JavaScript获取到这个元素的2D渲染上下文。在HTML部分,可以这样设置: ```...

    基于cropperjs和canvas实现的图片裁剪

    `Cropper.js`和`Canvas`结合使用,可以提供一种高效、灵活的图片裁剪解决方案。下面将详细介绍这两个技术以及如何将它们应用于实现图片裁剪功能。 `Cropper.js`是一个轻量级的JavaScript库,专门用于图片裁剪。它...

    html5+canvas+js头像缩放裁剪

    7. **保存结果**:最后,当用户确认裁剪结果,可以使用`toDataURL()`方法将Canvas内容转换为数据URL,通常是一个Base64编码的PNG图像,然后可以发送到服务器进行存储。 在实际应用中,可能还需要考虑一些额外的功能...

    canvas图像裁剪压缩旋转

    "canvas图像裁剪压缩旋转"这个主题涵盖了多个关键知识点,包括图片裁剪、缩放、滤镜应用以及旋转,这些都是实现动态图像操作的重要技术。下面将详细讲解这些知识点。 1. 图像裁剪: 使用HTML5的Canvas API,可以...

    Canvas仿微信照片裁剪功能

    本项目正是一个基于Canvas技术实现的仿微信照片裁剪控件,它提供了PC端和移动端的交互体验,包括拖动裁剪、手势放大缩小等功能。下面将详细介绍这个控件的关键知识点和实现原理。 1. **Canvas基础** Canvas是HTML5...

    android_canvas的裁剪功能

    Region.Op.DIFFERENCE 显示第一次不同于第二次的部分 Region.Op.REVERSE_DIFFERENCE 显示第二次不同于第一次的部分 Region.Op.REPLACE 显示第二次的部分 Region.Op.UNION 显示第一次和第二次的所有部分(并集) ...

    daycaca一款基于canvas图片处理类库它可以帮助你处理图片的压缩裁剪等

    2. 图片裁剪:用户可以选择任意区域进行裁剪,Daycaca会使用Canvas的drawImage方法结合clip函数,实现精确的裁剪操作。此功能对于实现自定义头像裁剪、图片预览等功能非常实用。 3. 图片转换:除了基本的压缩和裁剪...

    vue下canvas裁剪图片实例讲解

    总之,在Vue中实现canvas裁剪图片涉及了HTML、CSS和JavaScript的结合使用,理解并掌握canvas的绘图机制是实现这个功能的关键。通过以上步骤,你可以创建一个自定义的图片裁剪组件,灵活地应用到Vue项目中。在实际...

    微信小程序简单的canvas裁剪图片功能详解

    微信小程序的canvas裁剪图片功能可以让开发者在小程序中实现图片的裁剪操作,适用于需要图片处理的各种场景,比如用户头像编辑、图片分享等。在微信小程序中,Canvas API提供了丰富的绘图接口,可以帮助开发者绘制...

    Python基于tkinter canvas实现图片裁剪功能

    实现:tkinter 画布上显示图片,按下鼠标左键并且移动,实现截图 代码如下 # -*- encoding=utf-8 -*- import os import tkinter as tk from PIL import Image from PIL import ImageTk left_mouse_down_x = 0 ...

    微信小程序 图片裁剪功能 (完整源码)

    提供完整源码,能够直接在小程序里正常运行,纯前端代码(canvas画布裁剪),非常简洁,并附有详细的注释、说明重点实现路径和技术细节。 可供小程序初学者或者需要处理图片功能的开发者使用,可在图片上传、头像...

    基于HTML5 canvas实现图片马赛克特效

    <canvas id="myCanvas" width="500" height="500"></canvas> <script src="js/main.js"></script> ``` 接下来,我们需要引入`css/style.css`来设置页面样式,确保canvas元素居中显示等。 然后,我们编写`js/...

    SVG和Canvas绘图:SVG和Canvas的性能优化技巧.docx

    SVG和Canvas绘图:SVG和Canvas的性能优化技巧.docx

    imageCropping:canvas图片裁剪插件

    图片裁剪插件支持两种裁剪方式。 OR代码片段var imageCropping = new ImageCropping({ canvas: document.querySelector('canvas'), // 必填 img: myImg, // 必填 unfixed: { maxWidth: 800, // 可选,设置canvas宽度...

Global site tag (gtag.js) - Google Analytics