canvas画布裁剪方法的遮罩用途
本帖最后由 马黑黑 于 2022-8-15 16:20 编辑演示和解释帖子标题的命题,我们需要准备好CSS和HTML,很简单:
<style>
#papa { margin: auto; display: grid; place-items: center; width: 1024px; height: 640px; background: url('https://638183.freep.cn/638183/Pic/38/333.png') no-repeat center/cover; position: relative; }
#canv { position: absolute; }
</style>
<div id="papa"><canvas id="canv"></canvas></div>
画布置于一个父窗口之内。父框令子元素绝对居中。为了便于观察,CSS给画布设置了红色边框。
接下来就是通过JS操作画布,思路是在画布创建一个圆形裁剪区域、并在该区域上画一幅图片;圆形裁剪区域的半径循环变大变小,从而达到图片的开启、遮罩效果。
画布的 clip 方法,将上文建立的图形定义为画布的裁剪区,把裁剪区以外的范围“剪掉”、不可访问,随后在画布上绘制的内容只能在裁剪区上可见。
画布画图片,这里指将一张图片“绘制”到画布上,使用 drawImage 方法,该方法我们过去有过介绍。
下面是具体实现代码:
<script type="text/javascript">
let r = 10, speed = 0.5, idx = 0; //裁剪半径、速度
let w = canv.width = 500, h = canv.height = 500; //画布宽高
let ctx = canv.getContext('2d'); //画笔
let image = new Image(); //声明图像对象
image.src = 'https://638183.freep.cn/638183/t22/51/s3.jpg'; //指定图像RUL
image.onload = () =>ctx.drawImage(image, 0, 0, w, h); //图片加载事件 : 将图片画在画布上(本例可以不要这句,演示用)
(function draw() {
ctx.clearRect(0, 0, w, h); //清空画布
ctx.save(); //保存画布状态
ctx.beginPath(); //开启路径
ctx.arc(w / 2, h / 2, r, 0, Math.PI*2);
ctx.clip(); //裁剪上面设定的圆
ctx.drawImage(image, 0, 0, w, h); //在裁剪的区域上作图 : 图片仅能在当前裁剪区域显示
ctx.restore(); //恢复画布之前的保存状态
r += speed; //裁剪区域半径加上变化速度
if (r > w/2 || r <= 0) speed = -speed; // 半径大于画布的一半或小于等于0时(半径不能小于0)速度正负互反
requestAnimationFrame(draw); //定时器运行本函数
})();
</script>
函数 draw 的 if 语句所用到的条件还有其他用途,例如换图片等。整个脚本还可以深加工,做更多的事情。
<style>
#papa { margin: auto; display: grid; place-items: center; width: 700px; height: 640px; position: relative; }
#canv { position: absolute; border: 1px solid red; }
</style>
<div id="papa"><canvas id="canv"></canvas></div>
<script type="text/javascript">
let r = 10, speed = 0.5, idx = 0; //裁剪半径、速度
let w = canv.width = 500, h = canv.height = 500; //画布宽高
let ctx = canv.getContext('2d'); //画笔
let image = new Image(); //声明图像对象
image.src = 'https://638183.freep.cn/638183/t22/51/s3.jpg'; //指定图像RUL
image.onload = () =>ctx.drawImage(image, 0, 0, w, h);
(function draw() {
ctx.clearRect(0, 0, w, h); //清空画布
ctx.save(); //保存画布状态
ctx.beginPath(); //开启路径
ctx.arc(w / 2, h / 2, r, 0, Math.PI*2);
ctx.clip(); //裁剪上面设定的圆
ctx.drawImage(image, 0, 0, w, h); //在裁剪的区域上作图 : 图片仅能在当前裁剪区域显示
ctx.restore(); //恢复画布之前的保存状态
r += speed; //裁剪区域半径加上变化速度
if (r > w/2 || r <= 0) speed = -speed; // 半径大于画布的一半或小于等于0时(半径不能小于0)速度正负互反
requestAnimationFrame(draw); //定时器运行本函数
})();
</script>
有点难的,小白感觉一下子学不会 小辣椒 发表于 2022-8-15 16:36
有点难的,小白感觉一下子学不会
这个需要有JS积累 画布宽度的一半,正好是圆的半径。所以能从0到半径的变化。 ctx.arc(w / 2, h / 2, r, 0, Math.PI*2);
ctx.clip(); //裁剪上面设定的圆
原来这俩一起作用的,我还以为直接ctx.clip(); 就能裁出圆来呢{:4_173:} 红影 发表于 2022-8-15 19:25
ctx.arc(w / 2, h / 2, r, 0, Math.PI*2);
ctx.clip(); //裁剪上面设定的圆
它不接受任何参数,是寄生裁剪的 马黑黑 发表于 2022-8-15 21:07
它不接受任何参数,是寄生裁剪的
嗯,只要设定好了,它就只管裁。 红影 发表于 2022-8-16 22:01
嗯,只要设定好了,它就只管裁。
是的
页:
[1]