学习 canvas 的 globalCompositeOperation 做出的神奇效果

H5 Canvas 中 globalCompositeOperation 的理解和应用 H5 Canvas是HTML5中的一个元素,它拥有丰富的API,允许开发人员通过JS在网页上绘制图形、动画和复杂的视觉效果-比如笔者之前的文章引力粒子特效 - 归为尘埃。本文,我们来讲讲这个重要的属性。 阅读详情

说明

最早知道 canvas 的 globalCompositeOperation 属性,是在需要实现一个刮刮卡效果的时候,当时也就是网上找到刮刮卡的效果赶紧完成任务就完了,这次又学习一次,希望能加深理解吧。

先来看下 canvas 的 globalCompositeOperation属性,具体是干什么的。

定义

globalCompositeOperation 属性设置或返回如何将一个源(新的)图像绘制到目标(已有)的图像上。
源图像 = 您打算放置到画布上的绘图。
目标图像 = 您已经放置在画布上的绘图。

这个属性用来设置要在绘制新形状时应用的合成操作的类型,比如在一个蓝色的矩形上画一个红色的圆形,是红色在上显示,还是蓝色在上显示,重叠的部分显示还是不显示,不重叠的部分又怎么显示,等一些情况,在面对这些情况的时候,就是 globalCompositeOperation 属性起作用的时候了。
在取默认值的情况下,都是显示的,新画的图形会覆盖原来的图形。

用法

默认值: source-over
语法: context.globalCompositeOperation="source-in";

表格中的蓝色矩形为目标图像,红色圆形为源图像。

属性值描述效果
source-over默认。在目标图像上显示源图像。
source-atop在目标图像顶部显示源图像。源图像位于目标图像之外的部分是不可见的。
source-in在目标图像中显示源图像。只有目标图像内的源图像部分会显示,目标图像是透明的。
source-out在目标图像之外显示源图像。只会显示目标图像之外源图像部分,目标图像是透明的。
destination-over在源图像上方显示目标图像。
destination-atop在源图像顶部显示目标图像。源图像之外的目标图像部分不会被显示。
destination-in在源图像中显示目标图像。只有源图像内的目标图像部分会被显示,源图像是透明的。
destination-out在源图像外显示目标图像。只有源图像外的目标图像部分会被显示,源图像是透明的。
lighter显示源图像 + 目标图像。
copy显示源图像。忽略目标图像。
xor使用异或操作对源图像与目标图像进行组合。

好的,下来实现一个水滴扩散的效果
效果图

实现思路

在一个 canvas 上先画出黑白色的图片,然后设置背景是一张彩色的图片,鼠标点击时,设置 canvas 的 globalCompositeOperation 属性值为 destination-out,根据鼠标在 canvas 中的 坐标,用一个不规则的图形逐渐增大,来擦除掉黑白色的图片,就可以慢慢显示彩色的背景了。

也就是说我们需要三张图片

黑白的图片

这里写图片描述

彩色的图片

这里写图片描述

不规则形状的图片

这里写图片描述

代码

<!doctype html>
<html>

<head>
	<meta charset="UTF-8">
	<style>
		canvas {
			/* 设置鼠标的光标是一张图片, 16和22 分别表示热点的X坐标和Y坐标 */
			/* https://developer.mozilla.org/zh-CN/docs/Web/CSS/cursor/url */
			cursor: url('https://www.kkkk1000.com/images/globalCompositeOperation/mouse.png') 16 22, auto;
		}
	</style>
</head>

