[英]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-box”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 编辑器的情况下执行此操作,以便您可以观察发生的情况。
选择要变换的元素,然后选择“对象”>“组”以创建一个新组。 拖动该组使其位于文档左上角的中心。 这将transform="translate(…, …)"
属性应用于组。
从菜单中选择对象 > 取消组合。 这将“展平”变换属性,将任何坐标变换应用于组中的元素。
仍应选择原始元素。 选择对象 > 组将它们放回组中。 如果您使用 CSS 来转换元素,请将您的ID
或class
属性添加到该组(XML 编辑器在这一点上派上用场,或者您可以通过右键单击它并选择Object Properties来修改组的 ID。类将需要将通过 XML 编辑器添加或稍后在您的文本编辑器中添加。)。
选择组后,再次选择对象 > 组。 这将在原始组周围创建一个新组。
将此新组拖到文档中的正确位置。 如果您使用 XML 编辑器检查 DOM,您将看到transform="translate(…, …)"
添加到外部组。
现在可以将任何 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.