使用Vue.js截取屏幕截图

9

我按照https://www.digitalocean.com/community/tutorials/vuejs-screenshot-ui的步骤使用Vue.js来截取屏幕截图,虽然成功截图了,但是屏幕截图尺寸似乎不正确。

问题:

  • 输出应该是从光标选中的屏幕截图,但输出和光标选定的框不同。

问题所在: -我认为问题出在takeScreenshot方法上。

takeScreenshot: function () {
  html2canvas(document.querySelector('body')).then(canvas => {
    let croppedCanvas = document.createElement('canvas'),
        croppedCanvasContext = croppedCanvas.getContext('2d');

    croppedCanvas.width  = this.boxEndWidth;
    croppedCanvas.height = this.boxEndHeight;

    croppedCanvasContext.drawImage(canvas, this.boxLeft, this.boxTop, 
    this.boxEndWidth, this.boxEndHeight, 0, 0, this.boxEndWidth, 
    this.boxEndHeight);

    this.imageUrl = croppedCanvas.toDataURL();
  
    const screenshotImg = document.getElementById('screenshotImg');
  
    screenshotImg.src= this.imageUrl;
    console.log('imageUrl', this.imageUrl)
  });
}

我想知道是否有解决方法或者更好的方式来截屏。谢谢。

Codepen链接:https://codepen.io/dineshmadanlal/pen/MWjeXBQ

2个回答

1

看了您的原始 CodePen,我注意到您正在定义一个 CSS 类 .screenshot-img,其中 heightwidth 都设置为 100%。

此处 所述,如果您为图像指定了 100% 的大小,则它将占据其容器的 100%。相反,您想要的是保持截图的原始大小,因此不需要为图像指定任何大小,只需使用 CSS 即可。

我稍微修改了您的 CodePen,这里是链接,在这个版本中,截图似乎按照您的期望工作。


1
谢谢你的努力。我尝试了,但是截图似乎不准确。我拍的截图和结果看起来不同。 - Dinesh Madanlal

0

我更改了样式以适应屏幕截图的大小:

.screenshot-img {
  width: 100%;
  max-height: 100%;
  object-fit: contain;
}

enter image description here

并重构了你的代码:

getSelectRect: function() {
  const [left, top] = [Math.min(this.startX, this.endX), Math.min(this.startY, this.endY)]
  const [right, bottom] = [Math.max(this.startX, this.endX), Math.max(this.startY, this.endY)]
  const [width, height] = [right - left, bottom - top];
  return {left, top, right, bottom, width, height};
},
drawShadow: function() {
  const verticalScrollBarWidth = 16;
  const rc = this.getSelectRect() 
  this.boxTop = rc.top;
  this.boxLeft = rc.left;
  this.boxEndWidth = rc.width
  this.boxEndHeight = rc.height
  this.borderWidth = rc.top + "px " + 
    (this.windowWidth - rc.right - verticalScrollBarWidth) + "px " + 
    (this.windowHeight - rc.bottom) + "px " +
    rc.left + "px";
},
placeTooltip: function({startX , startY,  endX, endY}) {
  if (endX >= startX && endY >= startY) {
    this.toolTipLeft = (endX + this.toolTipWidth >= this.windowWidth) 
      ? this.windowWidth - this.toolTipWidth - (TOOLTIP_MARGIN * 2)
      : endX;
    this.toolTipTop = (endY + this.toolTipHeight + (TOOLTIP_MARGIN * 2) >= this.windowHeight)
      ? this.windowHeight - this.toolTipHeight - (TOOLTIP_MARGIN * 2)
      : endY;
  } else if (endX <= startX && endY >= startY) {
    this.toolTipLeft = (endX - this.toolTipWidth <= 0) 
      ? TOOLTIP_MARGIN
      : endX - this.toolTipWidth;
    this.toolTipTop = (endY + this.toolTipHeight + (TOOLTIP_MARGIN * 2) >= this.windowHeight) 
      ? this.windowHeight - this.toolTipHeight - (TOOLTIP_MARGIN * 2)
      : endY;
  } else if (endX >= startX && endY <= startY) {
    this.toolTipLeft = (endX + this.toolTipWidth >= this.windowWidth) 
      ? this.windowWidth - this.toolTipWidth - (TOOLTIP_MARGIN * 2)
      : endX;
     this.toolTipTop = (endY - this.toolTipHeight <= 0) 
      ? TOOLTIP_MARGIN
      : endY - this.toolTipHeight;
  } else if (endX <= startX && endY <= startY) {
    this.toolTipLeft = (endX - this.toolTipWidth <= 0) 
      ? TOOLTIP_MARGIN
      : endX - this.toolTipWidth;
    this.toolTipTop = (endY - this.toolTipHeight <= 0) 
      ? TOOLTIP_MARGIN
      : endY - this.toolTipHeight;
  }
},  
move: function (e) {
  this.crossHairsTop = e.clientY;
  this.crossHairsLeft = e.clientX;
  var tooltipBoundingRect = tooltip.getBoundingClientRect();
  this.toolTipWidth = tooltipBoundingRect.width;
  this.toolTipHeight = tooltipBoundingRect.height;
  this.isDragging = this.mouseIsDown;
  if (this.isDragging) {
    const endY = this.endY = e.clientY;
    const endX = this.endX = e.clientX;
    const startX = this.startX;
    const startY = this.startY;
    this.placeTooltip({startX , startY,  endX, endY})  
    this.drawShadow()
  }
},
mouseDown: function (e) {
  this.borderWidth = this.windowWidth + "px " + this.windowHeight + "px"; 
  this.startX = e.clientX;
  this.startY = e.clientY;
  this.toolTipWidth = tooltip.getBoundingClientRect().width;
  this.mouseIsDown = true;
  this.tookScreenShot = false;
},
mouseUp: function (e) {
  if (this.isDragging) {
    this.endX = e.clientX;
    this.endY = e.clientY;
    this.isDragging = false;
    this.mouseIsDown = false;
    this.takeScreenshot()
    this.tookScreenShot = true;
  }
},
takeScreenshot: function () {
  const rc = this.getSelectRect()
  html2canvas(document.querySelector('body')).then(canvas => {
    const croppedCanvas = document.createElement('canvas');
    croppedCanvas.width  = rc.width
    croppedCanvas.height = rc.height
    const croppedCanvasContext = croppedCanvas.getContext('2d');
    croppedCanvasContext.drawImage(
      canvas,
      rc.left, rc.top, rc.width, rc.height,
      0, 0, rc.width, rc.height
    );
    this.imageUrl = croppedCanvas.toDataURL();
    const screenshotImg = document.getElementById('screenshotImg');
    screenshotImg.src= this.imageUrl;
  });
}

希望现在它能按照您的愿望工作了, 当然,代码还需要改进 请查看沙盒


感谢您的回复,@Daniil Loban。但是还没有完全解决问题。虽然比旧代码好用了一些。请尝试捕获文本(HI can you show me in the screenshot? -> height to be 20px)。没错,代码库需要重构。我想在有一个正常工作的解决方案之后再进行重构。 - Dinesh Madanlal
当滚动页面并检测滚动条出现以计算顶部和左侧位置以进行捕获时,您需要使用偏移量。 - Daniil Loban

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接