下载svg,包括它的文本标记值

时间:2018-03-22 11:17:27

标签: svg

我正在研究从网页下载svg的方法。 除了最后一部分,我几乎完成了所有工作:

  

下载svg,包括其中包含的文本标签。

现在,为了给出更好的背景: 我需要使用fontawesome图标作为文本从svg下载图像。 正确下载了svg,没有将文本标签下载(它被下载为损坏的图像" square")

这是我的代码的简化版本:

function triggerDownload(imgURI, name, format) {
    let evt = new MouseEvent('click', {
        view: window,
        bubbles: false,
        cancelable: true
    });

    let a = document.createElement('a');
    a.setAttribute('download', name + '.' + format);
    a.setAttribute('href', imgURI);
    a.setAttribute('target', '_blank');

    a.dispatchEvent(evt);
}

function clickSVG(event) {
    const dd = 300;
    const format = "png"
    let canvas = document.getElementById('canvas'),
        target = event.currentTarget;
    canvas.width = dd;
    canvas.height = dd;
    debugger
    let newImage = target.cloneNode(true),
        circle = newImage.getElementsByClassName('svgCircle-test') ? newImage.getElementsByClassName('svgCircle-test') : null,
        image = newImage.getElementsByClassName('svgImage-test');
    newImage.height.baseVal.value = dd;
    newImage.width.baseVal.value = dd;
    if (circle.length > 0) {
        circle[0].cx.baseVal.value = dd / 2;
        circle[0].cy.baseVal.value = dd / 2;
        circle[0].r.baseVal.value = dd / 2;
    }

    let ctx = canvas.getContext('2d'),
        data = (new XMLSerializer()).serializeToString(newImage),
        DOMURL = window.URL || window.webkitURL || window,
        name = newImage.getAttribute('data-name'),
        img = new Image(),
        svgBlob = new Blob([data], {type: 'image/svg+xml;charset=utf-8'}),
        url = DOMURL.createObjectURL(svgBlob);

    img.onload = function () {
        ctx.drawImage(img, 0, 0);
        DOMURL.revokeObjectURL(url);

        let imgURI = canvas
            .toDataURL(`image/${format}`)
            .replace(`image/${format}`, 'image/octet-stream');

        triggerDownload(imgURI, name, format);
    };

    img.src = url;
}

document.getElementById("svg").addEventListener("click", clickSVG)

html看起来像这样:

<svg id="svg" height="200" width="200" data-name="test">
  <circle cx="100" cy="100" r="100" fill="#faa" class="svgCircle-test" />
  <text x="0" y="120" width="200" height="200" class="svgImage-test">&#xf2c6;</text>  
</svg>

<canvas id="canvas" />

这就是CSS:

svg {
    margin-top:10px;
    cursor: pointer;
    display: inline-block;
    padding: 5px;
}

svg text{
    font-family:'FontAwesome';
    font-size: 100px;
}

#canvas {
    display: none;
}

可以在此处找到帮助您了解问题并帮助我更好帮助的codepen:https://codepen.io/NickHG/pen/QMmJvd

要查看此问题,请点击圈子(这会将svg下载为png图片)。

注意:如果下载没有启动,可能是您的浏览器阻止弹出窗口。只需让它看到下载的图像。

由于

1 个答案:

答案 0 :(得分:1)

这里有几件事情。

一旦你将SVG文件“转换”为HTMLImageElement(<image>),就像你在画布上做的那样,事情发生了变化:

  1. 您应用于<text>的样式不再适用。那是因为它在HTML文件中,而不是SVG“文件”。您需要将样式添加到SVG本身。

  2. 呈现为<image>的SVG需要自包含。它们不能引用外部文件,例如Font Awesome字体。

    要使其自包含,您需要使用数据URL将字体文件嵌入SVG本身。

    您需要向SVG添加<style>元素,并包含指定Base64编码字体文件(或文件)的@font-face规则。

  3. See this question for an example