<body>
	<canvas id="canvas" width="400px" height="250px"></canvas>

	<script type="text/javascript"> 
		var canvas = document.getElementById("canvas");
		var context = canvas.getContext("2d");

		// 保存图片路径的数组
		var urlArr = ["https://www.kkkk1000.com/images/globalCompositeOperation/bg2.png", "https://www.kkkk1000.com/images/globalCompositeOperation/clear.png"];
		// imgArr 保存加载后的图片的数组,imgArr中保存的是真实的图片
		// loadImg 函数用来加载 urlArr 中所有的图片
		// 并返回一个保存所有图片的数组
		var imgArr = loadImg(urlArr);
		// flag 用来限制 点击事件,一张图片只会产生一次效果
		var flag = false;
 

		function loadImg(urlArr) {
			var index = 0;
			var res = [];
			// 每次给 load 函数传入一个图片路径,来加载图片
			load(urlArr[index]);
			function load(url) {
				// 如果 index 等于 urlArr.length,
				// 表示加载完 全部图片了,就结束 load函数
				if (index == urlArr.length) {
					// 加载完全部图片,调用 init 函数
					init();
					return;
				}

				var img = new Image();
				img.src = url;
				// 不管当前图片是否加载成功,都要加载下一张图片
				img.onload = next;
				img.onerror = function () {
					console.log(res[index] + "加载失败");
					next();
				}
				// next 用来加载下一张图片
				function next() {
					// 把加载后的图片,保存到 res 中
					res[index] = img;
					load(urlArr[++index])
				}
			}
			// 最后返回保存所有真实图片的数组
			return res;
		}

		function init() {
			// 先在canvas上画黑白的图片,然后再设置背景是彩色的图片
			// 避免先显示出彩色图片,再显示出黑白的图片
			context.globalCompositeOperation = "source-over";
			context.drawImage(imgArr[0], 0, 0, 400, 250);
			canvas.style.background = 'url(https://www.kkkk1000.com/images/globalCompositeOperation/bg.jpg)';
			canvas.style.backgroundSize = "100% 100%";

			// flag 是 true 时,鼠标点击才有水滴扩散的效果
			flag = true;
			// canvas 绑定点击事件,点击时产生水滴扩散效果
			canvas.onclick =  diffusion;
		}

		// width 表示 不规则形状的图片的尺寸
		var width = 0;
		// speed 表示扩散效果的速度
		var speed = 8;
		// diffusion 函数根据鼠标坐标,产生效果
		function  diffusion (e) {
			if (flag) {
				flag = false;
				context.globalCompositeOperation = "destination-out";
				window.requestAnimationFrame(draw);
				// 根据鼠标坐标,画扩散效果
				function draw() {
					// 这里不一定需要是 1800 ,但必须是一个足够大的数,可以扩散出整张背景图
					if (width > 1800) {
						flag = true;
						return;
					}
					width += speed;
					// 获取鼠标相对于 canvas 的坐标
					var x = e.layerX;
					var y = e.layerY;

					// 画不规则形状的图片,逐渐增大图片尺寸
					context.drawImage(imgArr[1], x - (width / 2), y - (width / 2), width, width);
					window.requestAnimationFrame(draw);
				}
			}
		}
	</script>
</body>

</html>

我们继续来实现一个刮刮卡的效果

效果图

这里写图片描述

刮刮卡效果实现的思路:

一个 canvas 上先画一层灰色,然后设置canvas的背景图,设置 canvas 的 globalCompositeOperation属性值为 destination-out,点击并移动时,根据移动点的坐标,擦除掉灰色,当擦掉一部分时,再自动擦除掉全部灰色,显示出背景来。

刮刮卡的效果和水滴扩散的效果,在开始的时候几乎是一样的,不过水滴扩散效果,用的是一张不规则形状的图片来清除黑白图片,而刮刮卡效果,是通过画线的方式,线比较粗而已,来清除上面的灰色。
主要的不同是,刮刮卡效果最后需要自动擦除掉全部灰色,这里有两种方式。

第一种
使用 canvas 的 getImageData 方法,来获取 canvas 上的像素信息,这个方法返回的对象的 data 属性是一个一维数组,包含以 RGBA 顺序的数据,数据使用 0 至 255(包含)的整数表示,详细的可以看看 canvas 的像素操作。
用这个方法来判断有多少已经擦除掉了,也就是通过一个变量来记录有多少像素的RGBA的值是0,当变量的值超过某一个值时,就清除全部灰色。

代码在这里。

第二种
就直接看移动了多少,鼠标移动时,会有一个变量进行自增运算,当这个变量,超过一定值时,就擦除全部灰色。

代码在这里。

注意:
第一种方式使用 getImageData 存在跨域问题,不过因为这个效果中,没有在canvas上画图片,而是设置canvas的 background 为一张图片,所以这个还没有影响,但是如果canvas上画了其他图片,就可能需要处理跨域的问题了。
使用 getImageData 能获取到 canvas 上的像素信息,就可以根据刮刮卡上灰色的面积,决定擦除全部灰色的时机,更加灵活。

第二种方式,虽然不存在跨域的问题,但是,不能很好的根据刮刮卡上灰色的面积,控制最后擦除全部灰色的时机。

总结

文章中的效果主要是使用 globalCompositeOperation属性取值为 destination-out ,而取值为其他值的时候,同样也是可以制作出各种效果的,大家也可以发挥自己的想象力,去试试其它值,也许有新发现呢。

Canvas的globalCompositeOperation属性详解和小练习&&实现放大镜 阅读详情

相关推荐

AFSim仿真系统中的图像处理器:从静态图像到视频流的目标识别技术解析

本文深入解析了AFSim仿真系统中WSF_IMAGE_PROCESSOR图像处理器的核心功能与技术实现。它详细阐述了该处理器如何从静态图像与视频流中完成目标检测、跟踪与识别,将原始像素数据转化为可供指挥系统使用的轨迹情报,并重点介绍了其基于约翰逊准则的目标识别进阶逻辑、关键参数配置以及脚本扩展能力,为构建高逼真度仿真应用提供了实践指导。

