2010-06-04 17 views
19

Tengo un funcionamiento de demostración muy simple que usa transformaciones y transiciones de Webkit para un desplazamiento horizontal suave entre 'paneles' (divs).Cómo reparar el parpadeo al usar transformaciones y transiciones de Webkit

La razón por la que quiero ir por esta ruta en comparación con un sistema basado en Javascript es que es para el iPad y el rendimiento de Javascript es bastante pobre, pero las transformaciones de css y las transiciones son suaves como la seda. Lamentablemente, estoy obteniendo una gran cantidad de parpadeo en el iPad con mi demostración.

Se puede ver the demo here

que necesitará safari o e iPad para verlo en acción. Nunca he visto que esto ocurra en ninguno de los demos de transformaciones y transiciones, así que espero que esto sea reparable.

De todos modos aquí está el código que impulsa la cosa ....

El HTML se parece a esto.

<html> 
    <head> 
     <title>Swipe Demo</title> 
     <link href="test.css" rel="stylesheet" /> 
     <link href="styles.css" rel="stylesheet" /> 
     <script type="text/javascript" src="jquery.js"></script> 
     <script type="text/javascript" src="functions.js"></script> 
     <script type="text/javascript" src="swiping.js"></script> 
    </head> 
    <body> 


    <div id="wrapper"> 
     <div class='panel one'> 
      <h1>This is panel 1</h1> 
     </div> 

     <div class='panel two'> 
      <h1>This is panel 2</h1> 
     </div> 

     <div class='panel three'> 
      <h1>This is panel 3</h1> 
     </div> 

     <div class='panel four'> 
      <h1>This is panel 4</h1> 
     </div> 
    </div> 

    </body> 
</html> 

La CSS tiene este aspecto

body, 
    html 
     { 
      padding: 0; 
      margin: 0; 
      background: #000; 
     } 

    #wrapper 
     { 
      width: 10000px; 
      -webkit-transform: translateX(0px); 
     } 

    .panel 
     { 
      width: 1024px; 
      height: 300px; 
      background: #fff; 
      display: block; 
      float: left; 
      position: relative; 
     } 

y el código JavaScript se parece a esto

// Mouse/iPad Touch 
var touchSupport = (typeof Touch == "object"), 
touchstart = touchSupport ? 'touchstart' : 'mousedown', 
touchmove = touchSupport ? 'touchmove' : 'mousemove', 
touchend  = touchSupport ? 'touchend' : 'mouseup'; 

$(document).ready(function(){ 

    // set top and left to zero 
    $("#wrapper").css("top", 0); 
    $("#wrapper").css("left", 0); 

    // get total number of panels 
    var panelTotal; 
    $(".panel").each(function(){ panelTotal += 1 }); 

    // Touch Start 
    // ------------------------------------------------------------------------------------------ 

    var touchStartX; 
    var touchStartY; 
    var currentX; 
    var currentY; 
    var shouldMove = false; 
    document.addEventListener(touchstart, swipeStart, false); 
    function swipeStart(event){ 

     touch = realEventType(event); 

     touchStartX = touch.pageX; 
     touchStartY = touch.pageY; 
     var pos = $("#wrapper").position(); 
     currentX = parseInt(pos.left); 
     currentY = parseInt(pos.top); 

     shouldMove = true; 

    } 

    // Touch Move 
    // ------------------------------------------------------------------------------------------ 

    var touchMoveX; 
    var touchMoveY; 
    var distanceX; 
    var distanceY; 
    document.addEventListener(touchmove, swipeMove, false); 
    function swipeMove(event){ 
     if(shouldMove){ 
      touch = realEventType(event); 
      event.preventDefault(); 

      touchMoveX = touch.pageX; 
      touchMoveY = touch.pageY; 

      distanceX = touchMoveX - touchStartX; 
      distanceY = touchMoveY - touchStartY;  
      movePanels(distanceX); 

     } 
    } 

    function movePanels(distance){ 
     newX = currentX + (distance/4);  
     $("#wrapper").css("left", newX); 
    } 


    // Touch End 
    // ------------------------------------------------------------------------------------------ 

    var cutOff = 100; 
    var panelIndex = 0; 
    document.addEventListener(touchend, swipeEnd, false); 
    function swipeEnd(event){ 

     touch = (touchSupport) ? event.changedTouches[0] : event; 

     var touchEndX = touch.pageX; 
     var touchEndY = touch.pageY; 

     updatePanelIndex(distanceX); 

     gotToPanel(); 

     shouldMove = false; 

    } 

    // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 

    function updatePanelIndex(distance){ 

     if(distanceX > cutOff) 
      panelIndex -= 1; 

     if(distanceX < (cutOff * -1)){ 
      panelIndex += 1; 
     } 

     if(panelIndex < 0){ 
      panelIndex = 0; 
     } 

     if(panelIndex >= panelTotal) 
      panelIndex = panelTotal -1; 

      console.log(panelIndex); 

    } 

    // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 

    function gotToPanel(){ 

     var panelPos = getTotalWidthOfElement($(".panel")) * panelIndex * -1; 

     $("#wrapper").css("-webkit-transition-property", "translateX"); 
     $("#wrapper").css("-webkit-transition-duration", "1s"); 
     $("#wrapper").css("-webkit-transform", "translateX("+panelPos+"px)"); 

    } 

}); 

