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 中的内容给我硬塞进去了

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

最后

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

更新

暂无

相关推荐
Web极客码20 分钟前
用 Python 搭建工具调用 Agent 的调试过程
java·服务器·前端
2401_8818283235 分钟前
简易文本处理网页工具|AI 通识课第三次作业
前端·javascript·html
障碍的枫子1 小时前
Vue组件导出&渲染
前端·javascript·vue.js
开开心心就好1 小时前
视频播放器完美解码集成三款播放器切换使用
前端·人工智能·智能手机·电脑·音视频·virtualenv·pygame
Sterting1 小时前
组件通信:Props 与 Emit
前端·vue.js
东方老白1 小时前
iOS 面试题
前端
hunterandroid1 小时前
Compose LazyColumn 性能优化:从卡顿到流畅的大列表治理
前端
sakiko_2 小时前
Swift学习笔记39-实战注意事项
前端·笔记·学习·swift
海带紫菜菠萝汤2 小时前
MSE (Media Source Extensions) 实战:流媒体分块加载与自适应码率
前端·javascript·音视频
@小匠2 小时前
Spring Boot Nacos绑定 Map 时中文 key 导致启动失败:一次从复现到源码的排查实录
java·开发语言·前端