使用 use-react-screenshot 创建的图像呈现不正确

Created image with use-react-screenshot is incorrectly rendered

我正在使用 use-react-screenshot 截取特定 dom 元素的屏幕截图,但图像变得很奇怪,看起来它部分渲染了 dom 元素

我正在使用 create-react-app

中的示例代码

import logo from "./logo.svg";
import "./App.css";
import { createRef } from "react";
import { useScreenshot, createFileName } from "use-react-screenshot";

function App() {
    const ref = createRef(null);
    const [image, takeScreenShot] = useScreenshot({
        type: "image/jpeg",
        quality: 1.0,
    });

    const download = (image, { name = "img", extension = "jpg" } = {}) => {
        const a = document.createElement("a");
        a.href = image;
        a.download = createFileName(extension, name);
        a.click();
    };

    const downloadScreenshot = () => takeScreenShot(ref.current).then(download);

    return (
        <div className="App">
            <header className="App-header">
                <button onClick={downloadScreenshot}>
                    Download screenshot
                </button>
                <img src={logo} className="App-logo" alt="logo" ref={ref} />
            </header>
        </div>
    );
}

export default App;

一个 sandbox 玩转它

我不确定它是否与作为 peerDependency 的 html2canvas 有关。无论我把 ref 放在哪里,都会发生同样的错误

关于github there were a lot of issues related with SVG not downloading properly with html2canvas. I suspect these to be the issues. Solutions / workaround 用户提供的包括对内部代码的代码修改。这又很难再继续下去了。下载时 Firefox 也显示空白图像。

我最好的解决方案是使用像 html-to-image 这样的替代库。几分钟之内,一切似乎都与此有关。 (甚至火狐)

import * as htmlToImage from "html-to-image";
...
  const takeScreenShot = async (node) => {
    const dataURI = await htmlToImage.toJpeg(node);
    return dataURI;
  };

  const download = (image, { name = "img", extension = "jpg" } = {}) => {
    const a = document.createElement("a");
    a.href = image;
    a.download = createFileName(extension, name);
    a.click();
  };

  const downloadScreenshot = () => takeScreenShot(ref.current).then(download);
...

Codesandbox

现在这可能不是最好的解决方案,但它是目前最好的替代工作解决方案。

经过一些研究,似乎与 React V17 不兼容,因为它没有像在 React V16 中那样将 html2canvas 安装为 peerDependency。所以,这是一个 bug.

它的解决方法是在终端

中使用html2canvas添加为对等依赖
npm add html2canvas --legacy-peer-deps

完成后,我可以截图了