我想制作一个包含一些“卡片翻转”风格动画的svg图片文件,使用css并在svg文件中嵌入样式表。在Chrome中,至少会出现两个问题,具体取决于所使用的代码:卡的正面即使在翻转时也保持不可见,使背面模糊,或者卡的背面被错误地定位。以下是我试图实现的简化版本:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
id="svg2"
version="1.1">
<style>
.outmost {
perspective: 100px;
transform-style: preserve-3d;
}
.outer {
transform-style: preserve-3d;
animation: flip 3s infinite alternate;
transform-origin: 50% 50%;
}
/* Front side */
.outer > :nth-last-child(1) {
transform: rotateY(0deg);
}
/* Backside */
.outer > :nth-child(1) {
transform: rotateY(-180deg);
}
/* Both sides */
.outer > * {
backface-visibility: hidden;
<!-- transform-style: preserve-3d; -->
transform-origin: 50% 50%;
}
@keyframes flip {
50% { transform: rotateY(180deg); }
}
</style>
<g class="outmost"> <!-- Container of the card -->
<g class="outer"> <!-- The card itself -->
<rect x="30" y="30" width="40" height="40" fill="red" /> <!-- Back side of the card -->
<rect x="30" y="30" width="40" height="40" fill="green" /> <!-- Front side of the card -->
</g>
</g>
</svg>
这是一个带有裸矩形的图片,如上面的代码所示:http://imgh.us/transformorigin_example_1.svg
这是一幅以列特为单位的图,像这样:<g> <rect … /> </g>
:http://imgh.us/transformorigin_example_2.svg
这在Firefox 44中显示得很正确,但在Chrome 48中严重损坏(都在MS Windows下),我想知道是否有任何方法可以解决这个问题。(我已经放弃了让它在Internet Explorer中工作的想法--后者根本没有动画图片,这比一个破碎的动画要好得多。
首先,Chrome似乎不尊重背面可见性,这有点破坏了整个卡片技巧:上面总是显示同一张牌背面不会变得可见。我试图通过分别动画卡片的正面和背面的翻转来解决这个问题,当卡片转到另一边时,改变每一个的可见性属性,但这在Firefox或Chrome中都不太好用-显然时间控制得不够严格,所以两个翻转不同步。
其次,如果我把rect:s放在组中(这与实际使用相对应),它在Firefox中仍然有效,但Chrome的React是奇怪地将卡片的背面向左偏移(这似乎是因为原始的旋转,旨在将背面放在颠倒的起始位置,围绕错误的中心旋转-换句话说,translation-origin属性似乎在那个阶段尚未生效,或者做得不正确),然后围绕新的中心旋转整个东西(然而,它确实看起来像是在(mangled)对象的translation-origin: 50% 50%
处,因为它应该,只有一个部分现在处于错误的位置,所以整个效果最终是错误的)。非常令人厌恶。
有几件事我试过了,没有用:1)将transform-origin: 50% 50%;
放在标记为/* Front side /和/ Backside /的声明块中(以便它们在代码方面接近它们应该影响的转换); 2)将声明块/ Both sides /放在/ Front side /和/ Backside */块之前; 3)将样式信息放入rect元素(<rect … style=”…” />
)中; 4)(有点绝望)添加-webkit-
前缀; 5)使用-webkit-backface-visibility: visible;-webkit-backface-visibility: hidden;
,即打开能见度,然后关闭,如this question的答案; 6)将“overflow:visible”添加到“outer”组,如this question中所建议的; 7)加入额外的transform:rotateY(0deg);
或transform: translate3d(0,0,0);
,如同一问题所建议。
也许还有一点很有趣,在Chrome的inspector中随意摆弄属性有时可以中和第二个问题(不正确的translation-origin),使卡片的两面最终在同一个地方,如果卡片是半透明的并且包含一个形状(但背面可见性仍然是错误的),这就变得很明显了,尽管我还没有能够在发生这种情况时辨别出任何模式。这种行为表明我们实际上可能在处理两个不同的bug。到目前为止,似乎只有在检查器中才有可能实现这一点,而不是通过对源代码进行更改。
我曾试图在网上寻找信息,但在谷歌上搜索“Chrome backface-visibility bug”或“chrome transform-origin bug”之类的东西,并没有真正找到任何有用的东西,我已经尝试过的想法。(然而,它确实出现了这句不祥的话:“Chrome充满了这些类型的SVG转换错误。”)有一堆旧的,有点类似的stackoverflow问题,但以下都没有帮助:backface-visibility:hidden bug in chrome,Did -webkit-backface-visibility break today in Chrome?,Webkit backface visibility not working .
有什么想法吗?
1条答案
按热度按时间yv5phkfx1#
我找不到一个解决方案,在纯SVG的Chrome中工作。然而,我确实使用HTML元素实现了同样的效果,这对某些人来说可能是一个可以接受的解决方案。
诀窍是为每个面使用单独的SVG元素,因为
backface-visibility: hidden
适用于HTML元素。CodePen:https://codepen.io/IJMacD/pen/qBLjdxw