【发布时间】:2023-02-10 23:27:49
【问题描述】:
我在 SVG 文件中结合使用 feTile 和 feOffset 来创建一个充满图案的阴影。图案本身也是一个 SVG 文件。为了保持完整的 SVG 独立,我想在其中嵌入模式而不是引用外部文件。
我发现的丑陋解决方法是对模式文件进行 base64 编码。此代码产生预期结果:
<svg>
<defs>
<!-- Base64-encoded below-->
<!-- <svg id="pattern1" xmlns='http://www.w3.org/2000/svg' width='10' height='10'> -->
<!-- <rect width='10' height='10' fill='#fff' /> -->
<!-- <circle cx="1" cy="1" r="1" fill="#000"/> -->
<!-- </svg> -->
<filter id="dropshadow" height="130%">
<!-- This does not work -->
<!-- <feImage width="3" height="3" result="checkerboard-image" xlink:href="#pattern1" /> -->
<feImage width="3" height="3" result="checkerboard-image"
xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+CiAgPHJlY3Qgd2lkdGg9JzEwJyBoZWlnaHQ9JzEwJyBmaWxsPScjZmZmJyAvPgogIDxjaXJjbGUgY3g9IjEiIGN5PSIxIiByPSIxIiBmaWxsPSIjMDAwIi8+Cjwvc3ZnPg==" />
<feTile in="checkerboard-image" result="texture" />
<feOffset dx="30" dy="20" result="offsetblur"/>
<feMerge>
<feMergeNode/> <!-- this contains the offset blurred image -->
<feMergeNode in="SourceGraphic"/> <!-- this contains the element that the filter is applied to -->
</feMerge>
</filter>
</defs>
<rect fill=white stroke=black x="10" y="10" width="200" height="100" style="filter:url(#dropshadow)" />
</svg>
我尝试嵌套 pattern-SVG 并使用它的 ID 引用它(请参阅代码中的代码注释),但这并没有显示任何内容。
是否可以做这样的事情来为模式引用另一个 SVG?
<feImage width="3" height="3" result="checkerboard-image" xlink:href="#pattern1" />
编辑:我找到了一种方法,但它似乎只适用于 chrome/chromium,firefox 例如没有正确呈现它。此外,添加更多 rect 的过滤器仍然无法正常工作
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" id="svg24" width="100%" height="1000" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<defs id="defs15">
<g transform="scale(0.25)" id="dotted-pattern">
<rect style="fill-opacity:0" id="pattern-box" width="16" height="16" />
<circle style="fill:#000" id="pattern-circle1" cx="10" cy="10" r="2" />
<circle style="fill:#000" id="pattern-circle2" cx="2" cy="2" r="2" />
</g>
<filter
id="dropshadow"
height="1.154449"
x="-0.0044999999"
y="-0.0049999999"
width="1.0582259">
<feImage width="4" height="4" result="pattern-image" href="#dotted-pattern" />
<feTile in="pattern-image" result="texture" id="feTile4" />
<feOffset dx="11" dy="15" result="offsetblur" id="feOffset6" />
<feMerge id="feMerge12">
<feMergeNode id="feMergeNode8" /> <feMergeNode in="SourceGraphic" id="feMergeNode10" />
</feMerge>
</filter>
</defs>
<rect fill="#ffffff" stroke="#000000" x="10" y="10" width="200" height="100" style="filter:url(#dropshadow)" id="node2" />
</svg>
【问题讨论】:
-
SVG 是 xml 格式,必须对二进制数据进行编码。 Base64 字符串是完成结果的一种方式。通常在具有多层图形的 SVG 中,层是文件的 URL。
标签: xml svg svg-filters