CSS 3D:rotateY + translateX 使元素在 Firefox 中闪烁

Posted

技术标签:

【中文标题】CSS 3D:rotateY + translateX 使元素在 Firefox 中闪烁【英文标题】:CSS 3D : rotateY + translateX make elements flicker during in Firefox 【发布时间】:2014-06-13 01:08:14 【问题描述】:

我需要在某些元素上实现“房间”3d 旋转;实现它transform: translateX(-100%) rotateY(90deg) 和它相反的过渡被使用。它在 Chrome 中运行良好,但 在 Firefox 中(最高版本 34)在过渡期间元素会闪烁。他们可以这样做只是片刻,已经走了一半,或者完全消失了。

我注意到:如果父级上的perspective CSS 值高于计算出的相关元素的宽度 - 过渡顺利。如果观点真的是罪魁祸首,那么我不明白这种行为的本质;规范说,如果 所有点 的 Z 轴值低于透视值,则不会绘制元素。在过渡期间,我的绝对应该至少部分可见。

需要注意的是,只有 rotateY 看起来有问题 - 而不是 rorateX。

这里是代码示例。 html:

<div class="cont">
    <div id="bg-club" class="background club"></div>
    <div id="bg-cafe" class="background cafe active"></div>
    <div id="bg-fitness" class="background fitness"></div>
    <div id="bg-resto" class="background resto"></div>
    <div id="bg-lady" class="background lady"></div>
</div>

CSS(为方便起见,去掉了前缀规则):

 .cont
      position:absolute;
      top:0;
      right:0;
      bottom:0;
      left:0;
      z-index:1;
      overflow:hidden;

      perspective:1000px;
      transform-style:preserve-3d;
 
 .background.active
      visibility:visible;
      z-index:1;
 
 .background
      position:absolute;
      top:50px;
      right:50px;
      bottom:50px;
      left:50px;
      z-index:10;

      backface-visibility: hidden; 
      transform: translate3d(0, 0, 0);
      transform-style: preserve-3d; 

      visibility:hidden;
      overflow:hidden;

      background-repeat:no-repeat;
      background-position:center center;
      background-size:cover;
     
      .background.cafebackground-color:#987071;
      .background.clubbackground-color:#a3367f
      .background.fitnessbackground-color:#79728b;
      .background.ladybackground-color:#a6160e;
      .background.restobackground-color:#712912;
.rotateRoomLeftOut 
    transform-origin: 100% 50%;
    animation: rotateRoomLeftOut 4s both ease;

.rotateRoomLeftIn 
    transform-origin: 0% 50%;
    animation: rotateRoomLeftIn 4s both ease;


@keyframes rotateRoomLeftOut 
    to  opacity: .3; transform: translateX(-100%) rotateY(90deg); 

@keyframes rotateRoomLeftIn 
    from  opacity: .3; transform: translateX(100%) rotateY(-90deg); 

这里是the fiddle。通过按下 1-5 个黄色框,我们激活了相应的背景动画。这里的perspective是1000px,所以un想要的效果可以通过调整窗口大小来实现。

另一个例子是this great set of page 3D transitions。只需导航到 Rotate->Room->Room to Left or Right。


编辑

似乎 Firefox 只使那些元素闪烁,其对应的尺寸(RotateYwidthrotateXheight)大于父级的 perspective。我还没有弄清楚为什么会发生这种情况,但迄今为止最简单和最直接的解决方案是将上述透视设置为大于元素的尺寸。在我的情况下,对于 FF 19+ 或其他方式,它将是 100vw(或 100vmax 覆盖两个旋转尺寸)。

更新后的sn-p:

$(document).ready(function()
	var generalEvtAffix = '.hotdot', bodyEl = $('body'), pageContents = $('.sidebar, .center-block'),
		tabsSel = $('.areas [data-toggle="tab"]');
		
	// Анимация фонов на главной
	var bgs = $('.background');
	$('.areas [data-toggle="tab"]').on('click'+generalEvtAffix, function(event)
		event.preventDefault();
		var thisLink = $(this);
		/* Если уже активен или анимация всё ещё не закончена, ничего не делаем */
		if(thisLink.parent().hasClass('active') || bgs.hasClass('animated'))
			return;
		var bg = $('#bg-'+this.getAttribute('data-bg')),
			bgActive = $('.background.active');
		/* Случайным образом определяем направление анимации. */
		var animationDirs = ["Left"/* , "Top", "Right", "Bottom" */],
			animationDirection = animationDirs[Math.floor(Math.random() * (animationDirs.length) + 0)];
			
		/* - отключаем клик по ссылке на направлении - чтобы временно заблокировать переключение вкладок */
		tabsSel.on('click'+generalEvtAffix+'.clicked', function(e)
			e.preventDefault();
			return false;
		);
		
		bgActive.addClass('animated rotateRoom'+animationDirection+'Out')
			.on('animationend.homepage-area-click webkitAnimationEnd.homepage-area-click', function()
				/* По окончании анимации "Прочь" прошлого активного элемента скрываем его */
				$(this).removeClass('animated active rotateRoom'+animationDirection+'Out')
					.off('animationend.homepage-area-click webkitAnimationEnd.homepage-area-click');
			);
		bg.addClass('animated active rotateRoom'+animationDirection+'In')
			.on('animationend.homepage-area-click webkitAnimationEnd.homepage-area-click', function(event)
				/* По окончании анимации обратно включаем клик. */
				console.log(event);
				$(this).removeClass('animated rotateRoom'+animationDirection+'In')
					.off('animationend.homepage-area-click webkitAnimationEnd.homepage-area-click');;
				tabsSel.off('click'+generalEvtAffix+'.clicked');
			);
	);
	);
 .cont
	position:absolute;
	top:0;
	right:0;
	bottom:0;
	left:0;
	z-index:1;
	overflow:hidden;
	
	-webkit-perspective:1000px;
	-moz-perspective:1000px;
	perspective:1000px;
	-webkit-transform-style:preserve-3d;
	-moz-transform-style:preserve-3d;
	transform-style:preserve-3d;

