截图

103 篇文章 0 订阅
97 篇文章 0 订阅
<!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>Document</title>
  <style>
    .Container {
      position: relative;
      box-sizing: border-box;
      border: 1px solid red;
      width: 0;
      height: 0;
      display: none;
      overflow: hidden;
    }

    .Masks {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 99;
      background: rgba(0, 0, 0, .5);
    }

    .Intercept {
      cursor: move;
      position: absolute;
      top: 0;
      left: 0;
      z-index: 999;
    }

    /* 上下左右 */
    .nodetop {
      position: absolute;
      top: -4px;
      left: 50%;
      transform: translateX(-50%);

      width: 30px;
      height: 8px;
      background: #fff;
      border-radius: 4px;
      cursor: n-resize;
    }

    .nodebottom {
      position: absolute;
      bottom: -4px;
      left: 50%;
      transform: translateX(-50%);

      width: 30px;
      height: 8px;
      background: #fff;
      border-radius: 4px;

      cursor: s-resize;
    }

    .nodeleft {
      position: absolute;
      top: 50%;
      left: -4px;
      transform: translateY(-50%);

      width: 8px;
      height: 30px;
      background: #fff;
      border-radius: 4px;

      cursor: w-resize;
    }

    .noderight {
      position: absolute;
      top: 50%;
      right: -4px;
      transform: translateY(-50%);

      width: 8px;
      height: 30px;
      background: #fff;
      border-radius: 4px;

      cursor: e-resize;
    }
  </style>
</head>

