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

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

最后

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

更新

暂无

相关推荐
whatever who cares8 分钟前
Java Web 架构全组件详解
java·前端·架构
DevDengChao20 分钟前
[Aliyun] [FC] 如何使用 website-fc-serve 插件部署静态网站
前端·后端
前端拿破轮23 分钟前
利用Github Page + Hexo 搭建专属的个人网站(一)
前端·人工智能·后端
q1cheng35 分钟前
基于Spring Boot + Vue项目online_learn的用户登录认证全流程分析
前端
大时光36 分钟前
gsap 配置解读 --2
前端
万岳科技程序员小金1 小时前
AI数字人小程序源码开发全流程实战:前端交互+后端算法部署指南
前端·人工智能·软件开发·ai数字人小程序·ai数字人系统源码·ai数字人软件开发·ai数字人平台搭建
白开水丶1 小时前
vue3源码学习(五)ref 、toRef、toRefs、proxyRefs 源码学习
前端·vue.js·学习
广州华水科技1 小时前
单北斗GNSS在变形监测中的应用与优势分析
前端
用泥种荷花1 小时前
【LangChain.js学习】大模型分类
前端
掘金安东尼1 小时前
Angular 中的增量水合:构建“秒开且可交互”的 SSR 应用
前端·angular.js