【问题标题】:How to capture what is visible through a div?如何捕获通过 div 可见的内容?
【发布时间】:2022-06-10 18:13:30
【问题描述】:

假设我有一个图像和一个 div,其位置是绝对的并且在该图像之上(div 的 z-index 大于图像的 z-index)。像这样:

我想使用 JavaScript 截取通过 div 可见的内容。一开始想把div改成canvas,然后写了这段代码:

<div class="utility-btn">
        <button class="enquiry-btn" onclick="openEnquiry()">?</button>
    </div>
    <div id="enquiry">
        <button id="close" onclick="closeEnquiry()">X</button>
        <div class="cover">
            <canvas id="capture"></canvas>
            <button class="btn" onclick="takeScreenshot()">
                Click to enquiry
            </button>
        </div>
    </div>

截图功能:

function takeScreenshot() {
            var canvas = document.getElementById('capture');
            ctx = canvas.getContext('2d');

            var backCanvas = document.createElement('canvas');
            backCanvas.width = canvas.width;
            backCanvas.height = canvas.height;
            var backCtx = backCanvas.getContext('2d');

            backCtx.drawImage(canvas, 0, 0);

            ctx.drawImage(backCanvas, 0, 0);
            var dataURL = backCanvas.toDataURL();
            console.log(dataURL);
        }

但是dataURL的图片并不是我想象的那样,它只是一张空白图片:

如何实现此功能。如何在不使用任何外部库的情况下做到这一点?

【问题讨论】:

  • 您是否在浏览器的 devtools 检查工具控制台中看到任何错误(例如,img 是否来自外部来源,因此您会收到一些关于“污染”的消息?)[我看不到您在哪里绘制初始图像]。
  • 不,我没有收到任何错误或警告
  • 你能否制作一个可运行的 sn-p,请参阅stackoverflow.com/help/minimal-reproducible-example 特别是,你是如何获取初始图像并将其绘制到画布上的?

标签: javascript html css canvas screenshot


【解决方案1】:

有两个问题:

#1

如果我们查看您负责实际截取屏幕截图的代码

        function takeScreenshot() {
            var canvas = document.getElementById('capture');
            ctx = canvas.getContext('2d');

            var backCanvas = document.createElement('canvas');
            backCanvas.width = canvas.width;
            backCanvas.height = canvas.height;
            var backCtx = backCanvas.getContext('2d');

            backCtx.drawImage(canvas, 0, 0);

            ctx.drawImage(backCanvas, 0, 0);
            var dataURL = backCanvas.toDataURL();
            console.log(dataURL);
        }

我们可以看到canvas 是您想要截取屏幕截图的元素。如果我们继续下去,我们可以看到您正在创建一个空的新画布backCanvas,并将其设置为第一个画布的大小。之后,您在第二个画布上绘制空的第一个画布,最后将第二个空画布绘制回第一个画布。

所以这没有太大意义。

相反,您需要使用threeJS 生成的实际画布。这些代码行将&lt;canvas&gt; 元素附加到容器&lt;div&gt;,threeJS 正在使用:

const container = document.getElementById('container');
container.appendChild(renderer.domElement);

我们可以使用:

document.getElementById("container").children[0]

#2

由于threeJS 使用WebGL 来绘制内容,它的渲染上下文不是常规的,并且出于性能原因,浏览器在绘制某些内容后会清除绘图缓冲区-因此您的屏幕截图将一直为空。您需要将一个选项传递给THREE.WebGLRenderer 构造函数以保留名为preserveDrawingBuffer 的绘图缓冲区。

所以改变这一行:

renderer = new THREE.WebGLRenderer();

到这里

renderer = new THREE.WebGLRenderer({preserveDrawingBuffer: true});

你的截图功能是这样的:

function takeScreenshot() {
    var canvas = document.getElementById('capture');
    ctx = canvas.getContext('2d');

    ctx.drawImage(document.getElementById("container").children[0], 0, 0);
    var dataURL = canvas.toDataURL();
    document.body.appendChild(canvas)
    console.log(dataURL);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-13
    • 2016-08-09
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多