使用 html2canvas 生成分享图片,CDN图片不展示问题

2,974 阅读1分钟

背景

生成分享图片,包含后端返回的图文,图片是 cdn 资源。 开始尝试使用 html2canvas 时,使用的是本地图片,生成截图无问题。

代码实现

import html2canvas from 'html2canvas';
const shareContent = document.getElementById("capture"); // 要生成截图的内容区域
(window.html2canvas || html2canvas)(shareContent, {
  useCORS: true, // 允许跨域 + 设置 <img crossOrigin="Anonymous" />
  scrollY: 0,
  scrollX: 0,
  height:shareContent.offsetHeight - 2,
}).then((canvas) => {
  console.log("生成整个图片");
  setUrl(canvas.toDataURL("image/png", 1))
})

问题

但是换成 cdn 资源时,在 ios 设备上随机出现 截图为空、图片展示不了的情况。

解决方案

因为使用本地图片,未遇到此问题,所以前端在获取图片 cdn 资源时,

  1. 将资源异步转换为 base64
  2. 将 base64 赋值给 img 标签
  3. 最后执行生成截图的代码 测试后问题解决

代码实现

  1. 需加载多张 cdn 图片,所以使用 Promise 处理多张 cdn 图片转为 base64
// 传入 cdn 地址
function convertUrlToBase64(url) {
    return new Promise((resolve) => {
        let img = new Image();
        img.crossOrigin = 'Anonymous';
        img.src = url;
        img.onload = function () {
            let canvas = document.createElement('canvas');
            canvas.width = img.width;
            canvas.height = img.height;
            let ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0, img.width, img.height);
            let ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase();
            let dataURL = canvas.toDataURL('image/' + ext);
            let base64 = {
                dataURL: dataURL,
                type: 'image/' + ext,
                ext: ext
            };
            resolve(base64)
        }
    })
}
  1. 实现异步加载完多张图片,将base64赋值给 img 标签,最后执行生成截图
const bgImg = document.getElementsByClassName('photo')[0];
const avatarImg = document.getElementsByClassName('avatar')[0]
Promise.all([convertUrlToBase64(bgImg.src), convertUrlToBase64(avatarImg.src)])
    .then(([base641,base642]) => {
        bgImg.src = base641.dataURL;
        avatarImg.src = base642.dataURL;
        (window.html2canvas || html2canvas)(shareContent, {
          useCORS: true,
          scrollY: 0,
          scrollX: 0,
          height:shareContent.offsetHeight - 2,
        }).then((canvas) => {
          console.log("生成整个图片");
          setUrl(canvas.toDataURL("image/png", 1))
          Toast.hide();
        })
})

结语

html2canvas 生成截图,cdn图片不展示问题已完美解决。🎉

在使用过程中遇到,生成截图时,文字整体下移情况,还未解决,在官方看到 issue github.com/niklasvh/ht…