在 SVG 组上设置变换原点在 Firefox 中不起作用

Posted

技术标签:

【中文标题】在 SVG 组上设置变换原点在 Firefox 中不起作用【英文标题】:Setting transform-origin on SVG group not working in Firefox 【发布时间】:2013-02-14 20:29:27 【问题描述】:

我在让 transform-origin 在 Firefox 中工作时遇到问题(v.18+,其他版本未测试)。 Webkit 浏览器按预期工作。我正在尝试将原点设置为组的中心,但到目前为止我尝试过的任何方法都没有奏效。

代码如下:

#test 
  -webkit-transform-origin: 50% 50%;
  transform-origin: center center;
  -webkit-animation: prop 2s infinite;
  animation: prop 2s infinite;


@-webkit-keyframes prop 
  0% 
    -webkit-transform: scale(1, 1);
  
  20% 
    -webkit-transform: scale(1, .8);
  
  40% 
    -webkit-transform: scale(1, .6);
  
  50% 
    -webkit-transform: scale(1, .4);
  
  60% 
    -webkit-transform: scale(1, .2);
  
  70% 
    -webkit-transform: scale(1, .4);
  
  80% 
    -webkit-transform: scale(1, .6);
  
  90% 
    -webkit-transform: scale(1, .8);
  
  100% 
    -webkit-transform: scale(1, 1);
  


@keyframes prop 
  0% 
    transform: matrix(1, 0, 0, 1, 0, 0);
  
  20% 
    transform: matrix(1, 0, 0, .8, 0, 0);
  
  40% 
    transform: matrix(1, 0, 0, .6, 0, 0);
  
  50% 
    transform: matrix(1, 0, 0, .4, 0, 0);
  
  60% 
    transform: matrix(1, 0, 0, .2, 0, 0);
  
  70% 
    transform: matrix(1, 0, 0, .4, 0, 0);
  
  80% 
    transform: matrix(1, 0, 0, .6, 0, 0);
  
  90% 
    transform: matrix(1, 0, 0, .8, 0, 0);
  
  100% 
    transform: matrix(1, 0, 0, 1, 0, 0);
  
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"   viewBox="0 0 16 16">
    <g id="test">
        <rect fill="#404040" x="7.062" y="3.625"  />
    </g>
</svg>

【问题讨论】:

FWIW,据说在 Firefox 19 beta 3 中已修复,尽管我在 Firefox 22 中仍然遇到问题。Mozilla bugzilla 列表:bugzilla.mozilla.org/show_bug.cgi?id=828286 Ugh nvm 抱歉误读,我不确定该错误是否相关... Firefox 中的 SVG 元素不支持 transform-origin。请投票bug #923193) 以获得支持。 @dotnetCarpenter 现在已在 Firefox 41+ 中修复 @zigomir 是的,你是对的!不过,它仍然不是默认的 firefox 浏览器。但是,是的,这个问题将在下一个 Firefox 版本中消失。测试:bug1013421.bmoattachments.org/attachment.cgi?id=8425610 【参考方案1】:

我试图使用 CSS 过渡围绕其中心点旋转一个简单的 cog svg 图形。我在使用 Firefox 时遇到了和你一样的问题; transform-origin 似乎没有效果。

解决方案是绘制原始的svg形状,使其中心位于坐标0, 0:

<svg x="0px" y="0px"   viewBox="0 0 400 400">
    <rect id="myObject" x="-50" y="-50" fill="#E52420"  />
</svg>

然后在其周围添加一个组并翻译到你想要的位置:

<svg x="0px" y="0px"   viewBox="0 0 400 400">
    <g transform="translate(150, 100)">
        <rect id="myObject" x="-50" y="-50" fill="#E52420"  />
    </g>
</svg>

现在您可以应用应该在 Firefox 中工作的 css 转换(我使用基于用户操作 (js-rotateObject) 的 javascripthtml 标记添加一个类,并使用 Minimizr 检查浏览器是否可以处理转换和转换(@ 987654326@):

#myObject
    transform: rotate(0deg);
    transition: all 1s linear;


.csstransforms.csstransitions.js-rotateObject #myObject
    transform: rotate(360deg);

希望对您有所帮助。

【讨论】:

对于那些遇到同样问题的人,这个答案很有帮助。如果您尝试在 元素上应用动画,它仍然可能不适用于 Firefox。这里有一个方便的修复:***.com/a/18943090/1869285 Firefox v42 现在支持 -moz-transform-origin 标签。 聪明的做法。希望 Firefox 能把他们的便便放在一起。 这是一个 Codepen 来证明你的观点(没有任何 Javascript)。谢谢你的提示。 :) codepen.io/schafeld/pen/zwjodP【参考方案2】:

从 Firefox 55(2017 年 8 月 8 日发布)开始,现在支持“transform-b​​ox”CSS 属性。将其设置为“填充框”将在 SVG 树中的变换原点方面模仿 Chrome。

transform-origin: center; /* or transform-origin: 50% */
transform-box: fill-box;

2017 年 9 月 14 日更新

您可以在 SVG 结构中选择您需要的元素,或者,正如 Tom 在 cmets 中指出的那样,您可以简单地将其应用于 SVG 元素的所有后代(只要样式不会干扰您的任何其他元素)正在努力实现):

svg .my-transformed-element 
    transform-origin: center; /* or transform-origin: 50% */
    transform-box: fill-box;

svg * 
    transform-origin: center; /* or transform-origin: 50% */
    transform-box: fill-box;

