CSS透视旋转和平移问题

6
我试图制作一种CSS-only的幻灯片过渡效果,从一个内容部分过渡到另一个。为了以有趣的方式实现,我使用CSS的perspectiverotateX来实质上放置页面内容。然后,我试图使用translateY将内容向屏幕底部滑动。
单独使用translateYrotateX都能完美工作,无论perspective是什么。然而,当它们结合在一起时,只有在特定的perspective下才能工作,这取决于窗口大小和rotateY值。
这个jsFiddle中,它在我尝试过的窗口大小中工作得很好。问题是,我想将perspective值降低到大约250px,但我无法这样做而不破坏动画效果。
我尝试使用更高的rotateY度数代替降低perspective,但是出现了同样的问题。
@keyframes slide {
  0% { transform: perspective(450px); }
  25% { transform: perspective(450px) rotateX(30deg); }
  50%,100% { transform: perspective(450px) rotateX(30deg) translateY(100%);  }
}

我已在CSS Deck和jsFiddle上测试过,使用FireFox和Chrome浏览器,似乎这是一个一贯性的问题。
有人能给我提供一个原因,并提供一个解决方法吗?
2个回答

4

试着在父元素上设置perspective属性作为单独的规则(而不是在animation中的transform部分)。

.parent {
    perspective: 250px;
}

@keyframes slide {
    25% { transform: rotateX(30deg); }
    50%, 100% { transform: rotateX(30deg) translateY(100%); }
}

更新的fiddle:http://jsfiddle.net/myajouri/DYpnU/

我的推理:

  1. 在动画过程中,perspective 没有变化,因此将其作为动画的一部分没有任何意义。

  2. 由于您的元素占据了父元素的100%区域,因此在父元素上设置 perspective 应该会产生与在元素本身(在 transform 内)上设置它相同的结果。

  3. 看起来解决了你的问题(请参见上面的 fiddle)。

更新:经过更多实验,我发现在动画中明确设置 translateY(0) 的初始值也可以解决这个问题。

@keyframes slide {
    0% { transform: perspective(150px); }
    25% { transform: perspective(150px) rotateX(30deg) translateY(0); }
    50%, 100% { transform: perspective(150px) rotateX(30deg) translateY(100%); }
}

更新的 JSFiddle 示例: http://jsfiddle.net/myajouri/YJS3v/


很棒的解决方案,+1!我能够使用这种方法得到想要的效果。不过我还是很好奇为什么原始方法不行。有什么想法吗? - Zach Saucier
我的想法是因为你的“perspective”(透视)附加在元素本身上,而且由于你的元素在动画期间改变了形状和位置,“perspective-origin”(透视原点)也在移动,导致动画播放与预期不同,特别是当透视值太小时,这会加强3D变换。 - myajouri
但是为什么透视原点会跳到如此遥远的值,从根本上颠倒了动画显示的方式呢?我不明白它怎么可能有这种能力。 - Zach Saucier
刚刚用另一种解决方案更新了答案。我正在努力推理中,很快会更新的。 - myajouri
1
所以我没有一个明确的答案来解释为什么动画会以这种方式播放。似乎对此起作用的因素有:1.您的 translateY(100%) 可能是一个非常大的数字,具体取决于您的窗口大小;2.您使用了一个小的透视值,这意味着透视消失点非常靠近观察者,这意味着CSS变换效果将被加强。您可以尝试将帧/窗口大小缩小到非常小的尺寸(这意味着较小的 translateY(100%) 值),问题就会消失。 - myajouri

2

我只是在myajouri的答案上稍作改进。

至少在Chrome中,你可以这样写:

@-webkit-keyframes slide {
  0% { -webkit-transform: perspective(50vh); }
  10%,15% { -webkit-transform: perspective(50vh) rotateX(30deg) translateY(0%); }
  50%,100% { -webkit-transform: perspective(50vh) rotateX(30deg) translateY(100%);  }
}

将视角设置为视口高度应该比您当前的设置更具响应性

演示

(未在其他浏览器中测试)


我曾经苦苦挣扎地尝试在响应式3D形状上使用“vw”来实现透视效果,但将其更改为“vh”是一个神奇的解决方案。如果其他人遇到类似问题,出于某种原因,“vh”比“vw”更适合响应式3D! - ceindeg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接