繁体   English   中英

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

[英]Setting transform-origin on SVG group not working in Firefox

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

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

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

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

希望有帮助。

从 Firefox 55(2017 年 8 月 8 日发布)开始,现在支持“transform-b​​ox”CSS 属性。 将其设置为“fill-box”将在 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;
}

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

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

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

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

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

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

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

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

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

这为我解决了问题:

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

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

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

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 相同,但时间略有不同,并且在浏览器中效果很好。

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

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

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

像这样:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM