svg 导出成图片会有很多限制, 外链的图片, 样式均会丢失,推荐使用 saveSvgAsPng.js 进行导出

 

以下是借鉴库写的导出函数:

function reEncode(data) {
    return decodeURIComponent(
        encodeURIComponent(data).replace(/%([0-9A-F]{2})/g, (match, p1) => {
            const c = String.fromCharCode(`0x${p1}`);
            return c === '%' ? '%25' : c;
        })
    )
}


function export2Base64Img(svgDom, MIMEType, option) {
    var serializer = new XMLSerializer();
    var source = serializer.serializeToString(svgDom);
    // 方式一: unescape(encodeURIComponent(txt))
    // var path = "data:image/svg+xml;base64," + window.btoa(unescape(encodeURIComponent(source)));
    // 方式二: decodeURIComponent(encodeURIComponent(txt))
    var path = "data:image/svg+xml;base64," + window.btoa(reEncode(source));
    var canvas = document.createElement("canvas"),
        context = canvas.getContext("2d"),
        img = new Image(),
        pixelRatio = window.devicePixelRatio || 1,
        _exportPath, handler
    option = option || {};

    canvas.width = parseFloat(svgDom.getAttribute('width')); //  * pixelRatio
    canvas.height = parseFloat(svgDom.getAttribute('height')); //  * pixelRatio 
    img.src = path;
    img.onload = function () {
        // 增加底色
        if (option.background) {
            context.beginPath();
            context.rect(0, 0, canvas.width, canvas.height);
            context.fillStyle = option.background;
            context.fill();
            context.closePath();
        }
        //
        context.drawImage(img, 0, 0);

        var marker = option.watermark || "";

        if (marker) {
            context.font = "18px 微软雅黑";
            context.fillStyle = "rgba(12, 0, 70, 0.5)";

            var textWidth = context.measureText(marker).width,
                textHegith = 50,
                pk = 1.2,
                rotate = (option.rotation || -45) * Math.PI / 180,
                sinReg = Math.sin(rotate),
                cosReg = Math.cos(rotate),
                width = Math.abs(canvas.width * cosReg) + Math.abs(canvas.height * sinReg),
                height = Math.abs(canvas.height * cosReg) + Math.abs(canvas.width * sinReg);

                var xf = Math.ceil(width / textWidth * pk);
                var yf = Math.ceil(height / textHegith);

                context.rotate(rotate);

                for (var i = 0; i < yf; i++) {
                    for (var k = 0; k < xf; k++) {
                        context.fillText(marker, textWidth * k * pk - canvas.height * cosReg, textHegith * i)
                    }
                }
            }


        document.body.appendChild(canvas);
        _exportPath = canvas.toDataURL(MIMEType || 'image/png', 1)
        typeof handler === 'function' && handler(_exportPath)
        document.body.removeChild(canvas)
    }

    return new Promise(function (resolve, reject) {
        handler = resolve
    })
}
View Code

相关文章: