26

我在让 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" 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>

4

8 回答 8

24

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

解决方案是绘制原始 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 转换(我使用基于用户操作 ( js-rotateObject) 的 JavaScript 向 HTML 标记添加一个类,并使用 Minimizr 检查浏览器是否可以处理转换和转换 ( .csstransforms.csstransitions):

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

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

希望有帮助。

于 2013-05-23T07:30:20.330 回答
21

从 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 在评论中指出的那样,您可以简单地将其应用于 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;
}
于 2017-08-09T03:40:06.067 回答
8

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

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

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

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

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

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

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

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

于 2013-07-12T20:28:49.083 回答
6

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

这为我解决了这个问题:

transform-box: fill-box;
transform-origin: center center;
于 2017-09-03T02:26:21.767 回答
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 等)来设置该值。

于 2015-09-01T17:50:30.807 回答
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 相同,时间稍有不同,并且跨浏览器效果很好。

于 2016-07-21T00:36:26.993 回答
0

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

#test{
    -webkit-transform-origin: 50% 50%;
    -moz-transform-origin: 50% 50%;
    ...
}
于 2018-01-18T08:52:35.903 回答
0

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

像这样:

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

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

于 2018-01-18T10:16:02.970 回答