【问题标题】:Why does Webkit/Safari (iOS, macOS) render my SVG transformations in a different order compared to Blink and Gecko?与 Blink 和 Gecko 相比,为什么 Webkit/Safari(iOS、macOS)以不同的顺序呈现我的 SVG 转换?
【发布时间】:2020-07-30 23:52:59
【问题描述】:

我有一个星号图标的最小 SVG 图像:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
    <defs>
        <style>
        .a {
            fill: red;
            transform-box: fill-box;
            transform-origin: center;
        }
        </style>
    </defs>
    <!-- x = 45 because it's 10px wide and centered around x=50, so x0 == 45, x1 == 55 -->
    <rect class="a" x="45" y="0" width="10" height="100"/>
    <rect class="a" x="45" y="0" width="10" height="100" transform="rotate(-45)"/>
    <rect class="a" x="45" y="0" width="10" height="100" transform="rotate( 45)"/>
    <rect class="a" x="45" y="0" width="10" height="100" transform="rotate(-90)"/>
</svg>

这在 Firefox 75 和 Chrome 80 中可以正确呈现,但在 iOS 或 macOS 上的 Safari 则不正确:

火狐75:

铬 80:

iOS 13 上的 Safari

但在 Safari 上,transform-origin 似乎被忽略了,或者与每个 &lt;rect&gt; 元素上的 transform="" 属性相比,应用乱序:

我听说它会在 macOS Safari 上呈现相同的损坏图像(我现在无法立即访问 macOS Safari,所以我无法从那里发布屏幕截图,抱歉)。

我在 Google 上搜索过 Safari/WebKit 是否缺乏对 transform-boxtransform-origintransform="rotate(deg)" 的支持,但据我所知,它们多年来都得到 Safari 的完全支持 - 所以我不明白为什么它会乱序应用转换并导致渲染中断。

【问题讨论】:

  • 大概 safari 不支持 SVG 上的 transform-origin 或 transform-b​​ox。
  • @RobertLongson 但是 MDN 和 CanIUse.com 都报告说 Safari 支持 SVG 的 transform-origintransform-box,没有关于行为差异的注释或其他说明。
  • 可能文档有误。
  • @RobertLongson 看起来文档只是在技术上是正确的 - 看起来 Safari 确实支持 SVG 中的 transform-origin CSS 属性,但它不将它用于 transform="" 链,这很奇怪(并且与所有其他浏览器相反......)
  • @RobertLongson 我正在向 MDN 的浏览器兼容性数据库提交 PR 以改进文档。

标签: svg safari webkit chromium


【解决方案1】:

在 Safari 中摆弄 SVG 后,Safari 的 Web Inspector确实 似乎识别了 transform-origin SVG 样式属性,但在应用转换时它实际上并没有使用它,这很奇怪(例如使用transform-origin: center;transform-origin: 0px 0pxtransform-origin: 50px 50px 没有效果) - 所以解决方法在于使用其他方式更改旋转中心。

据我所知,macOS Safari 和 iOS Safari 都只使用 transform-origin 进行使用 transform 属性的基于 CSS 的转换,而 not 在使用基于 SVG 属性的转换时使用 @ 987654328@ - 而 Blink 和 Gecko 都使用transform-origin 进行基于属性和基于 CSS 的转换。

使用translate 步骤

一种方法是添加一个translate 步骤,使旋转中心位于画布中心,然后执行旋转,然后撤消translate 步骤:

transform="translate( 50, 50 ) rotate(45) translate( -50, -50 )"

像这样:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100">
    <rect fill="red"    x="45" y="0" width="10" height="100" />
    <rect fill="blue"   x="45" y="0" width="10" height="100" transform="translate(50,50) rotate(-45) translate(-50,-50)" />
    <rect fill="green"  x="45" y="0" width="10" height="100" transform="translate(50,50) rotate( 45) translate(-50,-50)" />
    <rect fill="orange" x="45" y="0" width="10" height="100" transform="translate(50,50) rotate(-90) translate(-50,-50)" />
</svg>

更好的方法:使用rotate( angle, x, y )

I saw that the rotate transformation function 支持使用附加参数指定旋转中心,而不是将初始 translate 步骤应用于 transform 链 - 所以这适用于 Safari、Chrome (+Edge +Opera) 和 Firefox :

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100">
    <rect fill="red"    x="45" y="0" width="10" height="100" />
    <rect fill="blue"   x="45" y="0" width="10" height="100" transform="rotate(-45, 50, 50)" />
    <rect fill="green"  x="45" y="0" width="10" height="100" transform="rotate( 45, 50, 50)" />
    <rect fill="orange" x="45" y="0" width="10" height="100" transform="rotate(-90, 50, 50)" />
</svg>

【讨论】:

    猜你喜欢
    • 2017-11-04
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    相关资源
    最近更新 更多