在SVG组上设置transform-origin不在FireFox中工作

时间:2013-02-28 15:16:22

标签: html css css3 svg transform

我遇到了让transform-origin在Firefox中运行的问题(v.18 +,未经测试的其他版本)。 Webkit浏览器按预期工作。

我正试图将原点设置为群组的中心,但到目前为止我没有尝试过任何东西。

以下是代码:

<!DOCTYPE html>
<html> 
    <head>
        <title>TEST</title>
        <style>
            #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);}
            }
        </style>
    </head>
    <body>
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128px" height="128px" viewBox="0 0 16 16">
            <g id="test">
                <rect fill="#404040" x="7.062" y="3.625" width="1.875" height="8.75"/>
            </g>
        </svg>
    </body>
</html>

感谢您的帮助!

8 个答案:

答案 0 :(得分:23)

我试图使用CSS过渡围绕其中心点旋转一个简单的cog svg图形。我和Firefox有同样的问题;变换起源似乎没有效果。

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

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

然后在其周围添加一组并转换到您想要的位置:

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

现在你可以应用应该在Firefox中运行的css转换(我使用JavaScript基于用户操作(js-rotateObject)向HTML标记添加一个类,并使用Minimizr检查浏览器是否可以处理转换和转换(.csstransforms.csstransitions):

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

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

希望有所帮助。

答案 1 :(得分:15)

截至Firefox 55(2017年8月8日发布),&#34;转换框&#34;现在支持CSS属性。将其设置为&#34; fill-box&#34;将模仿Chrome中关于SVG树中变换原点的内容。

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

更新2017-9-14

您可以在SVG结构中选择所需的元素,或者如Tom在注释中指出的那样,您只需将其应用于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;
}

答案 2 :(得分:8)

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

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

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

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

  4. 选择组后,选择对象&gt;再次分组。这会在原始组周围创建一个新组。

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

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

  7. 感谢@ PatrickGrey.co.uk的初步见解。最棘手的部分是弄清楚如何将初始变换应用于复杂对象的坐标,而无需借助拔毛和大量的数学运算。 StackOverflow上的一些地方记录了“Group,move,Ungroup”技巧,但直到今天我才忘记它。希望这些步骤可以为其他人带来相当多的悲伤。

答案 3 :(得分:2)

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

这解决了我的问题:

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

答案 4 :(得分:1)

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

-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等)来设置值。

答案 5 :(得分:0)

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的时序略有不同,并且在浏览器中运行良好。

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

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

像这样:

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

第一个声明只是检查你是否在使用Firefox,因为你不想在其他浏览器上禁用它。第二个语句检查浏览器是否支持transform-box - 属性。我在当前项目中使用它,它就像一个魅力。

相关问题