cola5的博客 213

动画效果之 Canvas学习-globalCompositeOperation详解

本节介绍一下globalCompositeOperation,以的形式说明每个属性。 globalCompositeOperation与cilp()的区别: globalCompositeOperation用于控制源图像在目标图像上的显示方式。 源图像: 指你准备绘制到画布上的图像 目标图像:在画布上已经绘制的图像 clip() 方法从原始画布中剪切任意形状和尺寸。 提示:一旦剪切了某个区域...

咖啡味的小认真 3841

RK3588开发板RKNPU2环境部署实战:更新rknn_server与librknnrt.so详解

本文详细介绍了在RK3588开发板上更新rknn_server与librknnrt.so核心组件的完整实战流程。通过adb工具推送文件、设置权限并执行同步操作,确保RKNPU2环境部署成功,从而解决推理速度慢或初始化失败等问题,提升AI模型运行效率与稳定性。

weixin_29194817的博客 340

学习 canvas 的 globalCompositeOperation 做出的神奇效果(刮刮卡效果实现的思路)

https://blog.youkuaiyun.com/fe_dev/article/details/81985367

u012833739的博客 502

数字IC后端笔记-libcell命名规则与标准单元库介绍

ND3D1BWP13T40P140HVTND3D1BWP13T40P140HVTTSMC两种工艺,Metalization Stack的截面示意图:还有一层AP用来走RDL,RDL这层是最厚的一层,一般用于连接IO的bump,信号线基本上不会用这层绕线。

sinat_41774721的博客 2462

PLc S7-200 smart如何使用Modbus 485通讯传输接收数据

西门子在 STEP 7-Micro/WIN SMART 中正式推出 Modbus RTU 主站协议库(西门子标准库指令)。使用 Modbus RTU 主站指令库,可以读写 Modbus RTU 从站的数字量、模拟量 I/O 以及保持寄存器,从而实现PLC通过modbus方式控制其他器件。提示:以下是本篇文章正文内容,下面案例可供参考。

xjbsw0的博客 6万+

豆包MarsCode 助力:Canvas 上的素描变色魔法✨

作者:BLACK595????嘿!首先,先来看超酷的效果哦????!????素描图在用户鼠标按下后,就像被施了魔法一样????♂️,将鼠标范围内的素描像素神奇地转换成有色像素????。动图无法展示,感兴趣的朋友可以移步:https://juejin.cn/post/7410410146483781673#heading-3原理设置原图A在底层将模糊...

cnzzs的博客 1350

Oracle PLM Agile936 单点登录配置方式

Oracle PLM Agile936 单点登录配置方式

Jay的个人博客 824

如何用 JavaScript+Canvas 开发一款超级烧脑小游戏?

作者 |huangjianke 责编 | 伍杏玲 出品 | 优快云(ID:优快云news) 【优快云 编者按】据微信最新数据,微信小游戏累计注册用户量已突破10亿。那么初学者如何开发一款好玩又烧脑的微信小游戏呢?本文作者将详细为大家讲解。 “启逻辑之高妙,因想象而自由。”层叠拼图Plus是一款需要空间想象力和逻辑推理能力完美结合的微信小游戏,偶消奇不消,在简单的游戏规...

优快云资讯 2935

LaTex的下载与安装(2024小白+windows系统)

本文主要介绍了Latex的下载与安装,还包括安装过程中遇到的小问题的解决。

m0_53096519的博客 2万+

24、虚拟地理信息系统:技术与应用的全面解析

本文全面解析了虚拟地理信息系统(虚拟GIS)的技术架构与应用前景。文章从地理空间数据的增长出发,探讨了虚拟GIS在地形、建筑、天气等多维度数据的交互式可视化技术,重点介绍了全球层次结构、多分辨率模型、缓存分页机制及交互导航方法。系统已应用于天气分析、城市规划、应急响应等领域,并展望了未来在数据处理、模拟操作、移动可视化及智能城市、文化遗产保护等方向的发展路径与技术挑战。

v4w5x6的博客 88

如何知道当前像素的顶点坐标_如何用 JavaScript+Canvas 开发一款超级烧脑小游戏?...

作者 |huangjianke责编 | 伍杏玲出品 | 优快云(ID:优快云news)【程序人生 编者按】据微信最新数据,微信小游戏累计注册用户量已突破10亿。那么初学者如何开发一款好玩又烧脑的微信小游戏呢?本文作者将详细为大家讲解。“启逻辑之高妙,因想象而自由。”层叠拼图Plus是一款需要空间想象力和逻辑推理能力完美结合的微信小游戏,偶消奇不消,在简单的游戏规则下却有着无数种可能...

