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/que...
https://stackoverflow.com/que...
http://caibaojian.com/canvas/...(非零环绕原则 )

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/449457.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

set 和select 的区别

简单赋值是没有区别的 转载于:https://www.cnblogs.com/bingyizhihun/p/10597908.html

postgres大版本升级

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。进行升级版本之前请一定做好备份!查看当前版本:[postgresnode1 ~]$ psqlpsql (9.4.4)Type "help" for h…

马上有钱:揭密25种成为有钱人的方法(图)

1、做你真正感兴趣的事—你会花很多时间在上面,因此你一定要感兴趣才行,如果不是这样的话,你不愿意把时间花在上面,就得不到成功。 2、自己当老板。为别人打工,你绝不会变成巨富,老板一心一意地缩减开支&a…

无人承运平台系统流程图

转载于:https://www.cnblogs.com/procedureMonkey/p/10598052.html

Neither the JAVA_HOME nor the JRE_HOME environment variable is defined

Centos7.5 启动tomcat报错 报错: Neither the JAVA_HOME nor the JRE_HOME environment variable is defined At least one of these environment variable is needed to run this program原因:没有安装java 解决方法:安装java yum install java -y转载于:https://www.cnblogs…

让自己变成一个上进的人

1.认真设计你的环境2.引入外部监督 求“绑架”3.获取不确定的反馈4.选择一条既细密,又永无止境的职业上升台阶。转载于:https://www.cnblogs.com/Julietma/p/10600241.html

年买笔记本的8个小技巧 最适合自己才最好(组图)

显然,智能手机和平板在一定程度上可以替代传统电脑,让我们可以随时随地上网、使用各种应用。不过,传统电脑也拥有它的不可替代性,比如移动办公、视频编辑、玩游戏,笔记本电脑可能是个更好的选择。 作为一种成熟的电脑…

MySql查询系统时间,SQLServer查询系统时间,Oracle查询系统时间

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 MySQL查询系统时间 第一种方法:select current_date; MySQL> select current_date as Systemtime; 第二…

flask同源策略解决办法及flask-cors只允许特定域名跨域

falsk 同源策略解决办法: 使用 flask-cors 包 并且 在代码里 加响应的一行代码解决。 from flask import Flask, session from flask_cors import CORSapp Flask(__name__) CORS(app, resources{r"/*": {"origins": "*"}}) # 允许…

基本变量和引用变量

基本数据类型作比较,值相等则相等,值不相等则不相等(忽略数据类型) 引用类型作比较,引用地址相等则相等,否则都是不等的。 基本数据类型,和引用数据类型作比较,是比较值是否相等&…

真格量化-持仓量第n档卖方主力跟随策略

#!/usr/bin/env python # coding:utf-8 from PoboAPI import * import datetime import time import numpy as np import pandas as pd #日线级别 #开始时间,用于初始化一些参数 def OnStart(context):print("I\m starting...")#设定一个全局变量品种,本策略交易50E…

赚大钱必备 怎样成为赚钱高手(图)

1、一旦有赚钱的念头就马上一步一个脚印去做,要付诸行动,敢于碰,善于磨,只有这样才能抓住机会。 2、想赚钱,就要立志当商人,而且目标要高,选定十万、二十万,再是一百万、五百万。 …

不定长图片验证码训练

基于LSTM和CTCLoss训练不定长图片验证码 Github项目地址:https://github.com/JansonJo/captcha_ocr.git # codingutf-8 """ 将三通道的图片转为灰度图进行训练 """ import itertools import os import re import random import strin…

[云框架]KONG API Gateway v1.5 -框架说明、快速部署、插件开发

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 当前版本采用KONGv0.12.3 当我们决定对应用进行微服务改造时,应用客户端如何与微服务交互的问题也随之而来,毕竟…

真格量化-主力跟买策略

#!/usr/bin/env python # coding:utf-8 from PoboAPI import * import datetime import time import numpy as np import pandas as pd #日线级别 #开始时间,用于初始化一些参数 def OnStart(context):print("I\m starting...")#设定一个全局变量品种,本策略交易50E…

顶级投资者的21条箴言(组图)

每天你都会听见五花八门的投资建议,告诉你应该买入还是卖出。如果这让你感到无所适从,不妨静下心来,听听历史上最成功的投资者的建议。 我们搜集了21位顶尖大牛的投资箴言,以飨读者。 1、George Soros:好的投资总是无…

python 游戏 —— 汉诺塔(Hanoita)

一、汉诺塔问题 1. 问题来源 问题源于印度的一个古老传说,大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆…

Base62x比Base64的编码速度更快吗?

现在几乎所有企事业单位、政府机构、军工系统等的IT生产系统都会用到Base64编码,从RSA安全密钥到管理信息系统登录入口回跳,目前越来越多的IT系统研发者开始使用 Base62x 替换 Base64. -Base62x 提供了一种无符号输出的Base64的编码方案,在许…

对Docker常用命令的整理

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 查看docker版本信息、 #docker version #docker -v #docker info image镜像操作命令 #docker search image_name //检索image #docker p…

再说千遍万遍,都不如这四句话管用,不服不行!

一、健康是最大的利益    人有时候,真不知要谋求什么?往往把最值得维护和珍贵的东西忽视了,却不知拣了芝麻丢了西瓜。   现在好多人都在透支健康,燃烧生命,经常借口工作忙、应酬多,不注意生活方式&…