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

如何用JavaScript为SVG中的rect标签填充图片?

解决SVG矩形填充图片的问题

原代码的核心问题

  • HTML按钮标签闭合错误:<button>应该用</button>而非</a>
  • SVG矩形的fill值格式错误:#00000是5位无效值,需改为#000或#000000
  • Snap.svg使用方式错误:创建的pattern对象不能直接赋值给style.fill,需先添加到SVG文档再通过url()引用
  • 未等待SVG加载完成就操作:可能导致contentDocument获取失败
  • 矩形默认visibility="hidden":不修改的话看不到填充效果

方案一:原生SVG实现(无需第三方库)

这种方法更轻量,无需依赖Snap.svg:

修正后的HTML

<button onclick="changeRect('rect252')">Input</button>
<object type="image/svg+xml" id="main" class="edit-area" data="image.svg"></object>

JavaScript代码

// 监听SVG加载完成事件,避免提前操作
document.getElementById('main').addEventListener('load', () => {
  console.log('SVG加载完成');
});

function changeRect(id){
    const obj = document.getElementById("main");
    const svgDoc = obj.contentDocument;
    
    // 校验SVG是否加载完成
    if(!svgDoc) {
        alert('SVG未加载完成,请稍后重试');
        return;
    }
    
    const svgRect = svgDoc.getElementById(id);
    if(!svgRect) {
        alert('未找到指定ID的矩形');
        return;
    }

    // 显示矩形
    svgRect.setAttribute('visibility', 'visible');

    // 创建pattern元素(SVG命名空间必须正确)
    const pattern = svgDoc.createElementNS('http://www.w3.org/2000/svg', 'pattern');
    pattern.setAttribute('id', 'imgPattern');
    pattern.setAttribute('patternUnits', 'userSpaceOnUse');
    pattern.setAttribute('width', '50'); // 图案重复单元宽度,可按需调整
    pattern.setAttribute('height', '50'); // 图案重复单元高度,可按需调整

    // 创建image元素
    const img = svgDoc.createElementNS('http://www.w3.org/2000/svg', 'image');
    img.setAttribute('href', 'teste.svg'); // SVG内图片需用href而非src
    img.setAttribute('width', '50');
    img.setAttribute('height', '50');

    // 将pattern添加到SVG的defs(没有defs则创建)
    pattern.appendChild(img);
    let defs = svgDoc.querySelector('defs');
    if(!defs) {
        defs = svgDoc.createElementNS('http://www.w3.org/2000/svg', 'defs');
        svgDoc.querySelector('svg').insertBefore(defs, svgDoc.querySelector('svg').firstChild);
    }
    defs.appendChild(pattern);

    // 给矩形设置图片填充
    svgRect.setAttribute('fill', 'url(#imgPattern)');
}

修正后的SVG(image.svg)

<svg xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
  <rect
     style="fill:#000;"
     id="rect252"
     width="51.396542"
     height="31.275505"
     x="120.8588"
     y="92.630028"
     inkscape:label="Right"
     visibility="hidden"/>
</svg>

方案二:Snap.svg修正版

如果一定要用Snap.svg,需调整pattern的添加方式:

JavaScript代码

document.getElementById('main').addEventListener('load', () => {
  console.log('SVG加载完成');
});

function changeRect(id){
    const obj = document.getElementById("main");
    const svgDoc = obj.contentDocument;
    
    if(!svgDoc) {
        alert('SVG未加载完成');
        return;
    }
    
    const svgRect = svgDoc.getElementById(id);
    if(!svgRect) {
        alert('未找到指定矩形');
        return;
    }

    svgRect.setAttribute('visibility', 'visible');

    // 用Snap包装SVG根元素
    const snapSvg = Snap(svgDoc.querySelector('svg'));
    // 创建并配置pattern
    const pattern = snapSvg.image('teste.svg', 0, 0, 50, 50).pattern(0, 0, 50, 50);
    // 确保defs存在并添加pattern
    snapSvg.select('defs') || snapSvg.append('<defs></defs>');
    snapSvg.select('defs').append(pattern);
    // 给矩形设置填充
    snapSvg.select('#' + id).attr('fill', pattern);
}

关键注意事项

  • 确保teste.svg与当前页面、image.svg在同一域名下,避免跨域导致图片加载失败
  • 必须等待<object>内的SVG完全加载后再执行操作,否则contentDocument会返回null
  • SVG元素创建时必须使用官方命名空间(http://www.w3.org/2000/svg),否则浏览器无法识别

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:57:16