【问题标题】:html5 canvas cropping is incorrect, when margin is addedhtml5画布裁剪不正确,添加边距时
【发布时间】:2016-03-18 05:25:45
【问题描述】:

你好我想用canvas裁剪一张图片,但是当图片不在页面顶部,但是页面之前有一个margin或者其他元素时,结果会不正确,并且有错误的偏移量利润。我认为减去偏移量是一种不好的做法。我必须以特殊方式包装内容还是我的位置属性错误?

相关函数是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

非常感谢

【问题讨论】:

    标签: javascript css html canvas html5-canvas


    【解决方案1】:

    关注mouseup。您尝试为fixed 元素获取正确的topleft 值,但其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'));
    

    【讨论】:

    • 哇非常感谢您的解释。它完美无缺。还有一个问题,你为什么使用 documentElement 作为替代的后备?不总是有身体吗?谢谢
    • 在一些旧浏览器中,根元素(html)正在滚动而不是正文。
    • @DmitriyLoskutov,不是相反吗?在一些旧浏览器中,body 滚动而不是 root element(html) 。顺便说一句,你知道这些浏览器有多旧吗?是否已经支持画布标签?
    • 是的,这就是我所说的,怪癖模式下没有画布,document.body.scrollTop 是已弃用的画布。您做错了,但感谢您的链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 1970-01-01
    相关资源
    最近更新 更多