@-moz-document url-prefix()
    .cont
     perspective:100vw;   
    

.background.active
	visibility:visible;
	z-index:1;

.background
	position:absolute;
	top:50px;
	right:50px;
	bottom:50px;
	left:50px;
    z-index:10;
	
 	-webkit-backface-visibility: hidden;
	-moz-backface-visibility: hidden;
	backface-visibility: hidden; 
    -webkit-transform: translate3d(0, 0, 0);
    -moz-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
 	-webkit-transform-style: preserve-3d;
	-moz-transform-style: preserve-3d;
	transform-style: preserve-3d; 
	
	visibility:hidden;
	 overflow:hidden;
	
	background-repeat:no-repeat;
	background-position:center center;
	background-size:cover;

	.background.cafe
		background-color:#987071;
    
    .background.club
		background-color:#a3367f
	
	.background.fitness
		background-color:#79728b;
	
	.background.lady
		background-color:#a6160e;
	
	.background.resto
		background-color:#712912;
	
/* Классы анимации фона типа "Room" */
	.rotateRoomLeftOut 
		-webkit-transform-origin: 100% 50%;
		-webkit-animation: rotateRoomLeftOut 4s both ease;
		-moz-transform-origin: 100% 50%;
		-moz-animation: rotateRoomLeftOut 4s both ease;
		transform-origin: 100% 50%;
		animation: rotateRoomLeftOut 4s both ease;
	
	.rotateRoomLeftIn 
		-webkit-transform-origin: 0% 50%;
		-webkit-animation: rotateRoomLeftIn 4s both ease;
		-moz-transform-origin: 0% 50%;
		-moz-animation: rotateRoomLeftIn 4s both ease;
		transform-origin: 0% 50%;
		animation: rotateRoomLeftIn 4s both ease;
	
/* Описание анимаций */

	@-webkit-keyframes rotateRoomLeftOut 
		to  opacity: .3; -webkit-transform: translateX(-100%) rotateY(90deg); 
	
	@-moz-keyframes rotateRoomLeftOut 
		to  opacity: .3; -moz-transform: translateX(-100%) rotateY(90deg); 
	
	@keyframes rotateRoomLeftOut 
		to  opacity: .3; transform: translateX(-100%) rotateY(90deg); 
	

	@-webkit-keyframes rotateRoomLeftIn 
		from  opacity: .3; -webkit-transform: translateX(100%) rotateY(-90deg); 
	
	@-moz-keyframes rotateRoomLeftIn 
		from  opacity: .3; -moz-transform: translateX(100%) rotateY(-90deg); 
	
	@keyframes rotateRoomLeftIn 
		from  opacity: .3; transform: translateX(100%) rotateY(-90deg); 
	
.areas
    list-style:none;
    position:relative;z-index:1000;

.areas li a
    display:block;
    width:20px;
    height:20px;
    background:yellow;
    margin:5px;
    color:black;
    
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cont">
		<div id="bg-club" class="background club"></div>
		<div id="bg-cafe" class="background cafe active"></div>
		<div id="bg-fitness" class="background fitness"></div>
		<div id="bg-resto" class="background resto"></div>
		<div id="bg-lady" class="background lady"></div>
	</div>

<ul class="areas text-center content-section">
		<li><a href="#club" class="club" data-target="[data-tab='club']" data-bg="club" data-toggle="tab">1</a>
		</li><li class="active"><a href="#cafe" class="cafe" data-target="[data-tab='cafe']" data-bg="cafe" data-toggle="tab">2</a>
		</li><li><a href="#fitness" class="fitness" data-target="[data-tab='fitness']" data-bg="fitness" data-toggle="tab">3</a>
		</li><li><a href="#resto" class="resto" data-target="[data-tab='resto']" data-bg="resto" data-toggle="tab">4</a>
		</li><li><a href="#lady" class="lady" data-target="[data-tab='lady']" data-bg="lady" data-toggle="tab">5</a>
		</li>
	</ul>

仍然期待这种行为背后的原因。

【问题讨论】:

@JohanVdR,抱歉,您查看我的代码示例了吗?过渡不需要假装它们是 3D - 它们已经 3D 的。 backface-visibility 已经转为隐藏(我也在父元素上尝试过,但没有效果)。 可能会添加更多关键帧。 webdesign.tutsplus.com/tutorials/… 最初我以为您在谈论小提琴的顶部边框缺少抗锯齿,但您实际上看到的是闪烁/消失的面板是吗?在我的系统上(最新的 Nightly,优胜美地公共预览版 2)它看起来不错(除了前面提到的混叠)。对你来说仍然是个问题吗?您正在运行什么 GPU,您的驱动程序是最新的吗? 【参考方案1】:

我相信它闪烁的原因是 Mozilla 检测到对象不在视野范围内。 如果你的视角是 1000px,并且宽度为 1100px 的东西旋转了,那么元素的边缘会从你身后经过并且看不见,mozilla 可能会将其确定为“不渲染”

对于一致的视图,我可以提供的唯一解决方案是将视角设置为 100vw 之类的值,以确保您的视角始终与屏幕宽度一样远

【讨论】:

以上是关于CSS 3D:rotateY + translateX 使元素在 Firefox 中闪烁的主要内容,如果未能解决你的问题,请参考以下文章

css translate3d

css CSS3,动画:使用translate3d强制WebKit中的硬件加速

CSS3d 基础

css3 - 3d效果立方体

CSS3D效果

css3translate3d做从下往上显示