【问题标题】:How to use html2canvas with coordinates?如何使用带坐标的html2canvas?
【发布时间】:2019-05-21 21:19:48
【问题描述】:

我正在尝试使用html2canvas 在浏览器中捕获图像。捕获整个浏览器的图像是可行的。但我需要指定我想要捕获的x,y 开始和结束坐标。 In the docs我看到html2canvas可以接受x,y坐标:

x默认:元素x-offset 说明:裁剪画布x-坐标
y默认:元素y-offset 说明:裁剪画布y-坐标

将我的x,y 坐标传递给这些参数只会捕获整个窗口。

因此,我尝试捕获整个窗口,然后使用 drawImage() 从其中裁剪一个区域(在其他一些 stackoverflow 帖子中找到,不确定是哪个)

function snapImage(x1,y1,x2,y2, e){
    html2canvas(document.body).then(function(canvas) {
        // calc the size -- but no larger than the html2canvas size!
        var width = Math.min(canvas.width,Math.abs(x2-x1));
        var height = Math.min(canvas.height,Math.abs(y2-y1));
        // create a new avatarCanvas with the specified size
        var avatarCanvas = document.createElement('canvas');
        avatarCanvas.width=width;
        avatarCanvas.height=height;
        avatarCanvas.id = 'avatarCanvas';
        // put avatarCanvas into document body
        document.body.appendChild(avatarCanvas);
        // use the clipping version of drawImage to draw
        // a clipped portion of html2canvas's canvas onto avatarCanvas
        var avatarCtx = avatarCanvas.getContext('2d');
        avatarCtx.drawImage(canvas,x1,y1,width,height,0,0,width,height);
    });
}

这会绘制偏移量错误的移位图像。例如,给定以下网站:

图片取自示例:https://github.com/niklasvh/html2canvas/tree/master/examples

我标记“pluot?”区域来捕捉它:

见虚线矩形

虚线矩形是使用 js 绘制的,给定 2 个事件中的鼠标坐标:onmousedownonmouseup。因为矩形绘制正确,我假设我的坐标是正确的。但是当我将这些坐标传递给上面的函数snapImage() 时,我得到了以下捕获的图像:

看起来有一个偏移量。也许drawImage() 操作的起始坐标与我的画布起始坐标不同?


编辑:

事实证明,当我进行 100% 缩放时,我的代码可以正常工作。但当我放大/缩小时却没有。

【问题讨论】:

    标签: javascript html2canvas drawimage


    【解决方案1】:

    我猜这是因为您从带有 clientX 和 clientY 的事件中获得 x 和 y。请改用 pageX 和 pageY。看看这个jsFiddle

    let startX, startY;
    
    document.getElementsByTagName('body')[0].addEventListener('mousedown', function(event) {
        console.log("ok");
        startX = Math.floor(event.pageX);
        startY = Math.floor(event.pageY);
    });
    
    document.getElementsByTagName('body')[0].addEventListener('mouseup', function(event) {
        snapImage(Math.min(event.pageX, startX), Math.min(event.pageY, startY), Math.max(event.pageX, startX), Math.max(event.pageY, startY));
    });
    
    function snapImage(x1,y1,x2,y2, e){
        console.log(x1, x2, y1, y2);
        html2canvas(document.body).then(function(canvas) {
            // calc the size -- but no larger than the html2canvas size!
            var width = Math.min(canvas.width,Math.abs(x2-x1));
            var height = Math.min(canvas.height,Math.abs(y2-y1));
            // create a new avatarCanvas with the specified size
            var avatarCanvas = document.createElement('canvas');
            avatarCanvas.width=width;
            avatarCanvas.height=height;
            avatarCanvas.id = 'avatarCanvas';
            // put avatarCanvas into document body
            document.body.appendChild(avatarCanvas);
            // use the clipping version of drawImage to draw
            // a clipped portion of html2canvas's canvas onto avatarCanvas
            var avatarCtx = avatarCanvas.getContext('2d');
            avatarCtx.drawImage(canvas,x1,y1,width,height,0,0,width,height);
        });
    }
    

    【讨论】:

    • 我有 2 台不同尺寸的显示器处于扩展模式,您的代码只能在较小的显示器上运行。当我将浏览器窗口移动到更大的屏幕时,我遇到了类似的问题
    • 此外,在放大和缩小您的解决方案时,您的解决方案也无法正常工作...实际上我只是想通了,即使没有缩放,我的解决方案也可以工作...
    【解决方案2】:

    原来有一个内置的 chrome 函数captureVisibleTab 可以捕获活动标签的图像。所以我最终使用它而不是html2canvas。我得到了Copyfish Chrome Extension 的帮助。 Github 代码在这里:Copyfish.

    这是我的代码:

    听众:

    //listener in background.js which invokes the screen capture
    chrome.tabs.captureVisibleTab(function (dataURL) {
        sendResponse({
                dataURL: dataURL,
        });
    });
    

    接收者:

    //receiver in content.js which gets the captured image and crops it accordingly
    function(response){
        var img = new Image();
        img.src = response.dataURL;
        var dpf = window.innerWidth / img.width;
        var scaleFactor = 1 / dpf,
        sx = Math.min(x1, x2) * scaleFactor,
        sy = Math.min(y1, y2) * scaleFactor,
        width = Math.abs(x2 - x1),
        height = Math.abs(y2 - y1);
    
        // create a new avatarCanvas with the specified size
        var avatarCanvas = document.createElement('canvas');
        avatarCanvas.width = width;
        avatarCanvas.height = height;
        avatarCanvas.id = 'avatarCanvas';
        // put avatarCanvas into document body
        document.body.appendChild(avatarCanvas);
        // use the clipping version of drawImage to draw
        var avatarCtx = avatarCanvas.getContext('2d');
        avatarCtx.drawImage(img, sx, sy, scaledWidth, scaledHeight, 0, 0, width, height);
    }
    

    x,y 坐标分别由e.clientXe.clientY 获取。

    这种方法是防缩放和分辨率的。

    【讨论】:

    • 您是如何完成这项工作的?你怎么称呼captureVisibleTab这个方法?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 2020-03-06
    • 2012-04-07
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 2017-07-22
    相关资源
    最近更新 更多