刮刮卡,刮完清除遮罩层

  • Post author:
  • Post category:其他


首先你得了解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 版权协议,转载请附上原文出处链接和本声明。