最近在开发中遇到了一个功能把弹框中的表格转为一张图片进行预览,而html2canvas 库可以帮我们实现这一需求,它能将 HTML 元素渲染为 Canvas,进而生成图片。下面就来详细介绍如何在 Vue3 + TS 项目中使用 html2canvas 实现页面截图并下载功能。

准备工作

首先,需要安装 html2canvas 库。打开终端,在项目根目录下执行以下命令:

npm install html2canvas

功能实现代码解析

以下是实现页面截图并下载功能的核心代码:

const openCard = () => {
  JBLoding.value = true;
  const scale: any = sessionStorage.getItem('scaleNum') || 1;
  const element = cardTableRef.value;
  element.style.letterSpacing = '0.5px';
  html2canvas(cardTableRef.value, {
    backgroundColor: 'white',
    scale: 2
  }).then(function (canvas) {
    const margin = 20;
    const newCanvas = document.createElement('canvas');
    newCanvas.width = canvas.width + 2 * margin;
    newCanvas.height = canvas.height + 2 * margin;
    const ctx = newCanvas.getContext('2d');
    if (ctx) {
      ctx.font = 14 * scale + 'px';
      ctx.fillStyle = 'white';
      ctx.fillRect(0, 0, newCanvas.width, newCanvas.height);
      ctx.drawImage(canvas, margin, margin);
    }
    commonJs.downloadImage(newCanvas, '卡片.png');
    element.style.letterSpacing = 'unset';
    JBLoding.value = false;
  });
};

在这里插入图片描述

分解代码

const scale: any = sessionStorage.getItem('scaleNum') || 1;

首先是页面,如果你的页面上有整体页面的缩放,那么在你进行设置缩放的时候建议设置一个变量或者存入sessionStorage中,有什么用呢?用作于字体大小,在页面的缩放等比下 ,用你系统全局的字体号去乘以缩放比例就可以获取到实时的字体大小。

    const margin = 20;
    const newCanvas = document.createElement('canvas');
    newCanvas.width = canvas.width + 2 * margin;
    newCanvas.height = canvas.height + 2 * margin;

如果下载的图片需要边距的话就需要给这个画布多加的宽度* 2,也就是说留边距20px那么就是宽度需要20 * 2高度同样的,宽高+40。不需要加边距则忽略。

目标元素样式调整

const element = cardTableRef.value;

element.style.letterSpacing = '0.5px';

为何需要设置字间距?原因是下载的图片字间距大小不一,单词或者词语之间字间距的间距过大,所以通过 cardTableRef 获取到要进行截图的目标元素 element,并调整其字母间距为 0.5px,使截图内容的文字间距统一。在截图操作完成后,又将字母间距设置为 unset,恢复元素原来的样式。当然在设置样式的时候页面也会随着进行变化,此时我们可以加一个加载的动画

JBLoding.value = true; //下载显示
JBLoding.value = false; //下载完成隐藏

在现在完成后我们把加载动画关闭掉就可以了 。这样就避免了页面跳动和图片下载等待尴尬期。

(注:仅限于参考学习,如有更好的方法欢迎讨论)

更多推荐