function realEventType(event){ 
    e = (touchSupport) ? event.targetTouches[0] : event; 
    return e; 
} 

Respuesta

8

Trate de usar translate3d en lugar de translateX. Parece que solo translate3d es hardware acelerado en iPad 3.2.

5

Como se mencionó anteriormente, es mejor utilizar Translate3d debido a la aceleración del hardware que hace que las transiciones sean más fluidas.

Sin embargo, el parpadeo se produce cuando el div que se está animando es más grande que la pantalla. Por lo tanto, si usted tiene un área que se suma a anchos de 3,5 pantalla que desee hacer la transición horizontal, debe ser dividido en 4 divs como esto

[1] [2] [3] [. 5]

Ninguno de los divs debe exceder la altura o el ancho de la pantalla.

Disculpa las tardas con la publicación de esta respuesta. Me había olvidado por completo hasta que recibí un aviso de "pregunta popular".

+0

gigantesca - Estoy corriendo en el mismo problema, pero no estoy seguro de entender esta respuesta. Tengo un diseño similar: un área de visualización amplia que es 300% más ancha que la ventana/pantalla, y estoy animando esa área de izquierda a derecha. Si lo divido en 3 divs, cada uno tan ancho como la pantalla, ¿sugieres que anime cada uno individualmente? – mattstuehler

1

Tengo el parpadeo para desaparecer al obtener primero la vista para estar en un estado "3D". Primero tengo todos mis puntos de vista tienen el preservar-3D en. Entonces tengo este código,

MyNamespace.flickerFixer = function(children) { 
children.css({ 
    "-webkitTransform": "translate3D(0px, 0px, 0px)", 
    "-webkit-transition": "1s ease-in-out" 
}); 
} 

Y entonces inicializarlo antes de hacer animaciones webkit:

MyNamespace.flickerFixer($this.parent(".ui-content")); 
45

@gargantaun es correcto, Webkit parpadea si el elemento que desea animar es más grande que la pantalla. Pero hay una solución fácil. Solo agregue:

-webkit-backface-visibility: hidden; 

al elemento y listo!

+0

Tengo curiosidad, ¿cómo resolviste esto? – gargantuan

+0

Lo encontré [aquí] (http://stackoverflow.com/questions/3461441/prevent-flicker-on-webkit-transition-of-webkit-transform), lo necesité para nuestro [sitio web de las compañías] (http: // www. .beenetwork.eu) (espere unos segundos para la animación). –

+9

¡Utilice bajo su propio riesgo! Cuando salió IOS7, nuestra aplicación comenzó a fallar debido a errores de memoria. Normalmente usa 10-15 MB, pero los registros de bloqueo de IOS informaron el uso de ~ 600 MB. Después de algunas excavaciones, resultó que este truco de visibilidad de la cara posterior (que literalmente tenemos un enlace a este subproceso SO de nuestro código fuente) fue la causa, o al menos, eliminarlo hizo que el bloqueo desapareciera. No estoy seguro por qué, y solo era IOS7. Creo que debe haber algún error de fuga de memoria o algo en el tenedor de Apple de Webkit. Muchos desarrolladores se están quejando de que IOS7 Safari se cuelgue en la actualidad. – greim

1

Hoy en día, con iOS8, otra buena solución es aplicar un overflow: hidden a los elementos incriminados (o su contenedor).

0

Basado en @tobiasahlin hablar en WebExpo.

Safari tema parpadeo fijar mejor solución es

transform: translateZ(0); 
Cuestiones relacionadas