使用html2canvas将整个元素导出为图片,其中包含svg和img,解决img跟svg导出时img或svg(canvg处理)不显示的问题,以及相关优化

这篇具有很好参考价值的文章主要介绍了使用html2canvas将整个元素导出为图片,其中包含svg和img,解决img跟svg导出时img或svg(canvg处理)不显示的问题,以及相关优化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言

一、准备

二、解决问题

1.将svg跟img转为canvas的方法

2.将base64转换成file文件的方法

3.点击下载使用方法

1).对dom没有处理,需求只是将图片导出即可

 2).涉及对dom的拖拽,流程图之类的(需复制dom,在复制的dom上进行处理)

 三、效果图如下


前言

查阅很多相关的文章和文档,大多是解决svg导出不显示的问题,这个还是比较好处理的。但是对于我的需求而言,主要问题是,需要导出成图片的dom元素,中间既有img又有svg,导致我在导出时,img的元素并没有显示在导出的图片上

一、准备

我使用的html2canvas版本是1.4.1 ,canvg版本是1.5.3

npm install --save html2canvas@1.4.1
npm install --save canvg@1.5.3

引入组件

import html2canvas from "html2canvas";
import canvg from "canvg";

二、解决问题

1.将svg跟img转为canvas的方法

changeToCanvas(element) {
    const svgElems = element.querySelectorAll('svg');
    const imgElems = element.querySelectorAll('img');
    //es6语法
    let elems = [...svgElems, ...imgElems]
    elems.forEach(node => {
        let parentNode = node.parentNode;
        let canvas = document.createElement("canvas");
        canvas.style.zIndex = 9
        //处理svg转换canvas需要使用canvg组件
        if (node.tagName == 'svg') {
            let svg = node.outerHTML.trim();
            canvg(canvas, svg);
            if (node.style.position) {
                canvas.style.position += node.style.position;
                canvas.style.left += node.style.left;
                canvas.style.top += node.style.top;
            }
        } 
        //处理img转换canvas
        if (node.tagName == 'IMG') {
            canvas.width = node.width;
            canvas.height = node.height;
            canvas.getContext("2d").drawImage(node, 0, 0)
        }
        parentNode.removeChild(node);
        parentNode.appendChild(canvas);
    });
}

2.将base64转换成file文件的方法

base64ToFile(dataurl) {
    let arr = dataurl.split(',');
    let mime = arr[0].match(/:(.*?);/)[1];
    let bstr = atob(arr[1]);
    let n = bstr.length;
    let u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {
        type: mime
    });
},

3.点击下载使用方法

downloadIMG()这个方法中,由于我是svg制作流程图,避免下载后导致无法拖拽svg,所以我这里的做法是先复制一个临时元素,在使用完后再清除掉,如果说你本身不对svg以及img做一些操作的话,可以不需要这几步。

scale属性可以解决解决生成的canvas模糊问题

1).对dom没有处理,需求只是将图片导出即可

downloadIMG() {
    //需要在id为flowWrap的div里面加上 ref="flowWrap"
    const flow = this.$refs.flowWrap
    flow.style.background = '#000'
    //调用changeToCanvas
    this.changeToCanvas(flow)
    html2canvas(flow, {
        taintTest: false,
        scale: window.devicePixelRatio < 2 ? 2 : window.devicePixelRatio, //scala属性解决生成的canvas模糊问题
    }).then((canvas) => {
        //调用base64ToFile
        let blob = this.base64ToFile(canvas.toDataURL('image/png'));
        let a = document.createElement('a');
        a.setAttribute('href', URL.createObjectURL(blob));
        a.setAttribute('download', new Date().getTime() + '.png');
        URL.revokeObjectURL(blob);
        a.click();
        a.remove();
        //element组件,你可以直接使用alert查看
        this.$message.success('生成成功')
    }).catch((error) => {
        //element组件,你可以直接使用alert查看
        this.$message.error('生成失败,请查看控制台错误')
    });
},

 2).涉及对dom的拖拽,流程图之类的(需复制dom,在复制的dom上进行处理)

downloadIMG() {
    //找到元素dom并复制一个临时元素(需要在id为flowWrap的div里面加上 ref="flowWrap")
    //我这里id为flowWrap,你需要替换为你的id
    const flow = this.$refs.flowWrap
    //svg转换canvas会导致svg无法拖动,使用临时元素
    const tmpFlow = flow.cloneNode(1)
    tmpFlow.style.background = '#000'
    flow.appendChild(tmpFlow)
    //调用changeToCanvas
    this.changeToCanvas(tmpFlow)
    html2canvas(tmpFlow, {
        taintTest: false,
        scale: window.devicePixelRatio < 2 ? 2 : window.devicePixelRatio, //scala属性解决生成的canvas模糊问题
    }).then((canvas) => {
        //调用base64ToFile
        let blob = this.base64ToFile(canvas.toDataURL('image/png'));
        let a = document.createElement('a');
        a.setAttribute('href', URL.createObjectURL(blob));
        a.setAttribute('download', new Date().getTime() + '.png');
        URL.revokeObjectURL(blob);
        a.click();
        a.remove();
        flow.removeChild(tmpFlow) // 移除临时tmpFlow
        //element组件,你可以直接使用alert查看
        this.$message.success('生成成功')
    }).catch((error) => {
        flow.removeChild(tmpFlow) // 移除临时tmpFlow
        //element组件,你可以直接使用alert查看
        this.$message.error('生成失败,请查看控制台错误')
    });
},

 三、效果图如下

