Pregunta

Tengo una secuencia de animación compleja que implica fundidos y transiciones en JavaScript. Durante esta secuencia, que consta de cuatro elementos que cambian a la vez, un setTimeout se utiliza en cada elemento.

Probado en Internet Explorer 9, los trabajos de animación en tiempo real de velocidad (que debería tomar 1.6 segundos y se tomó exactamente 1,6 segundos). Cualquier otro navegador se quedará horriblemente, con tiempos de animación de 4 segundos (Firefox 3 y 4, Chrome, Opera) y algo así como 20 segundos en el IE 8 y siguientes.

¿Cómo puede ir tan rápido IE9, mientras que todos los demás navegadores están atascados en el barro?

Me han tratado de encontrar la manera de combinar los elementos en uno, de manera que uno tiene un setTimeout en un momento dado, pero por desgracia no se ponía de pie a cualquier interferencia (como hacer clic en un enlace diferente para iniciar un nuevo animación antes de la actual ha terminado).

EDIT: Elaborar en respuesta a los comentarios, aquí está el esquema del código:

link.onclick = function() {
    clearTimeout(colourFadeTimeout);
    colourFadeTimeout = setTimeout("colourFade(0);",25);

    clearTimeout(arrowScrollTimeout);
    arrowScrollTimeout = setTimeout("arrowScroll(0);",25);

    clearTimeout(pageFadeOutTimeout);
    pageFadeOutTimeout = setTimeout("pageFadeOut(0);",25);

    clearTimeout(pageFadeInTimeout);
    pageFadeInTimeout = setTimeout("pageFadeIn(0);",25);
}

Cada una de las cuatro funciones progresar el fundido por una trama, a continuación, establecer otro tiempo de espera con el argumento incrementado, hasta el final de la animación.

Se puede ver la página en http://adamhaskell.net/cw/index.html (Nombre de usuario: knockknock; Contraseña: goaway) (tiene sonido y la música, que puede ser desactivado, pero ten cuidado!) - mi JavaScript es muy desordenado ya que no he realmente organizada de forma adecuada, pero se comenta un poco por lo espero que usted puede ver lo que la idea general es.

¿Fue útil?

Solución

Hay varias cosas:

  1. Su tiempo de espera es de 25 ms. Esto se traduce a 40fps, que es una muy alta tasa de fotogramas para tratar de lograr a través de JavaScript. Especialmente para las cosas que implican la manipulación del DOM que pueden desencadenar los reflujos. Aumentar a 50 o 15 fps 60. debería ser más que suficiente líquido para el tipo de animación que está haciendo. Usted no está tratando de vídeos de presentación aquí, basta con mover cosas alrededor de la página.

  2. No utilice cadenas como el primer parámetro a setTimeout(). Especialmente si se preocupan por el rendimiento. Eso obligará javascript para volver a compilar la cadena cada fotograma de la animación. Utilizar una función en su lugar. Si usted necesita para pasar un uso argumento de una función anónima para envolver la función que desea ejecutar:

    setTimeout(function(){
        pageFadeIn(0)
    },50);
    

    esto sólo se compilan una vez cuando se carga el guión.

  3. Como se ha mencionado por Ben, es más barato utilizar un solo setTimeout para programar las funciones. Por lo demás, la claridad del código puede mejorar mediante el uso de setInterval lugar (o puede que no, depende de su estilo de codificación).


respuesta adicional:

Programación de animación Javascript tiene que ver con la optimización y el compromiso. Es posible una gran cantidad de cosas animadas de la página con poco lento hacia abajo pero hay que saber cómo hacer las cosas bien y decidir qué sacrificar. Como un ejemplo de lo mucho que se puede animar a la vez es un juego de estrategia en tiempo real de demostración que escribí hace un par de años.

Entre las cosas que hice para optimizar el juego son:

  1. Los soldados a pie se compone de sólo dos fotogramas de la animación y simplemente alternar entre las dos imágenes. Pero el efecto es muy convincente, no obstante. No es necesario animación perfecta, sólo uno que se ve convincente.

  2. Yo uso una sola setInterval para todo. Es más barato CPU-sabia y más fácil de manejar. Acaba de decidir sobre una frecuencia de cuadros de base y luego programar para la animación diferente para comenzar en diferentes momentos.

Otros consejos

Bueno, eso es un montón de javascript (a pesar de la "cuádruple de la dosis de genialidad":)

Usted está disparando una gran cantidad de secuencia de setTimeout, no estoy seguro de lo bien que se han optimizado los motores de JS para este .. particularmente IE <= 8

Ok, tal vez sólo una sugerencia áspera ... tal vez podría escribir un pequeño motor de temporización.

Mantener un objeto global que almacena su ejecución actual cronometrados eventos con la función a ejecutar, y el retraso ...

A continuación, tiene un único controlador de setTimeout que cheque contra ese objeto global, y disminuye el retardo en cada iteración y llama a la función cuando el retraso se convierte <0

evento global que haría ve algo así:

var events = {

        fade1 : {
            fn : func_name,
            delay : 25,
            params : {}
        }

        fadeArrow : {
            fn : func_name,
            delay : 500,
            params : {}
        }

        slideArrow : {
            fn : func_name,
            delay : 500,
            params : {
                arrow:some_value
            }
        }

    }

a continuación, crear una función para recorrer estos términos en un intervalo (tal vez 10 o 20 ms) y disminuir el retraso hasta que completen y disparan la función con params como un paramer a la función (marque Function.call para eso).

Una vez abajo, el fuego SetTimeOut de nuevo con el mismo retraso ..

Para cancelar un evento simplemente desarmar la propiedad de la lista de eventos ..

Construir unas pocas método para añadir / quitar la cola de eventos, params de actualización y así sucesivamente ..

Esto reduciría todo a un solo controlador de tiempo de espera ..

(sólo una idea)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top