React(2): 使用 html2canvas 生成图片

使用 html2canvas 生成图片

需求

  1. 将所需的内容生成图片
  2. div 中包括 svg

前置准备

js 复制代码
 "react": "^18.2.0",
 "react-dom": "^18.2.0",
 "html2canvas": "^1.4.1",

实现

html 复制代码
<div ref={payRef}></div>
js 复制代码
const payRef = useRef<HTMLDivElement>(null);

function generateImg() {
    if (orderRef.current) {
      html2canvas(orderRef.current, {
        useCORS: true,
        allowTaint: true, //开启跨域
      }).then((canvas) => {
        Toast.show('生成图片成功');
        const link = document.createElement('a');
        link.href = canvas.toDataURL();
        link.setAttribute('download', '订单详情.png');
        link.style.display = 'none';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      });
    }
}

生成的图片

出现的问题

svg 导不出来

百度了下发现都是用 canvg,但是发现不生效,查看了下 结构, 发现我用的是 vite-plugin-svg-icons 这个 vite 插件,你会发现 svg 里面的东西引用都在外面...

结构是这样的

不在同个 div 下面根本拿不到,然后我脑里突然想: 那我把它怼进去不就行了

更改

这里用 any 纯属无奈 ╮(╯▽╰)╭,因为 USEElementSymbolElement 定义就报错...,有大佬可以给我支下招

js 复制代码
export function changeToCanvas(element: HTMLDivElement) {
  const svgElems = element.querySelectorAll('svg');
  let elems: SVGElement[] = [...svgElems];
  elems.forEach((node: SVGElement) => {
    // 拿到 symbol 的 use 属性
    const childNodes: any = node.childNodes[0];
    // 除去 # 这个属性 拿到对应值
    const id = childNodes.href.baseVal.slice(1);
    // 拿到 Symbol 标签
    let symbol: any = document.getElementById(id)?.cloneNode(true);
    // 获取填充颜色
    let fill = window.getComputedStyle(node)['fill'];
    // 填充颜色
    symbol.style.fill = fill;
    // 直接把他塞到 use 中
    childNodes.appendChild(symbol);
  });
}

使用

html 复制代码
<div ref={payRef}></div>
js 复制代码
const payRef = useRef<HTMLDivElement>(null);
  function generateImg() {
    if (orderRef.current) {
      changeToCanvas(orderRef.current);
      html2canvas(orderRef.current, {
        useCORS: true,
        allowTaint: true, //开启跨域
      }).then((canvas) => {
        Toast.show('生成图片成功');
        const link = document.createElement('a');
        link.href = canvas.toDataURL();
        link.setAttribute('download', '订单详情.png');
        link.style.display = 'none';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      });
    }
  }

然后点击生成,打开控制台发现 use 中的内容给我硬塞进去了

然后生成的图片也没有问题

最后

如果大佬们有更好的建议可以私信我一下 ()

更新

暂无

相关推荐
killerbasd21 分钟前
牧苏苏传 我不装了 4/7
前端·javascript·vue.js
吴声子夜歌36 分钟前
ES6——二进制数组详解
前端·ecmascript·es6
码事漫谈1 小时前
手把手带你部署本地模型,让你Token自由(小白专属)
前端·后端
ZC跨境爬虫1 小时前
【爬虫实战对比】Requests vs Scrapy 笔趣阁小说爬虫,从单线程到高效并发的全方位升级
前端·爬虫·scrapy·html
爱上好庆祝1 小时前
svg图片
前端·css·学习·html·css3
王夏奇1 小时前
python中的__all__ 具体用法
java·前端·python
大家的林语冰2 小时前
《前端周刊》尤大开源 Vite+ 全家桶,前端工业革命启动;尤大爆料 Void 云服务新产品,Vite 进军全栈开发;ECMA 源码映射规范......
前端·javascript·vue.js
jiayong232 小时前
第 8 课:开始引入组合式函数
前端·javascript·学习
田八2 小时前
聊聊AI的发展史,AI的爆发并不是偶然
前端·人工智能·程序员
zhanghongbin013 小时前
AI 采集器:Claude Code、OpenAI、LiteLLM 监控
java·前端·人工智能