首先你得了解globalCompositeOperation 的一些属性
globalCompositeOperation
效果:
// source-over 绘制图形的 默认 混合方式,直接在现有图形的上方绘制,纯视觉覆盖 原和新都会显示
// context.globalCompositeOperation = source-over;
// source-in 仅在和原Canvas图形重叠的位置绘制新图形,否则处理为透明。
//如果重叠位置是半透明颜色,则也处理为半透明。此效果类似遮罩,新内容为显示层(上),
//原内容是遮罩层(底),遮罩层无论张什么样子,都不显示。
// context.globalCompositeOperation = "source-in";
// source-out 和source-in相反,重叠的位置是透明的,不重叠的或者半透明的重叠区域反而显示新图形。
//同样,原内容无论性质如何,最终效果都不会出现。
// context.globalCompositeOperation = "source-out";
// source-atop 仅在新内容和原内容重叠的位置进行类型遮罩的绘制,没有重叠的部分原内容也会绘制,新内容不重叠的位置不绘制。
// context.globalCompositeOperation = "source-atop";
//destination-*系列和source-*系列的区别就是动作的主体是新内容还是原内容。source-*系列是新内容,而destination-*系列动作主体是原内容。
// 首先呢 奖品图肯定是最底下的 然后灰色遮罩层给它盖住 画笔画轨迹就是相当于擦除
// 就是画笔画出来的轨迹跟灰色遮罩层相交部分给它隐藏
// 隐藏原内容和新内容重叠的部分。 灰色遮罩层就是原内容 画的圆就是新内容
//画圆跟灰色遮罩重叠一起,重叠部分影藏 底部内容就会显示出来
// context.globalCompositeOperation = "destination-out";
<template>
<div class="ggk" id="ggk">
<img class="award" v-if="award" src="../assets/canvas.png" alt="" />
<div class="award" v-else>谢谢惠顾</div>
<canvas id="canvas1" width="250" height="100">
你的浏览器不支持canvas 就显示这里
</canvas>
</div>
</template>
<script>
import { onMounted, ref } from "vue";
export default {
name: "",
setup() {
let award = ref(false);
onMounted(() => {
let canvas = document.querySelector("#canvas1"); //获取canvas对象
let context = canvas.getContext("2d"); //画笔
let ggk = document.querySelector("#ggk");
// 遮罩画布
context.fillStyle = "#ccc";
context.fillRect(0, 0, 250, 100);
// 文字
context.font = "20px 微软雅黑";
context.fillStyle = "#fff";
context.fillText("奖品", 112, 60);
let isDraw = false;
let lock = true;
// 按下或者触摸事件 设置 isDraw=true,即为允许绘制
// canvas.onmousedown = () => { // pc
canvas.ontouchstart = () => {
isDraw = true;
let num = Math.round(Math.random() * 10);
if(!lock) return;
if (num >= 5) {
award.value = true; //中奖
} else {
award.value = false; //未中奖
}
lock = false;
};
// 移动的时候 进行绘制 将上层图层清除掉
// canvas.onmousemove = (e) => { // pc
canvas.ontouchmove = (e) => {
if (!isDraw) return;
// 找到圆心 创建一支画圆的笔
// let x = e.pageX - ggk.offsetLeft; // pc
// let y = e.pageY - ggk.offsetTop; // pc
let x = e.changedTouches[0].pageX - ggk.offsetLeft;
let y = e.changedTouches[0].pageY - ggk.offsetTop;
// 隐藏原内容和新内容重叠的部分。 灰色遮罩层就是原内容
//画的圆就是新内容 画圆跟灰色遮罩重叠一起,重叠部分影藏
//底部内容就会显示出来
context.globalCompositeOperation = "destination-out";
context.arc(x, y, 20, 0, 2 * Math.PI);
context.fill();
};
// canvas.onmouseout = () => { // pc
// isDraw = false;
// };
// canvas.onmouseup = () => { // pc
canvas.ontouchend = () => {
isDraw = false;
getFilledPercentage();
};
// 计算已经刮过的区域占整个区域的百分比
function getFilledPercentage() {
let imgData = context.getImageData(0, 0, 250, 100); //获取画布中的所有像素
let pixels = imgData.data; //得到像素的字节数据
let transparent = 0; //设置一个变量来记录已经变为透明的像素点的数量
for (let i = 0; i < pixels.length; i += 4) {
let alpha = pixels[i + 3]; //获取每个像素的透明度数值
if (alpha < 10) transparent++; //当透明度小于10时,认为它已经被擦除,transparent数值加1
}
let percentage = transparent / (pixels.length / 4); //计算透明像素在所有像素点中所占比例
if (percentage > 0.5) {
// 当像素点的个数超过 60% 时,清空画布,显示底图
context.clearRect(0, 0, 250, 100);
}
}
});
return {
award,
};
},
components: {},
};
</script>
<style scoped lang="scss">
.ggk {
display: inline-block;
width: 250px;
height: 100px;
position: relative;
.award {
width: 250px;
height: 100px;
line-height: 100px;
position: absolute;
top: 0;
left: 0;
background: rgb(180, 214, 206);
}
#canvas1 {
width: 250px;
height: 100px;
line-height: 100px;
position: absolute;
top: 0;
left: 0;
}
}
</style>
版权声明:本文为Wancc123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。