SVG将相同的transform-origin应用于组/符号的所有子项

时间:2018-05-19 18:32:40

标签: css svg

我无法获得可重复使用的项目或组中的所有子项符合指定的transform-origin。目标是能够使用相同的样式模板反复重复使用相同的形状。但是,考虑transform-origin样式,CSS或其他方式,不会级联。它仅适用于<use>时。

例如:

svg {
  width: 125px; height: 125px;
  background: rgba(0, 0, 0, 0.5);
}
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
  <defs>
    <ellipse id="svg-ellipse-def" cx="500" cy="500" rx="140" ry="455" transform-origin="center" style="transform-origin: center"/>
  </defs>
  
  <symbol id="svg-ellipse" >
    <ellipse cx="500" cy="500" rx="140" ry="455" transform-origin="center" style="transform-origin: center"/>
  </symbol>
    
  <g fill="none" stroke="red" stroke-width="50">
     <use xlink:href="#svg-ellipse"/>
     <use xlink:href="#svg-ellipse" transform="rotate(45)"/>
     <use xlink:href="#svg-ellipse" transform="rotate(90)"/>
     <use xlink:href="#svg-ellipse-def" transform="rotate(-45)"/>
  </g>
</svg>

实际上,无论我使用class=属性还是transform-origin=属性甚至内联样式,变换原点都不适用。我也尝试将它包装在<defs>容器中。

期望的结果:

<use xlink:href="#svg-ellipse" transform="rotate(45)"/>     
<use xlink:href="#svg-ellipse" transform="rotate(90)"/>
<use xlink:href="#svg-ellipse" transform="rotate(-45)"/>

但是现在它看起来像这样:

<use xlink:href="#svg-ellipse" transform="rotate(45)" style="transform-origin:center"/>     
<use xlink:href="#svg-ellipse" transform="rotate(90)" style="transform-origin:center"/>
<use xlink:href="#svg-ellipse" transform="rotate(-45)" style="transform-origin:center"/>

svg {
  width: 125px; height: 125px;
  background: rgba(0,0,0,0.5);
}
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
  
  <symbol id="svg-ellipse" >
    <ellipse cx="500" cy="500" rx="140" ry="455"/>
  </symbol>
    
  <g fill="none" stroke="red" stroke-width="50">
     <use xlink:href="#svg-ellipse"/>
     <use xlink:href="#svg-ellipse" transform="rotate(45)"  transform-origin="center"/>
     <use xlink:href="#svg-ellipse" transform="rotate(90)" transform-origin="center"/>
     <use xlink:href="#svg-ellipse" transform="rotate(-45)"  transform-origin="center"/>
  </g>
</svg>

根据documentation

如果'use'元素引用'symbol'元素:

  

在生成的内容中,'use'将替换为'g',其中'use'元素的所有属性除了'x','y','width','height'和'xlink: href'被转移到生成的'g'元素。附加的变换translate(x,y)被附加到生成的'g'上'transform'属性的末尾(即右侧),其中x和y代表'x'和'y'的值'use'元素的属性。引用的“符号”及其内容被深度克隆到生成的树中,除了'符号'被'svg'替换。

查看开发控制台,这已得到确认,并且样式是内联但未应用的:

enter image description here

即使<use>元素具有transform-origin的内联样式,因为符号现在被转换为它自己的SVG作为<use>元素的子元素,并且它具有它自己的元素内联样式,不应该优先于它的父级内联吗?

1 个答案:

答案 0 :(得分:1)

您可以定位<use>元素本身,但不能定位其内容。原则上,内容可以继承 CSS属性。但是您遇到的障碍是:CSS transformtransform-origin属性都不可继承。

  • 如果旋转<use>元素,则围绕<use>元素的变换原点旋转它,而阴影DOM的内容相对于其根保持原位。

  • 如果您为<symbol><ellipse>设置了变换原点,则只有在您自己进行变换时才会应用它,并且变换将被克隆到其每个重用中。

我看到的最佳解决方案是将所有使用元素引用相同的符号转换起源。要使属性选择器起作用,您需要不使用xlink命名空间。无论如何,这已被弃用,但您必须考虑browser compatibility

但是,transform-origin support in SVG也是如此。那顺便说一下是原因 设置transform-box: fill-box。在Firefox和Chrome之间的实现方面存在一些差异之后,现在已经接受了这一点 SVG元素需要使用属性来转换它们与边界框相关的属性。我已经改变了你的例子来证明。

&#13;
&#13;
svg {
  width: 125px; height: 125px;
  background: rgba(0, 0, 0, 0.5);
}

use[href="#symbol1"] {
  transform-origin: center;
  transform-box: fill-box;
}
&#13;
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1500 1500">
  
  <symbol id="symbol1" >
    <ellipse cx="500" cy="500" rx="140" ry="455" />
  </symbol>
    
  <g fill="none" stroke="red" stroke-width="50">
     <use href="#symbol1" transform="translate(200, 400)" />
     <use href="#symbol1" transform="translate(200, 400) rotate(45)"/>
     <use href="#symbol1" transform="translate(200, 400) rotate(90)"/>
     <use href="#symbol1" transform="translate(200, 400) rotate(-45)"/>
  </g>
</svg>
&#13;
&#13;
&#13;