<body>
  <input id="npt" type="file" accept="image/png,image/jpeg">
  <img id="img" src="" alt="">
  <script>
    function Trim(obj, callback) {
      this.canvas = document.createElement("canvas");// 创建canvas对象
      this.ctx = this.canvas.getContext('2d');  // canvas方法
      this.imgurl = ''; // base64地址
      this.width = 0; // 图片宽
      this.height = 0; // 图片高

      this.dv = document.createElement('div'); // 最外层div
      this.Masks = document.createElement('div'); // 蒙层
      this.Intercept = document.createElement('div'); // 截取框

      this.nodetop = document.createElement('div'); // 上
      this.nodebottom = document.createElement('div'); // 下
      this.nodeleft = document.createElement('div'); // 左
      this.noderight = document.createElement('div'); // 右

      this.dragging = false;  // 判断是否是节点在移动
      this.position = []; //移动点位

      //x y为要裁剪的左上角的坐标,xx yy为右下角的坐标
      this.clone = [
        { x: 0, y: 0 },
        { xx: 0, yy: 0 }
      ]

      // 重新渲染的canvas
      this.nCanvas = document.createElement('canvas');
      this.nCtx = this.nCanvas.getContext('2d');

      this.callback = callback; //回调函数

      this._base64Url(obj.id);
    }

    // 解析上传的图片
    Trim.prototype._base64Url = function (id) {
      // 获取图片base64数据
      var npt = document.querySelector(id);
      npt.onchange = () => {
        var reader = new FileReader();
        reader.readAsDataURL(npt.files[0]);
        reader.onloadend = (e) => {
          this.imgurl = e.target.result;
          // 渲染图片
          this._creatImg()
        };
      };
    }

    // 渲染图片到canvas上
    Trim.prototype._creatImg = function () {
      var image = new Image();
      image.src = this.imgurl;
      image.addEventListener('load', () => {
        // 获取原图宽高
        this.width = image.width < 500 ? image.width : (image.width / 2);
        this.height = image.width < 500 ? image.height : (image.height / 2);

        //设置canvas大小与原图宽高一致
        this.canvas.height = this.height;
        this.canvas.width = this.width;

        // 在canvas绘制图片
        this.ctx.drawImage(image, 0, 0, this.width, this.height);

        // 设置dv
        this._creatDv();
      })
    }

    // 创建div
    Trim.prototype._creatDv = function () {
      // 把canvas追加到dv上
      this.dv.appendChild(this.canvas);

      // 创建最外层div
      document.body.appendChild(this.dv);
      this.dv.className = 'Container';

      // 设置dv样式
      this.dv.style.display = 'block';
      this.dv.style.width = `${this.width}px`;
      this.dv.style.height = `${this.height}px`;

      // 创建蒙层
      this.Masks.className = 'Masks';
      this.dv.appendChild(this.Masks);

      // 创建截取区域
      this.dv.appendChild(this.Intercept);
      this.Intercept.className = 'Intercept';
      this.Intercept.style.width = `${this.width / 2}px`;
      this.Intercept.style.height = `${this.height / 2}px`;
      this.Intercept.style.top = `${this.height / 4}px`;
      this.Intercept.style.left = `${this.width / 4}px`;

      // 设置截图信息
      this.clone = [
        { x: this.Intercept.offsetLeft, y: this.Intercept.offsetTop },
        { xx: this.Intercept.offsetLeft + this.width / 2, yy: this.Intercept.offsetTop + this.height / 2 }
      ]
      // 调用截图
      this._Screenshots();

      // 按下鼠标
      this.Intercept.addEventListener('mousedown', (e) => {
        this.dragging = true
        this.position = [e.clientX, e.clientY]
      })

      // 移动鼠标
      this.Intercept.addEventListener('mousemove', (e) => {
        //判断是否点击div
        if (this.dragging === false) {
          return;
        }

        // 获取鼠标移动坐标
        const x = e.clientX;
        const y = e.clientY;

        // 鼠标移动坐标减去点击坐标
        const deltax = x - this.position[0]
        const deltay = y - this.position[1]

        // 把字符串转为数字
        const left = parseInt(this.Intercept.offsetLeft)
        const top = parseInt(this.Intercept.offsetTop)

        // 设置div偏移量
        if ((left + deltax + this.Intercept.offsetWidth) <= this.width && (left + deltax) >= 0) {
          this.Intercept.style.left = left + deltax + 'px'
        }
        if ((top + deltay + this.Intercept.offsetHeight) <= this.height && (top + deltay) >= 0) {
          this.Intercept.style.top = top + deltay + 'px'
        }

        this.clone = [
          { x: this.Intercept.offsetLeft, y: this.Intercept.offsetTop },
          { xx: this.Intercept.offsetLeft + this.width / 2, yy: this.Intercept.offsetTop + this.height / 2 }
        ]

        // 鼠标移动坐标覆盖点击坐标
        this.position = [x, y]

        this._Screenshots();
        // 阻止事件冒泡
        e.stopPropagation();
      })

      // 松开鼠标
      this.Intercept.addEventListener('mouseup', () => {
        // 取消移动
        this.dragging = false
      })

      // 移入documen取消移动
      document.addEventListener('mousemove', () => {
        this.dragging = false;
        this.position = [0, 0]
      })
    }

    Trim.prototype._Screenshots = function () {
      // 截图宽度
      var w = this.clone[1].xx - this.clone[0].x;
      // 截图高度
      var h = this.clone[1].yy - this.clone[0].y;

      // 获取截图区域内容,截图区域的像素点矩阵
      var cutImage = this.ctx.getImageData(this.clone[0].x, this.clone[0].y, w + 1, h + 1);

      // 设置重新渲染canvas的参数
      this.nCanvas.width = w;
      this.nCanvas.height = h;
      this.nCtx.putImageData(cutImage, 0, 0);// 将画布上指定矩形的像素数据,通过 putImageData() 方法将图像数据放回画布

      // 把canvas节点添加到可移动div里面去
      this.Intercept.appendChild(this.nCanvas)

      // 回调函数把值传出去
      let imgurl = this.nCanvas.toDataURL('image/png')
      this.callback(imgurl);
    }

    let a = new Trim({
      id: '#npt'
    }, function (data) {
      console.log(data)
    })
  </script>
</body>

</html>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值