添加边距时,html5画布裁剪不正确

时间:2016-03-17 20:58:35

标签: javascript css html5 canvas html5-canvas

您好我想使用画布裁剪图像,但是当图像不在页面顶部,但在页面上有一个边距或其他元素时,结果将变得不正确并且具有错误的偏移量余量。我认为减去偏移量是一种不好的做法。我是否必须以特殊方式包装内容或我的位置属性是否错误?

相关功能是cropMedia。

function cropMedia(media, {
  stretch = 1,
  left = 0,
  top = 0,
  width,
  height 
} = {}) {
  const croppedCanvas = document.createElement('canvas');

  croppedCanvas.width = width;
  croppedCanvas.height = height;
  const ctx = croppedCanvas.getContext('2d');

  ctx.drawImage(media, left, top, width, height, 0, 0, width * stretch, height * stretch);

  return croppedCanvas;
}

以下是我的codepen以获取更相关的代码:http://codepen.io/anon/pen/YqNaow

非常感谢

1 个答案:

答案 0 :(得分:1)

注意mouseup。您尝试为top元素获取正确的leftfixed值,但其topleft属性的样式由viewport计算得出浏览器(不是document的顶部和左侧)。这是正确的代码。

class CanvasCrop {
  constructor(media) {
    let x1 = 0;
    let y1 = 0;
    let x2 = 0;
    let y2 = 0;
    let dragThreshold = 50;

    let mousedown = false;
    let dragging = false;

    const selectionRect = document.getElementById('selectionRect');

    function reCalc() {
      var x3 = Math.min(x1, x2);
      var x4 = Math.max(x1, x2);
      var y3 = Math.min(y1, y2);
      var y4 = Math.max(y1, y2);
      selectionRect.style.left = x3 + 'px';
      selectionRect.style.top = y3 + 'px';
      selectionRect.style.width = x4 - x3 + 'px';
      selectionRect.style.height = y4 - y3 + 'px';
    }

    function cropMedia(media, {
      stretch = 1,
      left = 0,
      top = 0,
      width,
      height 
    } = {}) {
      const croppedCanvas = document.createElement('canvas');

      croppedCanvas.width = width;
      croppedCanvas.height = height;
      const ctx = croppedCanvas.getContext('2d');

      ctx.drawImage(media, left, top, width, height, 0, 0, width * stretch, height * stretch);

      return croppedCanvas;
    }

    media.onmousedown = function(e) {
      mousedown = true;
      selectionRect.hidden = 0;
      x1 = e.clientX;
      y1 = e.clientY;
    };
    onmousemove = function(e) {
      //todo implement isDragging
      if (mousedown) {
        x2 = e.clientX;
        y2 = e.clientY;
        var deltaX = Math.abs(x2 - x1);
        var deltaY = Math.abs(x2 - x1);
        reCalc();
        if (deltaX > dragThreshold || deltaY > dragThreshold) dragging = true;
      }
    };
    onmouseup = (e) => {
      var pic = document.getElementById('pic');
      var offsetTop = pic.offsetTop;
      var offsetLeft = pic.offsetLeft;
      var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
      var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
      scrollTop -= offsetTop;
      scrollLeft -= offsetLeft;
      selectionRect.hidden = 1;
      mousedown = false;
      if (dragging) {
        dragging = false;

        let croppedCanvas = cropMedia(media, {
          left: parseInt(selectionRect.style.left, 10) + scrollLeft,
          top: parseInt(selectionRect.style.top, 10) + scrollTop,
          width: parseInt(selectionRect.style.width, 10),
          height: parseInt(selectionRect.style.height, 10)
        });
        const preview = document.getElementById('preview');
        preview.innerHTML = '';
        preview.appendChild(croppedCanvas);
      }
    };
  }
}

const cc = new CanvasCrop(document.getElementById('pic'));