You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte构建后Canvas绘制SVG导出图片出现破损问题

问题解决:Svelte Build后SVG转图片出现中心破损伪影

可能原因

  1. Build工具优化后,SVG丢失了xmlns命名空间,导致XMLSerializer生成的SVG在非Safari浏览器中无法正确解析渲染
  2. Blob URL的编码处理在部分浏览器中存在兼容性问题
  3. SVG加载和Canvas绘制的时机未完全同步,导致渲染不完整

解决方案

方案1:手动添加SVG命名空间

Build过程中部分工具会自动移除SVG的xmlns属性,这会导致非Safari浏览器无法正确识别SVG结构。在序列化SVG时手动补充该属性:

const downloadAsJpeg = () => {
    if (!qrSvg) return;
    const canvas = document.createElement('canvas');
    canvas.width = 1000;
    canvas.height = 1000;
    const ctx = canvas.getContext('2d');
    if (ctx) {
        ctx.fillStyle = 'white';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        
        let svgString = new XMLSerializer().serializeToString(qrSvg);
        // 检查并添加xmlns命名空间
        if (!qrSvg.hasAttribute('xmlns')) {
            svgString = svgString.replace('<svg', '<svg xmlns="http://www.w3.org/2000/svg"');
        }
        
        const svgBlob = new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' });
        const svgUrl = URL.createObjectURL(svgBlob);
        const img = new Image();
        img.onload = () => {
            ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
            const logo = new Image();
            logo.onload = () => {
                const logoSize = 250;
                const logoX = (canvas.width - logoSize) / 2;
                const logoY = (canvas.height - logoSize) / 2;
                ctx.drawImage(logo, logoX, logoY, logoSize, logoSize);
                const jpegDataUrl = canvas.toDataURL('image/jpeg', 0.9);
                const link = document.createElement('a');
                link.href = jpegDataUrl;
                link.download = `just-type-${scanToChatPhoneNumber}.jpeg`;
                link.click();
                URL.revokeObjectURL(svgUrl);
            };
            logo.src = logoLight;
        };
        img.src = svgUrl;
    } else {
        console.error('Failed to get 2d context from canvas.');
    }
};

方案2:改用SVG Data URL替代Blob URL

部分浏览器对Blob URL加载SVG的兼容性较差,直接使用base64编码的Data URL可以避免该问题:

const downloadAsJpeg = () => {
    if (!qrSvg) return;
    const canvas = document.createElement('canvas');
    canvas.width = 1000;
    canvas.height = 1000;
    const ctx = canvas.getContext('2d');
    if (ctx) {
        ctx.fillStyle = 'white';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        
        let svgString = new XMLSerializer().serializeToString(qrSvg);
        if (!qrSvg.hasAttribute('xmlns')) {
            svgString = svgString.replace('<svg', '<svg xmlns="http://www.w3.org/2000/svg"');
        }
        // 转为Data URL
        const svgDataUrl = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`;
        
        const img = new Image();
        img.onload = () => {
            ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
            const logo = new Image();
            logo.onload = () => {
                const logoSize = 250;
                const logoX = (canvas.width - logoSize) / 2;
                const logoY = (canvas.height - logoSize) / 2;
                ctx.drawImage(logo, logoX, logoY, logoSize, logoSize);
                const jpegDataUrl = canvas.toDataURL('image/jpeg', 0.9);
                const link = document.createElement('a');
                link.href = jpegDataUrl;
                link.download = `just-type-${scanToChatPhoneNumber}.jpeg`;
                link.click();
            };
            logo.src = logoLight;
        };
        img.src = svgDataUrl;
    } else {
        console.error('Failed to get 2d context from canvas.');
    }
};

方案3:调整Build工具的SVG优化配置

如果使用Vite/Rollup等构建工具,检查SVG插件的优化设置,禁止移除xmlns属性或过度压缩SVG:

以Vite为例,修改vite.config.js:

import { sveltekit } from '@sveltejs/kit/vite';
import svg from '@poppanator/sveltekit-svg';

export default {
    plugins: [
        sveltekit(),
        svg({
            // 保留xmlns属性
            preserveAttributes: ['xmlns'],
            // 禁用不必要的压缩优化
            optimize: false
        })
    ]
};

内容的提问来源于stack exchange,提问作者Zulfiqar Laili

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 19:50:21