JS原生使用Canvas截取图片并下载

HTML部分 

<body> 
  <div
      class="wrap"
      onmousedown="handleMouseDown(event)"
      onmousemove="handleMouseMove(event)"
      onmouseup="handleMouseUp(event)"
    >
      <img id="image" src="" alt="" />
      <canvas
        style="left: 30px;top: 40px;"
        width="300"
        height="200"
        id="canvas"
      ></canvas>
    </div>
    <input type="file" onchange="handleInput(event)" />
    <button onclick="handleCut()">截取</button>
    <button onclick="handleDownload()">下载</button>
</body> 

CSS部分

   .wrap {
      width: 600px;
      height: 400px;
      position: relative;
      border: 1px solid #333;
      box-sizing: border-box;
    }
    #image {
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      left: 0;
    }
    #canvas {
      position: absolute;
      border: 1px solid rgb(136, 219, 119);
      background: rgba(156, 156, 156, 0.3);
      display: none;
      z-index: 100;
      box-sizing: border-box;
    }
    button {
      width: 80px;
      height: 30px;
    }

JS部分

    let imageFile = null;
    let isMouseDown = false;
    let wrap = document.getElementsByClassName("wrap")[0];
    let ctx = document.getElementById("canvas");
    let img = document.getElementById("image");
    let content = ctx.getContext("2d");
    let wrapWidth = wrap.offsetWidth;
    let wrapHeight = wrap.offsetHeight;
    let ctxWidth, ctxHeight;
    function handleInput(e) {
      imageFile = e.target.files[0];
      let fileReader = new FileReader();
      fileReader.onload = function(e) {
        img.src = e.target.result;
        canvas.style.display = "block";
        ctxWidth = ctx.offsetWidth;
        ctxHeight = ctx.offsetHeight;
      };   
      // 将文件转化为base64编码
      fileReader.readAsDataURL(imageFile);
    }

    function handleMouseDown(event) {
      if (!img.getAttribute("src")) return;
      // 一旦移动位置,就清空画布
      ctx.height = ctx.height;
      isMouseDown = true;
      updateSite(event.pageX, event.pageY);
    }
    function handleMouseMove(event) {
      if (!isMouseDown) return;
      updateSite(event.pageX, event.pageY);
    }
    function handleMouseUp(event) {
      isMouseDown = false;
    }
    // 移动canvas位置
    function updateSite(X, Y) {
      let currentTop, currentLeft;
      if (Y + ctxHeight / 2 >= wrapHeight) {
        currentTop = wrapHeight - ctxHeight;
      } else if (Y - ctxHeight / 2 <= 0) {
        currentTop = 0;
      } else {
        currentTop = Y - ctxHeight / 2;
        console.log("currentTop", currentTop, Y - ctxHeight / 2, ctxHeight);
      }
      if (X + ctxWidth / 2 >= wrapWidth) {
        currentLeft = wrapWidth - ctxWidth;
      } else if (X - ctxWidth / 2 <= 0) {
        currentLeft = 0;
      } else {
        currentLeft = X - ctxWidth / 2;
        console.log("currentLeft", currentLeft, X - ctxWidth / 2, ctxWidth);
      }
      ctx.style.top = currentTop + "px";
      ctx.style.left = currentLeft + "px";
    }

    // 截取
    function handleCut(type = "image/png") {
      if (!img.getAttribute("src")) {
        alert("请导入图片");
        return;
      }
      let cutImg = document.createElement("img");
      content.drawImage(
        img,
        -parseInt(ctx.style.left),
        -parseInt(ctx.style.top),
        wrap.scrollWidth,
        wrap.scrollHeight
      );
      cutImg.src = ctx.toDataURL(type);
      document.body.append(cutImg);
    }
    function handleDownload() {
      if (!img.getAttribute("src")) {
        alert("请导入图片");
        return;
      }
      loadFile(DataURLToFile(ctx.toDataURL()));
    }
    function DataURLToFile(dataUrl, filename = "file", type) {
      let arr = dataUrl.split(",");
      let bstr = atob(arr[1]);
      !type && (type = arr[0].replace("data:", "").replace(";base64", ""));

      let n = bstr.length,
        u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new File([u8arr], filename, { type });
    }
    // 下载文件
    function loadFile(content, filename = "file") {
      var aLink = document.createElement("a");
      aLink.download = filename;
      aLink.href = URL.createObjectURL(content);
      aLink.click();
      URL.revokeObjectURL(content);
    }

效果如下,截取框内的图片,并可通过下载按钮下载

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值