【讨论】:

请编辑您的答案以指明应在哪些元素上设置此 CSS 道具。 (SVG?G?路径/矩形/等)它像 HTML box-sizing,所以我们想要 svg * transform-box: fill-box; 吗?编辑:我最终做了后者。 svg * 已更新,感谢汤姆提供的信息! - 至于元素,它可以是 SVG 结构中需要样式的任何元素(例如制作动画) - &lt;g&gt;&lt;circle&gt;&lt;path&gt; 等等。 这应该是公认的答案。只是一个简单的svg * transform-box: fill-box; 为我修复了所有动画。 现在应该是答案了! @MSC - 在做了一些测试后,我认为这可能是一个错误,但我不确定。谢谢。【参考方案3】:

@PatrickGrey 的回答对我来说非常有效,但我需要处理具有多个路径的更复杂的 SVG。我能够使用 Inkscape 完成此修复,但这是一个多步骤的过程。我建议在打开 Inkscape XML 编辑器的情况下执行此操作,这样您就可以看到正在发生的事情。

    选择要变换的元素,然后选择对象>组创建一个新组。拖动该组,使其位于文档左上角的中心。这会将transform="translate(…, …)" 属性应用于组。

    从菜单中选择对象>取消组合。这将“展平”变换属性,将任何坐标变换应用于组中的元素。

    仍应选择原始元素。选择 Object > Group 将它们放回一个组中。如果您使用 CSS 来转换元素,请将您的 IDclass 属性添加到此组(XML 编辑器对此非常有用,或者您可以通过右键单击它并选择 对象属性。需要通过 XML 编辑器或稍后在文本编辑器中添加类。)。

    选中组后,再次选择对象>组。这会围绕原始组创建一个新组。

    将此新组拖动到文档中的正确位置。如果您使用 XML 编辑器检查 DOM,您会看到 transform="translate(…, …)" 已添加到 outer 组中。

    现在可以将任何 CSS 转换应用于 inner 组,Chrome 和 Firefox 将一致地处理它们。

感谢@PatrickGrey.co.uk 的初步见解。最棘手的部分是弄清楚如何将初始变换应用于复杂对象的坐标,而无需借助头发拉扯和大量数学运算。 *** 上有几个地方记录了“分组、移动、取消分组”的技巧,但直到今天我才忘记它。希望这些步骤可以为其他人节省相当多的悲伤。

【讨论】:

这项技术对我来说非常有效。非常感谢@thirdender! 很高兴它有帮助 :-) 如果您可以帮助编辑我的答案,使其更清晰,请随意。今天重读时,我仍然觉得它非常混乱……:-p【参考方案4】:

根据this bug report 中的cmets,Firefox 的transform-box 默认值与Chrome 不同。从 Firefox 55 开始,现在可以在不设置标志的情况下设置此属性。

这为我解决了这个问题:

transform-box: fill-box;
transform-origin: center center;

【讨论】:

在我的情况下,这是导致问题的原因。【参考方案5】:

如果您可以使用固定的像素值,请改用它来使其工作。

-moz-transform-origin: 25px 25px;
-ms-transform-origin:  25px 25px;
-o-transform-origin: 25px 25px;
-webkit-transform-origin:  25px 25px;
transform-origin: 25px 25px;

一些浏览器仍然不支持带有百分比值的转换原点,至少不是在所有情况下。如果您没有固定的 px 值,请为每个 javascript 计算一个并使用您选择的库(如 jQuery、Greensock 等)来设置该值。

【讨论】:

【参考方案6】:

FWIW,我能够使用 Greensock 解决我的问题,使用 TweenMax 为内部的各个路径设置动画,这在 Firefox Gecko 和 Webkit 浏览器(Safari/Chrome)中工作得更好(不完全是确定如何,但它对我有用)

有一个带有两个齿轮的 SVG,我想在另一个形状内旋转。所以我给每个齿轮一个唯一的 id (id="gear1", id="gear2") 然后用 Greensock 旋转它们,如下所示:

TweenMax.to("#gear1", 3.2,  
  repeat: -1, //repeat infintely 
  ease: Linear.easeNone,  //no easing, linear motion 
  rotation:360,  //amount to rotate (full) 
  transformOrigin:"center"  //transform origin that WORKS :) 
);

#gear2 相同,时间稍有不同,并且在浏览器中运行良好。

【讨论】:

【参考方案7】:

您的 css 代码中缺少 -moz-transform-origin

#test
    -webkit-transform-origin: 50% 50%;
    -moz-transform-origin: 50% 50%;
    ...

【讨论】:

【参考方案8】:

另外,您可以考虑为不支持transform-box: fill-box的 Firefox 版本禁用动画

像这样:

@supports (-moz-transform: rotate(0deg)) and (not (transform-box: fill-box)) 
    #test 
        animation: none;
    

第一个语句只是检查您是否在使用 firefox,因为无论如何您都不想在其他浏览器上禁用它。第二条语句检查浏览器是否支持transform-box-property。我在当前项目中使用了它,它就像一个魅力。

【讨论】:

以上是关于在 SVG 组上设置变换原点在 Firefox 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

SVG 变换原点 CSS 动画 – Firefox 错误

svg子元素上的CSS变换原点问题

Safari SVG 变换原点缩放动画

以光标位置为变换原点缩放 SVG

SVG 和 JQuery GIF 填充在 Firefox 上运行速度较慢

动画 SVG 组对象 - 使用样式组件进行变换旋转不会围绕圆原点旋转