weixin_39774556的博客 215

2025机械考研复试面试问题汇总篇(含13门科目),考研机械复试专业面试常见重点问题总结!考研机械复试专业面试准备看这一篇就够了!

(完整版内容:)1.汇集了本科各科的重点知识及多个机械名校800多个常见问题,共8.7万字185页,涵盖机械所以专业课的重点知识和常见问答。 2.涉及机械大类重点科目,包括:材料力学、控制工程、数控技术、机械制造技术基础、理论力学、液压传动、机械设计、机械原理、工程材料、互换性与技术测量、测试技术、汽车理论、程序设计与C语言等13门必修课。

weixin_56510835的博客 1861

canvas中globalCompositeOperation属性值所代表的的值表达含义及样式

CANVAS属性记录  一:globalCompositeOperation的属性 CanvasRenderingContext2D.globalCompositeOperation Canvas 2D API的 属性设置在绘制新形状时要应用的合成操作的类型。 1.1 Type类型 1.2 source-over 这是默认设置,并在现有画布内容的顶部绘制新形状 1.3 source-in 新图形仅在新图形和目标画布重叠的位置绘制。其他一切都是透明的。 const canvas = this.$re

qq_1307495的博客 1850

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【HTML5】Canvas之globalCompositeOperation属性详解

HTML5 Canvas globalCompositeOperation属性详解

laijieyao的专栏 3万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

canvas中颜色合成之globalCompositeOperation属性学习

globalCompositeOperation属性有点类似ps中的混合模式。 该属性一共有12种属性值: source-over 默认。在目标图像上显示源图像。 source-atop 在目标图像顶部显示源图像。源图像位于目标图像之外的部分是不可见的。 source-in 在目标图像中显示源图像。只有目标图像内

cheng198938的博客 1787

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

html5属性详解,【HTML5】Canvas之globalCompositeOperation属性详解

globalCompositeOperation即Canvas中的合成操作。1、source-over这是默认值,他表示绘制的图形将画在现有画布之上$(document).ready(function(){varcanvas=document.getElementById("myCanvas");varcontext=canvas.getContext("2d");context.fillStyl...

weixin_34620658的博客 687

从零开始学习在VUE3中使用canvas(五):globalCompositeOperation(图形混合)

本文介绍了canvas中图像混合的用法以及属性

qq_45820271的博客 1855

canvas基础——绘制简单的图形

绘制直线: HTML部分: 1 <canvas id="myCanvas" style="border:1px solid #000;" width="200px" height="100px"></canvas> JS部分: 1 window.onload = function(){ 2 var c = document.getElement...

weixin_34347651的博客 316

Canvas学习笔记六 - 合成裁剪与动画

在此之前,总是将一个图形画在另一个之上,对于其他更多的情况,仅仅这样是远远不够的。比如,对合成的图形来说,绘制顺序会有限制。不过,我们可以利用 globalCompositeOperation 属性来改变这种状况。此外, clip属性允许我们隐藏不想看到的部分图形。 一、globalCompositeOperation 通过globalCompositeOperation属性,不仅可以在已有图形后面再画新图形,还可以用来遮盖指定区域,清除画布中的某些部分(清除区域不仅限于矩形,像clearRect()方法做

blog 445

Canvas里的globalCompositeOperation

Canvas里的globalCompositeOperation是个很少用到的函数,不太熟悉程序绘图的同学们估计压根都不知道这玩意是干什么的.简单来说,Composite(组合),就是对你在绘图中,后绘制的图形与先绘制的图形之间的组合显示效果,比如在国画中,你先画一笔红色,再来一笔绿色,相交的部分是一种混色,而在油画中,绿色就会覆盖掉相交部分的红色,这在程序绘图中的处理就是Composite,Ca...

weixin_33885676的博客 224

Canvas之globalAlpha和globalCompositeOperation

Canvas之globalAlpha和globalCompositeOperation前言一、区别二、使用方法1.globalAlpha2.globalCompositeOperation总结 前言 这里为Canvas画布的补充,是关于画布元素透明度的两个属性的用法和区别 一、区别 golbalAlpha 是使全局具有透明度 globalCompositeOperation 是渲染绘制的图像在重叠时的效果 globalAlpha = 1; globalCompositeOperation = "

yunmegnze的博客 506
上一篇: 小程序—九宫格心形拼图
下一篇: 用 canvas 的 getImageData 做点有趣的事
FEWY
FEWY 领域专家: 前端开发技术领域 领域专家: 前端开发技术领域
博客等级 码龄10年 504粉丝 77原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值