1

与 Chrome、Edge 和 Opera 相比,我发现 Firefox 存在不一致之处。transform-origin使用 CSS 类时,每个浏览器都可以正常处理。但是,当我将transform-originSVG 元素作为属性放置时,FF 会忽略该效果。演示代码如下。我的主要问题是如何解决这个问题,但我也很想知道这是否是预期的行为。

CSStransform-origin在 FF 中工作。

<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 1000'>	
	<style>	
		.centered{			
			transform-origin: center;
		}
	</style>
	<path fill='#500' d='M500 500 400 400 400 600 600 600 600 400z' transform='scale(2)' class='centered'/>
</svg>

内联 SVG 似乎无法识别transform-origin(在 Chrome/edge 中始终有效)

<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 1000'>	
	<path fill='#500' d='M500 500 400 400 400 600 600 600 600 400z' transform='scale(2)' transform-origin='center'/>
</svg>


编辑:另一位用户指出这个问题类似于How to set transform origin in SVG,但他们的前提是超级广泛(如何)并且错误或过时(发布于 8.5 年前)。

“我尝试使用 transform-origin 属性,但它不会影响任何东西。”

也许浏览器支持有所改进,但我的问题特别表明transform-origin在所有现代浏览器中作为 CSS 规则或作为除 FireFox 之外的所有现代浏览器中的表示属性非常完美。这种差异很可能导致一个解决方案是该线程独有的,而第二个解决方案是对其他线程答案的新看法。

更不用说他们的问题以 JavaScript 实现为中心,并且是在 FireFox 无法识别诸如“中心”或无单位数字之类的关键字时发布的,这有损于核心 SVG 标记问题,即 FireFox 解释与transform-origin=''其他浏览器不同的表示属性.

4

2 回答 2

2

总的来说,标记为正确的答案在所有情况下都有效。但是,我正在编写另一个解决方案,因为它最容易实现。但请注意,它仅适用于transform而不适用于patternTransform. 虽然非 FireFox 浏览器可以识别transform-origin这两个属性,但我的解决方案不适用于patternTransformFireFox。

添加transform-origin样式属性 ( style='transform-origin:center') 而不是其自己的表示属性 ( transform-origin='center') 适用于transform,如下所示。这甚至适用于数据 URI 中的 SVG。

<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 1000'>    
    <path fill='#500' d='M500 500 400 400 400 600 600 600 600 400z' transform='scale(2)' style='transform-origin:center'/>
</svg>
于 2020-02-08T20:25:39.767 回答
1

我已经解决了这个问题,但我(到目前为止)无法给你一个全面的推理为什么它有效。

首先要知道的是,您可以链接 SVG 变换

因此,无论您在何处编写transform="scale(2)",都可以将 a 添加translate(x, y)到链中,如下所示:

transform="scale(2) translate(x, y)"

到目前为止,一切都很好......但如果scale2,那么我们应该赋予x和什么ytranslate

为了找出答案,我决定叠加更大和更小的 SVG 形状版本(彩虹的每种颜色一个),看看我能找到什么模式。

在你的灰色形状的顶部,我放置了一个相同大小的绿色形状。

我给绿色形状做了一个变换:

transform="scale(1) translate(0, 0)"

这样它就会与你原来的灰色形状完全一致。

然后我开始叠加较大的缩放版本(黄色橙色红色)并叠加较小的缩放版本(蓝色靛蓝紫罗兰色)。

我预测,x并且y在每种情况下都将与scale应用于该形状的因素以及原件的整体尺寸有关viewBox

有了 3 个较小的版本和 3 个较大的版本,模式就出现了:

  • 红色,8倍大 / x&y变换值是50% of ((1000 / 8) - 1000)
  • 橙色4倍大 / x&y变换值是50% of ((1000 / 4) - 1000)
  • 黄色,2倍大 / x&y变换值是50% of ((1000 / 2) - 1000)
  • 绿色,1倍大 / x&y变换值是50% of ((1000 / 1) - 1000)
  • 蓝色,0.5倍大 / x&y变换值是50% of ((1000 / 0.5) - 1000)
  • Indigo0.25倍大 / x&y变换值是50% of ((1000 / 0.25) - 1000)
  • 紫罗兰色0.125倍大 / x&y变换值是50% of ((1000 / 0.125) - 1000)

由此,我们可以得出结论,如果您定位一个以50%, 50%您为中心的形状,viewBox并且您希望在同一位置显示该形状scale(2),您必须应用translatefor xof:

50% of ((width of canvas / scale-factor) - (width of canvas))

where50%对应于x您想要将形状居中的位置。

和一个translatey

50% of ((height of canvas / scale-factor) - (height of canvas))

where50%对应于y您想要将形状居中的位置。

这一直有效,但我还没有花足够的时间盯着它,以正确理解原因。

工作示例:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">

<!-- Grey Original -->
<path fill="#555" d="M500 500 400 400 400 600 600 600 600 400z" />

<!-- Red Transform [50% of ((1000 / 8) - 1000) is -437.5] -->
<path fill="rgb(255, 0, 0)" d="M500 500 400 400 400 600 600 600 600 400z" transform="scale(8) translate(-437.5, -437.5)" />

<!-- Orange Transform [50% of ((1000 / 4) - 1000) is -375] -->
<path fill="rgb(255, 125, 0)" d="M500 500 400 400 400 600 600 600 600 400z" transform="scale(4) translate(-375, -375)" />

<!-- Yellow Transform [50% of ((1000 / 2) - 1000) is -250] -->
<path fill="rgb(255, 255, 0)" d="M500 500 400 400 400 600 600 600 600 400z" transform="scale(2) translate(-250, -250)" />

<!-- Green Transform [50% of ((1000 / 1) - 1000) is 0] -->
<path fill="rgb(0, 125, 0)" d="M500 500 400 400 400 600 600 600 600 400z" transform="scale(1) translate(0, 0)" />

<!-- Blue Transform [50% of ((1000 / 0.5) - 1000) is 500] -->
<path fill="rgb(0, 0, 125)" d="M500 500 400 400 400 600 600 600 600 400z" transform="scale(0.5) translate(500, 500)" />

<!-- Indigo Transform [50% of ((1000 / 0.25) - 1000) is 1500] -->
<path fill="rgb(63, 0, 255)" d="M500 500 400 400 400 600 600 600 600 400z" transform="scale(0.25) translate(1500, 1500)" />

<!-- Violet Transform [50% of ((1000 / 0.125) - 1000) is 3500] -->
<path fill="rgb(199, 125, 243)" d="M500 500 400 400 400 600 600 600 600 400z" transform="scale(0.125) translate(3500, 3500)" />

</svg>

于 2020-02-07T20:10:03.353 回答