主要介绍了 html2canvas 的基本使用及下载处理,也介绍了项目中使用的一些问题和解决方法,如初始化截图时机、跨域问题、滚动条问题、图片不清晰问题、多行文字错位等。

1. 基础介绍

Github 地址:github.com/niklasvh/ht…

html2canvas 是一个 JavaScript HTML 渲染器,允许在用户浏览器中直接对网页或部分网页进行“截图”。这些截图基于 DOM,因此可能与实际显示效果不完全一致,因为它并不是进行实际的截图,而是根据页面上的信息构建截图。

html2canvas 的主要用途是把网页渲染成图片,然后保存到本地。

 1
 2import html2canvas from "html2canvas";
 3
 4const generateImg = async () => {
 5    const canvas = await html2canvas(
 6      
 7      document.querySelector(".mlp_down") as HTMLElement,
 8      {
 9        useCORS: true, 
10        allowTaint: true, 
11        scrollY: 0, 
12        scrollX: 0,
13      }
14    );
15    
16    const base64Img = canvas.toDataURL("image/jpeg", 1.0);
17    return base64Img;
18  };

2. 初始化截图

在 html2canvas 执行之前确保所有动态内容已经更新完毕,一般使用 setTimeout 或者 requestAnimationFrame 等方法确保内容更新完成。

 1useEffect(() => {
 2  if (isWx) {
 3    setTimeout(() => {
 4      
 5      generateImg();
 6    }, 100); 
 7  }
 8}, []);

3. 图片保存

上述生成图片后,需要保存到本地。

  • 手机浏览器中,可以直接下载
  • 微信浏览器中,不能直接下载,需要长按保存
    • 处理方式:将生成的图片,放在最上层,并设置透明度为 0(opacity:0)
 1const handleDownload = async () => {
 2  const base64Img = await generateImg();
 3  
 4  const isWx =
 5    window.navigator.userAgent.toLowerCase().indexOf("micromessenger") > -1;
 6
 7  if (isWx) {
 8    message.info("请长按图片保存");
 9    
10    return;
11  }
12
13  
14  const link = document.createElement("a");
15  link.href = base64Img;
16  link.download = "藏头诗";
17  link.style.display = "none";
18  document.body.appendChild(link);
19  link.click();
20  document.body.removeChild(link);
21};

4. 图片不清晰问题

在手机端使用时,保存下来的图片很模糊,需要配置scale参数,消除截图锯齿。

  • window.devicePixelRatio:用于获取设备的像素比率(device pixel ratio),即物理像素与 CSS 像素的比例。这个属性通常用于适应高分辨率屏幕(例如 Retina 屏幕),以确保在不同设备上都能获得清晰的图像和文本。

    • 提高图片质量:在高分辨率屏幕上,使用 window.devicePixelRatio 可以使图像放大,从而提高截图的清晰度。
    • 适应不同设备:不同设备有不同的像素密度,通过 window.devicePixelRatio 可以自动适应不同的设备,确保截图在各种设备上都能清晰可见。
  • 物理像素:屏幕上的实际像素数量。

  • CSS 像素:浏览器用来计算布局的逻辑像素。

  • 设备像素比:物理像素与 CSS 像素的比例。

假设设备的 devicePixelRatio 为 2,物理像素为 1px,CSS 像素为 0.5px。

这意味着在高分辨率设备上,每个 CSS 像素实际上对应两个物理像素,因此图像会更加清晰。

 1const canvas = await html2canvas(
 2  document.querySelector(".mlp_down") as HTMLElement,
 3  {
 4    
 5    
 6    scale: window.devicePixelRatio,
 7  }
 8);

5. 多行文字错位问题

垂直展示诗歌内容时,在 Andriod 手机浏览器中生成的图片,文字内容显示正常;

  • 从右到左的垂直书写模式:writing-mode: vertical-rl;

但是在 IOS 手机上生成的图片,文字内容错位了

解决办法:诗中的每个字单独渲染span

 1<div className="mlp_poem">
 2  {poem.map((line, index) => (
 3    <div key={index} className="line">
 4      {/* 1. 改造前 */}
 5      {/* {line} */}
 6
 7      {/* 2. 改造后:修复多行文字错位问题:每个字单独渲染 */}
 8      {line.split("").map((r: string) => (
 9        <span key={r}>{r}</span>
10      ))}
11    </div>
12  ))}
13</div>
个人笔记记录 2021 ~ 2025