直到最近,在Firefox(v25)中正确呈现了以下SVG代码,它怎么也不再(v33).我测试过的所有其他浏览器(Chrome 33,Safari 6,IE 10).
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" height="1000px" width="1000px" y="0px" x="0px" version="1.1">
<defs>
<clipPath id="clip1">
<rect height="100" width="10" y="0" x="0"/>
</clipPath>
<clipPath id="clip2">
<rect height="100" width="10" y="0" x="10"/>
</clipPath>
<clipPath id="clip3">
<rect height="100" width="10" y="0" x="20"/>
</clipPath>
<symbol id="fill_texture">
<g>
<rect height="10" width="10" x="0" y="0" fill="#ff0000"/>
<rect height="10" width="10" x="3" y="5" fill="#0ff000"/>
<rect height="10" width="10" x="6" y="10" fill="#0000ff"/>
<rect height="10" width="10" x="9" y="15" fill="#ffff00"/>
<rect height="10" width="10" x="12" y="20" fill="#ff00ff"/>
<rect height="10" width="10" x="15" y="25" fill="#00ffff"/>
</g>
</symbol>
</defs>
<g id="columns">
<use id="unclipped" xlink:href="#fill_texture" width="100" height="100" x="0" y="0"/>
<use id="slot1" xlink:href="#fill_texture" clip-path="url(#clip1)" x="50" y="0"/>
<use id="slot2" xlink:href="#fill_texture" clip-path="url(#clip2)" x="100" y="0"/>
<use id="slot3" xlink:href="#fill_texture" clip-path="url(#clip3)" x="150" y="0"/>
</g>
</svg>
Run Code Online (Sandbox Code Playgroud)
我试图做的是将准备好的符号分成三部分,然后在我喜欢的地方使用这三部分.在Firefox 33中,它似乎是在它的原始位置(在我的示例中为0,0或0,10)应用剪辑,而其他浏览器和以前版本的Firefox从use应用它的元素的左上角开始应用剪辑至.如果必须移动每个剪辑路径以匹配use而不是被视为相对于它的位置,我无法看到剪辑如何在多个元素中重用.
默认情况下,剪切路径的位置在应用它的对象的用户坐标系中计算(clipPathUnits="userSpaceOnUse").
(您可以将其设置为clipPathUnits="objectBoundingBox",但是您必须重新定义剪切路径中的所有形状长度,以相对于要剪切的形状的高度和宽度.)
有一个简单的解决方案可以始终获得所需的效果:转换使用元素的坐标系.而不是使用他们定位的x和y属性,以放置它们transform="translate(x,y)"的属性.这样,用于定位剪切路径的坐标系将随之移动.
这是你的小提琴更新,以显示变化.它在下面作为堆栈片段重复,并且应该在所有浏览器中按预期工作.
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"
xml:space="preserve" version="1.1"
height="100px" width="400px" y="0px" x="0px" >
<defs>
<clipPath id="clip1" >
<rect height="100" width="10" y="0" x="0"/>
</clipPath>
<clipPath id="clip2">
<rect height="100" width="10" y="0" x="10"/>
</clipPath>
<clipPath id="clip3">
<rect height="100" width="10" y="0" x="20"/>
</clipPath>
<symbol id="fill_texture">
<g>
<rect height="10" width="10" x="0" y="0" fill="#ff0000"/>
<rect height="10" width="10" x="3" y="5" fill="#0ff000"/>
<rect height="10" width="10" x="6" y="10" fill="#0000ff"/>
<rect height="10" width="10" x="9" y="15" fill="#ffff00"/>
<rect height="10" width="10" x="12" y="20" fill="#ff00ff"/>
<rect height="10" width="10" x="15" y="25" fill="#00ffff"/>
</g>
</symbol>
</defs>
<g id="columns">
<use id="unclipped" xlink:href="#fill_texture"
width="100" height="100" x="0" y="0"/>
<use id="slot1" xlink:href="#fill_texture" clip-path="url(#clip1)"
transform="translate(50,0)"/>
<use id="slot2" xlink:href="#fill_texture" clip-path="url(#clip2)"
transform="translate(100,0)"/>
<use id="slot3" xlink:href="#fill_texture" clip-path="url(#clip3)"
transform="translate(150,0)"/>
</g>
</svg>
Run Code Online (Sandbox Code Playgroud)
那么,应该在使用发生x和y替代transform?很难说,因为规格不一致.
Firefox(v33)实现从剪切路径规则的逻辑应用程序有意义.在<use>a时<symbol>,为符号内的内容创建新的坐标空间,但use元素仍在父坐标空间中.并且因为它是被剪裁的use元素,所以这是与剪切路径匹配很重要的坐标.x坐标为50或更大的use元素将始终位于您给出的剪切路径之外,不会延伸超过x = 30.
但是,为什么其他浏览器将剪切路径原点定位在<use>元素的(x,y)点而不是其坐标系的原点?这是因为该规范定义了如何的方式x,并y应实行:作为一个额外的转换添加到还有所有其他属性和样式(包括分组元素clip-path,你指定的)<use>.
根据规格,以下代码:
<use xlink:href="#content" clip-path="url(#clip)"
x="50" y="100" width="50" height="100" />
Run Code Online (Sandbox Code Playgroud)
应该被渲染(假设"content"是a <symbol>)与:
<g clip-path="url(#clip)" transform="translate(50,100)">
<svg width="50" height="100" <!--viewBox and other attributes from the symbol--> >
<!-- graphics from symbol#content go here -->
</svg>
</g>
Run Code Online (Sandbox Code Playgroud)
在该表示下,剪切路径应该被翻译以匹配transform属性.
然而,比如果使用了,会发生什么完全不同<image>或<rect>代替<use>,但完全相同的x,y,width,height和clip-path属性.对于这些其他元素,x并且y仅定义父坐标系内的位置,而不是坐标系的变换,因此它们确实改变了剪切路径的原点.这就是为什么我会把这称为规范中不幸的不一致.