svg - 与 Blink 和 Gecko 相比,为什么 Webkit/Safari(iOS、macOS)以不同的顺序呈现我的 SVG 转换?
问题描述
我有一个星号图标的最小 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
相比,似乎被忽略或乱序应用:transform=""
<rect>
有人告诉我它会在 macOS Safari 上呈现相同的损坏图像(我现在无法立即访问 macOS Safari,所以我无法从那里发布屏幕截图,抱歉)。
我在 Google 上搜索了 Safari/WebKit 是否缺乏对 的支持transform-box
,transform-origin
或者transform="rotate(deg)"
据我所知,Safari 多年来都完全支持它们——所以我不明白为什么它会应用这些转换——无序并导致渲染损坏。
解决方案
在 Safari 中摆弄 SVG 后,Safari 的 Web Inspector似乎确实识别了transform-origin
SVG 样式属性,但在应用转换时它实际上并没有使用它,这很奇怪(例如使用transform-origin: center;
或transform-origin: 0px 0px
没有transform-origin: 50px 50px
效果) - 所以修复在于使用其他方式更改旋转中心。
据我所知,macOS Safari 和 iOS Safari 都只transform-origin
用于使用属性的基于 CSS 的转换,transform
而不是在使用基于属性的 SVG 转换时使用transform=""
- 而 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 )
:
我没有对链应用初始translate
步骤,而是看到转换函数支持使用附加参数指定旋转中心 - 所以这适用于 Safari、Chrome (+Edge +Opera) 和 Firefox:transform
rotate
<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>
推荐阅读
- elasticsearch - 如何对包含空格的属性名称进行弹性搜索聚合
- node.js - 如何在源程序终止时捕获整个程序管道输出?
- python - Python - dir(list) -- __functions__ 它们是什么?
- c# - 在 mvc 中将 C# 字符串与 jquery 进行比较
- javascript - 在 React 中以列表格式输出数组
- android - TextView 更改后 ImageButton 更改位置
- qt - 在 CMake 中链接到 Qt --> 无法链接到 QML/QtQuick 函数
- sql-server - xp_instance_regread 程序不断自动执行
- php - 无法通过 php 在 mongodb 中查询 ISODate
- javascript - 如何为用于查询 dyanmoDB 表的函数编写单元测试?