前端-原生-Canvas-刮刮乐

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Canvas创意</title>
    <script src="../libs/Ticket.js"></script>

    <style>
      body {
        margin: 0px;
      }
    </style>
  </head>
  <body>
    <!-- 刮刮乐 -->
    <div>
      <canvas id="canvas-ticket"></canvas>
    </div>

    <script type="text/javascript">
      (function () {
        //刮刮乐
        let canvasTicket = document.getElementById("canvas-ticket");
        let ticket = new Ticket();
        ticket.init(
          canvasTicket,
          "https://file.idongjia.cn/T3MpCgB7CT1RCvBVdK.png",
          "https://file.idongjia.cn/T3tKAgBXYT1RCvBVdK.png",
          () => {
            ticket.clean();
          }
        );
      })();
    </script>
  </body>
</html>
/**刮刮乐*/
class Ticket {
  constructor() {
    this.ctx = null;
    this.imgData = null;
    this.isDown = false;
    this.img = new Image();
    this.pst = 0.5;
    this.backFun = null;
  }
  init(canvas, bg, cover, backFun = null, pst = 0.5) {
    this.backFun = backFun;
    this.pst = pst;
    this.ctx = canvas.getContext("2d");
    canvas.style.backgroundImage = "url(" + bg + ")";
    canvas.style.backgroundPosition = "center";
    canvas.style.backgroundRepeat = "no-repeat";
    canvas.style.backgroundSize = "contain";
    this.img.crossOrigin = "";
    this.img.src = cover;
    this.img.onload = () => {
      canvas.width = this.img.width;
      canvas.height = this.img.height;
      this.ctx.drawImage(this.img, 0, 0, this.img.width, this.img.height);
    };

    canvas.addEventListener("mousemove", (event) => {
      this.move(event.offsetX, event.offsetY);
    });
    canvas.addEventListener("mousedown", () => {
      this.start();
    });
    canvas.addEventListener("mouseup", () => {
      this.end();
    });

    canvas.addEventListener("touchmove", (e) => {
      let dx = canvas.offsetLeft; //记录div当时的左偏移量
      let dy = canvas.offsetTop; //记录div的上偏移量
      let offsetX = e.touches[0].pageX - dx;
      let offsetY = e.touches[0].pageY - dy;
      this.move(offsetX, offsetY);
    });
    canvas.addEventListener("touchstart", () => {
      this.start();
    });
    canvas.addEventListener("touchend", () => {
      this.end();
    });
  }
  start() {
    this.isDown = true;
  }
  move(offsetX, offsetY) {
    if (this.isDown) {
      let x = offsetX;
      let y = offsetY;
      this.ctx.beginPath();
      this.ctx.fillStyle = "white";
      this.ctx.arc(x, y, 20, Math.PI * 2, false);
      this.ctx.fill();
      this.ctx.closePath();
      this.ctx.globalCompositeOperation = "destination-out";
    }
  }
  end() {
    this.isDown = false;
    this.imgData = this.ctx.getImageData(0, 0, this.img.width, this.img.height);
    let zeroNum = 0;
    this.imgData.data.map((it) => {
      if (it === 0) {
        zeroNum++;
      }
    });
    //达到百分比就证明挂完了
    let currPst = zeroNum / this.imgData.data.length;
    if (this.pst <= currPst) {
      if (this.backFun) {
        this.backFun();
      }
    }
  }
  clean() {
    let tempImageData = this.ctx.createImageData(this.imgData);
    tempImageData.data.map((it) => {
      it = 0;
    });
    this.ctx.putImageData(tempImageData, 0, 0);
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值