AlexZ33 / canvas_demo

一个canvas实例仓库
2 stars 2 forks source link

在图片上实现水滴扩散效果 #7

Open AlexZ33 opened 3 years ago

AlexZ33 commented 3 years ago

前言:

canvas的globalComposietOperation属性:

source-out:只显示新图片和已存在图片未重叠的部分

image

destination-out: 显示已存在图片和新绘制图片未重叠的部分(该部分是已存在图片的部分) image

window.requestAnimationFrame:让图像动起来

参考文档:

https://juejin.im/post/5b87de766fb9a01a175dce1e

https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation

AlexZ33 commented 3 years ago
<canvas id="canvas" width="400px" height="250px"></canvas>
<div style="display: none;">
<img id="sourceImage" src="https://user-gold-cdn.xitu.io/2018/8/30/1658abd14d14b88a?w=640&h=360&f=png&s=221487" width="400px" height="250px">
</div>
<script type="text/javascript">
window.onload = function() {
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var imgArr = document.getElementById('sourceImage');

// flag 用来限制点击事件,一张图片只会产生一次效果
var flag = false;
init()
function init() {
// 先在canvas上画黑白的图片,然后再设置背景是彩色的图片
// 避免先显示出彩色图片,再显示出黑白的图片
context.globalCompositeOperation = "source-out";
context.drawImage(imgArr, 0, 0, 400, 250);
canvas.style.background = 'url(https://user-gold-cdn.xitu.io/2018/8/30/1658abd157ad9e8b?w=640&h=360&f=jpeg&s=44022)';
canvas.style.backgroundSize = "100% 100%";

// flag 是 true 时,鼠标点击才有水滴扩散的效果
flag = true;
// canvas 绑定点击事件,点击时产生水滴扩散效果
canvas.onclick = diffusion;
}
// diffusion 函数根据鼠标坐标,产生效果
function diffusion (e) {
if (flag) {
flag = false;
// width 表示 扩散形状的图片的尺寸
let width = 0
// speed 表示扩散效果的速度
let speed = 8
context.globalCompositeOperation = "destination-out";
window.requestAnimationFrame(draw);
// 根据鼠标坐标,画扩散效果
function draw() {
context.beginPath();
context.arc(e.offsetX, e.offsetY, width, 0, 2 * Math.PI, false);
context.fill();
// 通过判断半径小于元素宽度,不断绘制 width += speed 的圆形
width += speed;
// 这里不一定需要是 1900 ,但必须是一个足够大的数,可以扩散出整张背景图
if (width < 1900) {
window.requestAnimationFrame(draw);
}
}
}
}

}
</script>