两张图片实现擦除效果(canvas)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0;"
    />
    <title>橡皮擦效果</title>
    <style type="text/css">
      html,
      body {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
      }
      .view {
        position: relative;
        width: 100%;
        height: 100%;
        overflow: hidden;
      }
      .box {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        background: #000 url("./image/1.jpg") no-repeat center center;
        background-size: auto 100%;
        backface-visibility: hidden;
        overflow: hidden;
      }
      #cas {
        opacity: 1;
        -webkit-transition: opacity 0.5s;
        -ms-transition: opacity 0.5s;
        -moz-transition: opacity 0.5s;
      }

      .noOp {
        opacity: 0 !important;
      }
    </style>
  </head>
  <body>
    <div class="view">
      <div class="box" id="bb">
        <canvas id="cas"></canvas>
      </div>
    </div>

    <script charset="utf-8">
      var canvas = document.getElementById("cas"),
        ctx = canvas.getContext("2d");
      var x1,
        y1,
        a = 30,
        timeout,
        totimes = 100,
        distance = 30;
      var saveDot = [];

      var canvasBox = document.getElementById("bb");

      canvas.width = canvasBox.clientWidth;
      canvas.height = canvasBox.clientHeight;

      var img = new Image();
      img.src = "./image/2.jpg";
      img.onload = function () {
        var w = (canvas.height * img.width) / img.height;
        ctx.drawImage(img, (canvas.width - w) / 2, 0, w, canvas.height);
        tapClip();
      };

      function getClipArea(e, hastouch) {
        var x = hastouch ? e.targetTouches[0].pageX : e.clientX;
        var y = hastouch ? e.targetTouches[0].pageY : e.clientY;
        var ndom = canvas;

        while (ndom.tagName !== "BODY") {
          x -= ndom.offsetLeft;
          y -= ndom.offsetTop;
          ndom = ndom.parentNode;
        }

        return {
          x: x,
          y: y,
        };
      }

      //通过修改globalCompositeOperation来达到擦除的效果
      function tapClip() {
        var hastouch = "ontouchstart" in window ? true : false,
          tapstart = hastouch ? "touchstart" : "mousedown",
          tapmove = hastouch ? "touchmove" : "mousemove",
          tapend = hastouch ? "touchend" : "mouseup";

        var area;
        var x2, y2;

        ctx.lineCap = "round";
        ctx.lineJoin = "round";
        ctx.lineWidth = a * 2;
        ctx.globalCompositeOperation = "destination-out";

        window.addEventListener(tapstart, function (e) {
          clearTimeout(timeout);
          e.preventDefault();

          area = getClipArea(e, hastouch);

          x1 = area.x;
          y1 = area.y;

          drawLine(x1, y1);

          this.addEventListener(tapmove, tapmoveHandler);

          this.addEventListener(tapend, function () {
            this.removeEventListener(tapmove, tapmoveHandler);

            //检测擦除状态
            timeout = setTimeout(function () {
              var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
              var dd = 0;
              for (var x = 0; x < imgData.width; x += distance) {
                for (var y = 0; y < imgData.height; y += distance) {
                  var i = (y * imgData.width + x) * 4;
                  if (imgData.data[i + 3] > 0) {
                    dd++;
                  }
                }
              }
              if (
                dd /
                  ((imgData.width * imgData.height) / (distance * distance)) <
                0.4
              ) {
                canvas.className = "noOp";
              }
            }, totimes);
          });

          function tapmoveHandler(e) {
            clearTimeout(timeout);

            e.preventDefault();

            area = getClipArea(e, hastouch);

            x2 = area.x;
            y2 = area.y;

            drawLine(x1, y1, x2, y2);

            x1 = x2;
            y1 = y2;
          }
        });
      }

      function drawLine(x1, y1, x2, y2) {
        //		ctx.save();
        //		if(arguments.length==2){
        //			saveDot = [[x1, y1]];
        //			ctx.beginPath();
        //			ctx.arc(x1, y1, a, 0, 2 * Math.PI);
        //			ctx.fill();
        //		}else {
        //			saveDot.push([x2,y2]);
        //			if(saveDot.length >= 3){
        //				ctx.beginPath();
        //				ctx.moveTo(saveDot[0][0], saveDot[0][1]);
        //				ctx.quadraticCurveTo(saveDot[1][0], saveDot[1][1], saveDot[2][0], saveDot[2][1]);
        //				ctx.stroke();
        //				saveDot = [saveDot.pop()];
        //			}
        //		}
        //		ctx.restore();

        ctx.save();
        ctx.beginPath();
        if (arguments.length == 2) {
          ctx.arc(x1, y1, a, 0, 2 * Math.PI);
          ctx.fill();
        } else {
          ctx.moveTo(x1, y1);
          ctx.lineTo(x2, y2);
          ctx.stroke();
        }
        ctx.restore();
      }

      //使用clip来达到擦除效果
      function otherClip() {
        var hastouch = "ontouchstart" in window ? true : false,
          tapstart = hastouch ? "touchstart" : "mousedown",
          tapmove = hastouch ? "touchmove" : "mousemove",
          tapend = hastouch ? "touchend" : "mouseup";

        var area;

        canvas.addEventListener(tapstart, function (e) {
          clearTimeout(timeout);
          e.preventDefault();

          area = getClipArea(e, hastouch);

          x1 = area.x;
          y1 = area.y;

          ctx.save();
          ctx.beginPath();
          ctx.arc(x1, y1, a, 0, 2 * Math.PI);
          ctx.clip();
          ctx.clearRect(0, 0, canvas.width, canvas.height);
          ctx.restore();

          canvas.addEventListener(tapmove, tapmoveHandler);
          canvas.addEventListener(tapend, function () {
            canvas.removeEventListener(tapmove, tapmoveHandler);

            timeout = setTimeout(function () {
              var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
              var dd = 0;
              for (var x = 0; x < imgData.width; x += distance) {
                for (var y = 0; y < imgData.height; y += distance) {
                  var i = (y * imgData.width + x) * 4;
                  if (imgData.data[i + 3] > 0) {
                    dd++;
                  }
                }
              }
              if (
                dd /
                  ((imgData.width * imgData.height) / (distance * distance)) <
                0.4
              ) {
                canvas.className = "noOp";
              }
            }, totimes);
          });

          function tapmoveHandler(e) {
            e.preventDefault();
            area = getClipArea(e, hastouch);
            x2 = area.x;
            y2 = area.y;

            var asin = a * Math.sin(Math.atan((y2 - y1) / (x2 - x1)));
            var acos = a * Math.cos(Math.atan((y2 - y1) / (x2 - x1)));
            var x3 = x1 + asin;
            var y3 = y1 - acos;
            var x4 = x1 - asin;
            var y4 = y1 + acos;
            var x5 = x2 + asin;
            var y5 = y2 - acos;
            var x6 = x2 - asin;
            var y6 = y2 + acos;

            ctx.save();
            ctx.beginPath();
            ctx.arc(x2, y2, a, 0, 2 * Math.PI);
            ctx.clip();
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.restore();

            ctx.save();
            ctx.beginPath();
            ctx.moveTo(x3, y3);
            ctx.lineTo(x5, y5);
            ctx.lineTo(x6, y6);
            ctx.lineTo(x4, y4);
            ctx.closePath();
            ctx.clip();
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.restore();

            x1 = x2;
            y1 = y2;
          }
        });
      }
    </script>
  </body>
</html>

转自:https://www.cnblogs.com/axes/p/3850309.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值