js实现将多个svg转为一个canvas,并将该canvas转为图片

博客围绕将由两个SVG实现的小提琴图和图例图表转为图片并可下载的需求展开。预期获得包含所有内容的图片,实现思路是把多个SVG转为一个canvas元素,输出base64编码赋值给img元素src属性展示图表,还给出了实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求

如下图表,小提琴图和右侧的图例是两个svg实现的,现在需要将这个图表转为图片,并可下载。
在这里插入图片描述

预期结果

获得一张图片,包含上图所有内容。
在这里插入图片描述

实现思路

将多个svg转为一个canvas元素,通过canvas元素输出base64编码,将base64编码赋值给img元素的src属性,即可通过img元素展示完整的图表。

实现代码

// 将一个svg转换为一个canvas
function drawSVGToCanvas(svg: SVGElement) {
    const { width, height } = svg.getBoundingClientRect(); // 方法返回一个对象,该DOMRect对象提供有关元素大小及其相对于视口的位置的信息。
    const serializer = new XMLSerializer();
    const copy = svg.cloneNode(true);
    const data = serializer.serializeToString(copy); // 返回字符串的序列化子树。
    const image = new Image();
    const blob = new Blob([data], {
        type: 'image/svg+xml;charset=utf-8'
    });
    const url = URL.createObjectURL(blob);
    return new Promise(resolve => {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        canvas.width = width;
        canvas.height = height;
        image.addEventListener('load', () => {
            ctx && ctx.drawImage(image, 0, 0, width, height);
            URL.revokeObjectURL(url);
            resolve(canvas);
        }, { once: true });
        image.src = url;
    })
}

// 将多个svg转为base64编码
async function convertSVGsToSingleImage(svgs: SVGElement[], format = 'image/png') {
    const canvas = document.createElement('canvas');
    const ctx: any = canvas.getContext('2d');
    const drawSVGs = Array.from(svgs).map(svg => drawSVGToCanvas(svg))
    const renders = await Promise.all(drawSVGs);
    canvas.width = Math.max(...renders.map((render: any) => render.width));
    canvas.height = Math.max(...renders.map((render: any) => render.height));
    renders.forEach((render: any) => ctx.drawImage(render, 0, 0, render.width, render.height));
    const source = canvas.toDataURL(format).replace(format, 'image/octet-stream');
    return source;
}

// 使用函数实现功能
convertSVGsToSingleImage(svgList).then(source => {
    const image = new Image();
    // image.addEventListener('load', () => {
    //     preview.append(image); // 如果需要将img元素添加到html中,此处preview即为容器元素
    // })
    image.src = source;
    const imgOptions = {
        src: source
    };
    store.commit('addCacheImages', imgOptions); // 此处的做法为将base64编码赋值到系统的其他地方(图片缓存组件)
});
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值