2014-04-27 7 views
7

Ho bisogno di implementare una rotazione 3d "stanza" su alcuni elementi; per ottenerlo transform: translateX(-100%) rotateY(90deg) e la sua transizione opposta sono usati. Funziona bene in Chrome, ma in Firefox (fino alla versione 34) lo sfarfallio degli elementi durante la transizione. Possono farlo solo per un momento, aver fatto metà strada o scomparire completamente.CSS 3D: rotateY + translateX rendono lo sfarfallio degli elementi durante Firefox

Che cosa ho notato: se il valore CSS perspective nel padre è superiore alla larghezza calcolata degli elementi in questione, la transizione va bene. Se la prospettiva è davvero un colpevole, allora non capisco la natura di tale comportamento; le specifiche dicono, un elemento non viene disegnato se il valore dell'asse Z di tutti i suoi punti è inferiore al valore di prospettiva. E il mio dovrebbe essere visibile almeno in parte durante la transizione.

Si noti che solo la rotazioneY sembra difettosa, non la rorateX.

Ecco i campioni di codice. L'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> 

Il CSS (per comodità le regole prefissate vengono rimossi):

.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.cafe{background-color:#987071;} 
     .background.club{background-color:#a3367f} 
     .background.fitness{background-color:#79728b;} 
     .background.lady{background-color:#a6160e;} 
     .background.resto{background-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); } 
} 

Ed ecco the fiddle. Premendo 1-5 caselle gialle attiviamo l'animazione di sfondo corrispondente. Lo perspective qui è 1000px, quindi l'effetto desiderato è un ridimensionando la finestra.

L'altro esempio è this great set of page 3D transitions. Basta navigare su Ruota-> Stanza-> Stanza a sinistra o a destra.


Modifica

Sembra che Firefox rende solo quegli elementi sfarfallio, la cui corrispondente dimensione (sia width per RotateY o height per rotateX) è maggiore del genitore perspective. Non ho ancora capito, perché ciò accada, ma la soluzione più semplice e più immediata finora è quella di impostare la prospettiva sopra menzionata più grande della dimensione dell'elemento. Nel mio caso, sarebbe 100vw (o 100vmax per coprire entrambe le dimensioni di rotazione) per FF 19+ o un altro modo.

Il frammento di aggiornamento:

$(document).ready(function(){ 
 
\t var generalEvtAffix = '.hotdot', bodyEl = $('body'), pageContents = $('.sidebar, .center-block'), 
 
\t \t tabsSel = $('.areas [data-toggle="tab"]'); 
 
\t \t 
 
\t // Анимация фонов на главной 
 
\t var bgs = $('.background'); 
 
\t $('.areas [data-toggle="tab"]').on('click'+generalEvtAffix, function(event){ 
 
\t \t event.preventDefault(); 
 
\t \t var thisLink = $(this); 
 
\t \t /* Если уже активен или анимация всё ещё не закончена, ничего не делаем */ 
 
\t \t if(thisLink.parent().hasClass('active') || bgs.hasClass('animated')) 
 
\t \t \t return; 
 
\t \t var bg = $('#bg-'+this.getAttribute('data-bg')), 
 
\t \t \t bgActive = $('.background.active'); 
 
\t \t /* Случайным образом определяем направление анимации. */ 
 
\t \t var animationDirs = ["Left"/* , "Top", "Right", "Bottom" */], 
 
\t \t \t animationDirection = animationDirs[Math.floor(Math.random() * (animationDirs.length) + 0)]; 
 
\t \t \t 
 
\t \t /* - отключаем клик по ссылке на направлении - чтобы временно заблокировать переключение вкладок */ 
 
\t \t tabsSel.on('click'+generalEvtAffix+'.clicked', function(e){ 
 
\t \t \t e.preventDefault(); 
 
\t \t \t return false; 
 
\t \t }); 
 
\t \t 
 
\t \t bgActive.addClass('animated rotateRoom'+animationDirection+'Out') 
 
\t \t \t .on('animationend.homepage-area-click webkitAnimationEnd.homepage-area-click', function(){ 
 
\t \t \t \t /* По окончании анимации "Прочь" прошлого активного элемента скрываем его */ 
 
\t \t \t \t $(this).removeClass('animated active rotateRoom'+animationDirection+'Out') 
 
\t \t \t \t \t .off('animationend.homepage-area-click webkitAnimationEnd.homepage-area-click'); 
 
\t \t \t }); 
 
\t \t bg.addClass('animated active rotateRoom'+animationDirection+'In') 
 
\t \t \t .on('animationend.homepage-area-click webkitAnimationEnd.homepage-area-click', function(event){ 
 
\t \t \t \t /* По окончании анимации обратно включаем клик. */ 
 
\t \t \t \t console.log(event); 
 
\t \t \t \t $(this).removeClass('animated rotateRoom'+animationDirection+'In') 
 
\t \t \t \t \t .off('animationend.homepage-area-click webkitAnimationEnd.homepage-area-click');; 
 
\t \t \t \t tabsSel.off('click'+generalEvtAffix+'.clicked'); 
 
\t \t \t }); 
 
\t }); 
 
\t });
.cont{ 
 
\t position:absolute; 
 
\t top:0; 
 
\t right:0; 
 
\t bottom:0; 
 
\t left:0; 
 
\t z-index:1; 
 
\t overflow:hidden; 
 
\t 
 
\t -webkit-perspective:1000px; 
 
\t -moz-perspective:1000px; 
 
\t perspective:1000px; 
 
\t -webkit-transform-style:preserve-3d; 
 
\t -moz-transform-style:preserve-3d; 
 
\t transform-style:preserve-3d; 
 
} 
 
@-moz-document url-prefix(){ 
 
    .cont{ 
 
    perspective:100vw; 
 
    } 
 
} 
 
.background.active{ 
 
\t visibility:visible; 
 
\t z-index:1; 
 
} 
 
.background{ 
 
\t position:absolute; 
 
\t top:50px; 
 
\t right:50px; 
 
\t bottom:50px; 
 
\t left:50px; 
 
    z-index:10; 
 
\t 
 
    \t -webkit-backface-visibility: hidden; 
 
\t -moz-backface-visibility: hidden; 
 
\t backface-visibility: hidden; 
 
    -webkit-transform: translate3d(0, 0, 0); 
 
    -moz-transform: translate3d(0, 0, 0); 
 
    transform: translate3d(0, 0, 0); 
 
    \t -webkit-transform-style: preserve-3d; 
 
\t -moz-transform-style: preserve-3d; 
 
\t transform-style: preserve-3d; 
 
\t 
 
\t visibility:hidden; 
 
\t overflow:hidden; 
 
\t 
 
\t background-repeat:no-repeat; 
 
\t background-position:center center; 
 
\t background-size:cover; 
 
} 
 
\t .background.cafe{ 
 
\t \t background-color:#987071; 
 
    } 
 
    .background.club{ 
 
\t \t background-color:#a3367f 
 
\t } 
 
\t .background.fitness{ 
 
\t \t background-color:#79728b; 
 
\t } 
 
\t .background.lady{ 
 
\t \t background-color:#a6160e; 
 
\t } 
 
\t .background.resto{ 
 
\t \t background-color:#712912; 
 
\t } 
 
/* Классы анимации фона типа "Room" */ 
 
\t .rotateRoomLeftOut { 
 
\t \t -webkit-transform-origin: 100% 50%; 
 
\t \t -webkit-animation: rotateRoomLeftOut 4s both ease; 
 
\t \t -moz-transform-origin: 100% 50%; 
 
\t \t -moz-animation: rotateRoomLeftOut 4s both ease; 
 
\t \t transform-origin: 100% 50%; 
 
\t \t animation: rotateRoomLeftOut 4s both ease; 
 
\t } 
 
\t .rotateRoomLeftIn { 
 
\t \t -webkit-transform-origin: 0% 50%; 
 
\t \t -webkit-animation: rotateRoomLeftIn 4s both ease; 
 
\t \t -moz-transform-origin: 0% 50%; 
 
\t \t -moz-animation: rotateRoomLeftIn 4s both ease; 
 
\t \t transform-origin: 0% 50%; 
 
\t \t animation: rotateRoomLeftIn 4s both ease; 
 
\t } 
 
/* Описание анимаций */ 
 

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

 
\t @-webkit-keyframes rotateRoomLeftIn { 
 
\t \t from { opacity: .3; -webkit-transform: translateX(100%) rotateY(-90deg); } 
 
\t } 
 
\t @-moz-keyframes rotateRoomLeftIn { 
 
\t \t from { opacity: .3; -moz-transform: translateX(100%) rotateY(-90deg); } 
 
\t } 
 
\t @keyframes rotateRoomLeftIn { 
 
\t \t from { opacity: .3; transform: translateX(100%) rotateY(-90deg); } 
 
\t } 
 
.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"> 
 
\t \t <div id="bg-club" class="background club"></div> 
 
\t \t <div id="bg-cafe" class="background cafe active"></div> 
 
\t \t <div id="bg-fitness" class="background fitness"></div> 
 
\t \t <div id="bg-resto" class="background resto"></div> 
 
\t \t <div id="bg-lady" class="background lady"></div> 
 
\t </div> 
 

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

ancora in attesa per una ragione alla base di questo comportamento.

+0

@JohanVdR, scusa, ma hai cercato nei miei esempi di codice? Le transizioni non hanno bisogno di fingere di essere 3D - sono già * sono * 3D. Il 'backface-visibility' è già stato nascosto (e l'ho provato anche sull'elemento genitore, senza alcun effetto). – bonflash

+0

Forse aggiungi più fotogrammi chiave. http://webdesign.tutsplus.com/tutorials/css3-animations-the-hiccups-and-bugs-youll-want-to-avoid--webdesign-4867 – JohanVdR

+1

Originariamente pensavo che stavate parlando della mancanza di antialias lungo il bordo superiore del tuo violino, ma in realtà stai vedendo pannelli tremolanti o in via di estinzione, vero? Sul mio sistema (ultima Nightly, Yosemite public preview 2) sembra a posto (a parte l'aliasing sopra menzionato). È ancora un problema per te? Che GPU stai correndo e quali sono i tuoi driver aggiornati? –

risposta

0

Credo che il motivo per cui il tremolio sia dovuto al fatto che Mozilla rileva l'oggetto come non visibile. se la tua prospettiva è 1000px, e qualcosa con una larghezza di 1100px ruota, quindi il bordo dell'elemento passerà dietro di te e fuori dalla vista, che mozilla può determinare come "non eseguire il rendering"

l'unica soluzione che posso offrire una visione coerente è di impostare la prospettiva su qualcosa come 100vw per assicurarsi che la tua prospettiva sia sempre lontana dallo schermo.

Problemi correlati