【问题标题】:Capture screenshot with Vue.js使用 Vue.js 截取屏幕截图
【发布时间】:2020-12-08 12:32:37
【问题描述】:

我按照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

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

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

    here 所述,如果您为图像指定 100% 的大小,那么它将占用其容器的 100%。相反,您想要的是将屏幕截图保持在其原始大小,因此不要为您的图像 CSS 指定任何大小就足够了。

    我用 this one 稍微修改了您的 CodePen,屏幕截图看起来与您预期的一样。

    【讨论】:

    • 感谢您的努力。我试过了,但截图似乎不准确。我截取的屏幕截图和结果似乎不同。
    【解决方案2】:

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

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

    并重构您的代码:

    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;
      });
    }
    

    我希望它现在能如你所愿, 当然,代码需要改进 see sandbox

    【讨论】:

    • 感谢您的回复@Daniil Loban。不能 100% 工作。虽然比旧代码工作得更好。尝试捕获文本(您可以在屏幕截图中显示我吗?-> 高度为 20 像素)。对,代码库需要重构。我想在找到合适的解决方案后这样做。
    • 您需要在滚动页面和检测滚动条出现时使用偏移量来计算顶部和左侧的位置以进行捕获
    猜你喜欢
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    相关资源
    最近更新 更多