多个SVG clipPath在不同位置使用元素

时间:2014-11-04 00:41:54

标签: svg clipping

直到最近,在Firefox(v25)中正确呈现了以下SVG代码,但它还没有(v33)。我测试过的所有其他浏览器(Chrome 33,Safari 6,IE 10)。

http://jsfiddle.net/9btoveeL/

<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>

我尝试做的是将准备好的符号分成三部分,然后在我喜欢的任何地方使用这三部分。在Firefox 33中,似乎它正在应用剪辑的原始位置(在我的示例中为0,0或0,10),而其他浏览器和以前版本的Firefox从左上角开始应用剪辑它应用于use元素。 如果必须移动每个剪辑路径以匹配use的位置而不是被视为相对于它的位置,我就无法看到剪辑如何在多个元素中重复使用。

1 个答案:

答案 0 :(得分:5)

默认情况下,剪切路径的位置在应用它的对象的用户坐标系中计算(clipPathUnits="userSpaceOnUse")。

(您可以将其设置为clipPathUnits="objectBoundingBox",但是您必须将裁剪路径中的所有形状长度重新定义为相对于要裁剪的形状的高度和宽度。)< / em>的

有一个简单的解决方案可以始终获得您想要的效果:转换使用元素的坐标系。不要使用xy属性定位它们,而是使用transform="translate(x,y)"属性定位它们。这样,用于定位剪切路径的坐标系将随之移动。

Here's your fiddle updated to show the change。它在下面作为堆栈代码重复,并且应该在所有浏览器中按预期工作。

&#13;
&#13;
<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>

    
&#13;
&#13;
&#13;


那么当您使用xy代替transform时,应该会发生什么?很难说,因为规格不一致。

Firefox(v33)实现从剪切路径规则的逻辑应用程序中有意义。 当您<use> <symbol>时,您可以为符号中的内容创建新的坐标空间,但use元素仍位于父坐标空间中。并且因为它是被剪裁的use元素,所以这是与剪切路径匹配很重要的坐标。 x坐标为50或更大的use元素将始终位于您给出的剪切路径之外,不会超过x = 30.

但是,为什么其他浏览器将剪切路径原点定位在<use>元素的(x,y)点而不是坐标系的原点?这是因为the way the specifications define how x and y should be implemented:作为添加到分组元素的附加转换,该分组元素还具有您在clip-path上指定的所有其他属性和样式(包括<use>)。 / p>

根据规格,以下代码:

<use xlink:href="#content" clip-path="url(#clip)" 
     x="50" y="100" width="50" height="100" />

应该被渲染(假设&#34;内容&#34;是<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>

并且在该表示下,剪切路径应该被翻译以匹配transform属性。

然而,这与使用<image><rect>代替<use>时会发生的情况完全不同,但与x完全相同,{{1 }},ywidthheight属性。对于这些其他元素,clip-pathx仅定义父坐标系内的位置,而不是坐标系的变换,因此它们确实会更改剪切路径的原点。这就是为什么我会把这称为规范中不幸的不一致。