canvg,scala,vue.js,javascript,html,前端

canvg,scala,vue.js,javascript,html,前端

canvg,scala,vue.js,javascript,html,前端文章来源地址https://www.toymoban.com/news/detail-809236.html

到了这里,关于使用html2canvas将整个元素导出为图片,其中包含svg和img,解决img跟svg导出时img或svg(canvg处理)不显示的问题,以及相关优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue2如何将页面生成 pdf 导出 html2Canvas + jspdf

    npm i html2canvas npm i jspdf import html2canvas from \\\'html2canvas\\\'; import jsPDF from \\\'jspdf\\\' export const htmlToPDF = async (htmlId, title = \\\"报表\\\", bgColor = \\\"#fff\\\") = {   let pdfDom = document.getElementById(htmlId)   pdfDom.style.padding = \\\'0 10px !important\\\'   const A4Width = 595.28;   const A4Height = 841.89;   let canvas = await html2canvas(pd

    2024年02月16日
    浏览(58)
  • Html转PDF,前端JS实现Html页面导出PDF(html2canvas+jspdf)

    一、背景介绍 ​ 当我们在不想改变后端代码的同时想是纯html页面导出PDF,那么(html2canvas+jspdf)就是无疑最好的选择,导出时它不占用我们服务器的资源,而是由用户本地自行执行js文件下载PDF,不占用我们系统的带宽,所以这无非是最好的选择方式。 二、疑问 1、为什么要

    2024年01月23日
    浏览(59)
  • html2canvas使用文档

    Install NPM Install Yarn 以 vue 举例,这样写起来比较方便 如果想要将图片导出,可以这样写 名称 默认值 描述 allowTaint false 是否允许跨源图像污染画布 backgroundColor #ffffff 画布背景色(如果在DOM中未指定),为透明设置null canvas null 用作绘图基础的现有画布元素 foreignObjectRendering

    2024年03月28日
    浏览(57)
  • html2canvas使用指南

      最近项目中需要使用到将网页中的内容下载成图片,通过按钮点击将页面保存下来,方便同事使用进行工作汇报。如图: 然后我想到了 html2canvas ,就可以解决我现在遇到的问题了。我火速从官网下载了js文件,这里附上链接:   http://html2canvas.hertzen.com/  这里   html2canvas

    2024年02月14日
    浏览(59)
  • vue使用html2canvas优化---节点过滤

    当你使用html2canvas对某个节点进行截图时,项目小dom节点少那还没什么性能问题,如果是个大项目,有成百上千个dom节点,那将是非常头疼的事情(产品经理:小张啊,你这个截图功能为什么需要这个长的时间,这让客户怎么用,重新改。小张:********...)。不多bb了,直接开

    2024年02月12日
    浏览(51)
  • 解决使用 html2canvas 截图不全问题

    1、截图不全 之前没用过这个,网上找了代码之后发现有滚动条的情况下会截图不全,仅能展示出当前页面展示出来的内容,类似于这种情况,这是带滚动条的html,第一张和第二张分别为滚动条在顶部以及在底部的展现 下载成pdf之后分别为这样,只有窗口展示的部分,滚动条

    2024年02月11日
    浏览(51)
  • Vue使用html2canvas将DOM节点生成对应的PDF

    要通过Vue使用html2canvas将DOM节点生成对应的PDF,您需要安装html2canvas和jspdf这两个库。html2canvas用于将DOM节点转换为Canvas,而jspdf用于将Canvas转换为PDF。以下是一个简单的示例代码,展示了如何使用html2canvas和jspdf生成PDF文件: 首先,安装html2canvas和jspdf依赖: 然后,在Vue组件中

    2024年02月11日
    浏览(58)
  • html2canvas截图模糊问题

    最近项目中使用的html2canvas插件打印报表时,发现出现报表模糊的问题,而实际上是插件生成的图片中的像素发生了偏移。 后来查阅html2canvas源码中,发现了以下参数: 参数名称 默认值 描述 scale 1 按比例增加分辨率(2=双倍) dpi 96 将分辨率提高到特定的DPI(每英寸点数)

    2024年01月17日
    浏览(59)
  • (vue)Vue项目中使用jsPDF和html2canvas生成PDF

    效果: 1.:安装jsPDF和html2canvas 2.在需要生成PDF文档的组件中引入jsPDF和html2canvas 解决参考: 1.https://www.jianshu.com/p/31d37bef539b 2.https://www.php.cn/faq/556634.html 3.https://blog.csdn.net/m0_54967474/article/details/123820384

    2024年02月10日
    浏览(54)
  • vue3中,使用html2canvas截图包含视频、图片、文字的区域

    需求:将页面中指定区域进行截图,区域中包含了图片、文字、视频。 第一步,先安装 第二步,在页面引入: 第三步,页面使用: 1)html部分: 2)js部分: 刚开始我截出的图只有文字,插图和视频部分是空白的,并没有将页面的插图和视频截进去,最终发现是 跨域 导致的

    2024年02月06日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包