¡Necesitaremos una API más grande!

 

 

 

  • Anuncie en la revista Smashing
  • ¡Registro!

  • Índice
    1. ¡Animamos algo!
      1. UsandorequestAnimationFrame
      2. Usando transiciones CSS
      3. Ingrese animaciones CSS
      4. Animaciones web, ¡sálvanos de este lío!
      5. Otras lecturas

    A todo el mundo le gustan las cosas que circulan por la Web, ¿verdad? Recuerda cómo lloraste lágrimas de alegría cuando usaste por primera vez.? Sí. Casi sollocé hasta sacarme toda el agua del cuerpo mientras contemplaba “EL SITIO WEB COOL DE JAKE” moviéndose de un lado a otro en letras serif mayúsculas. Por supuesto, hoy en día somos más maduros como industria.

     

    Hemos aprendido que los usuarios no quieren que los sitios web parezcan una consola CSI que sufre una crisis personal ; en cambio, optamos por transiciones suaves que mejoren la experiencia, en lugar de ser la experiencia en sí. En términos de API de animación, hemos sido mal atendidos, lo que nos ha obligado a hackear temporizadores que en realidad no fueron creados para la animación. Las cosas han ido mejorando constantemente en esa área, pero la nueva especificación de animación web parece destinada a cambiar mucho las cosas.

    Entonces, ¿por qué necesitamos una nueva especificación de animación? ¿No tenemos ya suficientes formas de animar las cosas?

    Optimizando la forma de hacer que las cosas se muevan. ( Fuente de imagen )

    ¡Animamos algo!

    Imaginemos que quisiéramos animar algo horizontalmente desde una posición izquierda a otra, durante tres segundos, y luego hacer algo al finalizar. Podemos hacer esto sin JavaScript, usando animaciones CSS, pero si las posiciones inicial y final se determinan mediante programación, entonces necesitaremos algo que podamos controlar desde un script.

    UsandorequestAnimationFrame

    Si está realizando actualizaciones visuales con JavaScript, entonces debería utilizar requestAnimationFrame. Se sincroniza con las actualizaciones de la pantalla real, lo que le brinda el mayor tiempo posible para tener todo listo para el renderizado. Si el navegador está en una pantalla de 60 Hz (la mayoría lo está) y sus cuadros se pueden construir en menos de 60 segundos, entonces obtendrá 60 cuadros por segundo (FPS). requestAnimationFramele impide crear marcos que no tienen tiempo de mostrarse. La sincronización con la frecuencia de la pantalla es importante; 30 FPS parecen más fluidos que 40 FPS porque 40 no se dividen en los 60 Hz nativos de la pantalla. HTML5 Rocks tiene un excelente artículo sobre la sincronización con la pantalla .

     

    Desafortunadamente, jQuery usasetInterval , que no es tan sencillo como requestAnimationFrame. requestAnimationFrameno se activa mientras la pestaña o ventana no está visible, lo cual es A Good Thing™ . Desafortunadamente, esto ha creado incompatibilidad con sitios web que dependen del setIntervalcomportamiento menos óptimo de continuar ejecutándose en segundo plano. Puede optar por participar requestAnimationFramea través de un complemento . Vaya y agréguelo a todas sus páginas usando la animación jQuery ahora; prometo esperarlo; solo asegúrese de que el cambio de pestañas no interrumpa sus animaciones.

    De todos modos, basta de charlar . Aquí hay una animación simple que usaraf , moviendo un cuadro horizontalmente de 250pxa 500px. Tenga en cuenta que el cuadro comienza en 0px, por lo que hay un salto hasta 250pxel momento en que comienza la animación; esto demuestra que podemos iniciar la animación desde un punto distinto de su posición renderizada actual.

    Aquí está el código:

    // On button press…animateLeft(elm, '250px', '500px', function() { console.log("Done!");});// The implementationfunction animateLeft(elm, from, to, done) { // Turn our CSS values into numbers // We're being lazy and assuming they're in px from = parseInt(from, 10); to = parseInt(to, 10); // Work out the amount we need to move the box var diff = to - from; var duration = 3000; var startTime = performance.now(); // Set initial position elm.style.transform = 'translate(' + from + 'px, 0)'; function frame(time) { // How long has the animation been running? var animTime = time - startTime; // Are we done? if (animTime = duration) { // It's likely that the last rendered position wasn't the // final position, so we set it here. elm.style.transform = 'translate(' + to + 'px, 0)'; done(); } else { // What position should the box be in? var position = from + (animTime / duration * diff); elm.style.transform = 'translate(' + position + 'px, 0)'; // Request our next frame requestAnimationFrame(frame); } } // request our first frame requestAnimationFrame(frame);}

    Lo anterior es el código ideal según las especificaciones. En el ejemplo de trabajo, tuve que lidiar con los prefijos de proveedores en requestAnimationFramey transform. Estamos animando usando transformy translate, en lugar de left, porque permiten el posicionamiento de subpíxeles y, por lo tanto, una animación más fluida , una de las ventajas que Flash tuvo sobre HTML durante tanto tiempo.

    Este es un trozo de código bastante grande y apestoso para simplemente animar algo, y se volvería mucho más grande si manejáramos diferentes unidades CSS y suavización. Por supuesto, puedes guardar todos los bits complicados en una biblioteca y crear una API más simple. Aquí está el desglose cuadro por cuadro:

     

    Esta es la vista de la línea de tiempo de Chrome Developer Tools mientras se ejecuta la animación. Cada cuadro ejecuta algo de JavaScript, recalcula el estilo y el diseño, pinta el cuadro y luego lo envía a la GPU, que lo compone en la página. El tiempo de dibujo aumenta varias veces, lo que provoca una sacudida en la animación. Esto se debe a retrasos en la interacción con la GPU (los picos grises) o retrasos causados ​​por otro JavaScript (los picos amarillos).

    Esto resalta un cuello de botella en el rendimiento de la animación basada en JavaScript:

    Aquí, otro fragmento de JavaScript hace algunas cosas y tarda 250 milisegundos en hacerlo. Mientras esto sucede, nuestra animación no puede moverse. En el mundo real, esto podría ser un botón de una red social que se activa y hace algo lento , o podría ser algún script propio activado por la interacción de un usuario. En el ejemplo anterior, creé un botón que realiza un whilebucle durante 250 milisegundos (estoy bastante seguro de que este código está en todos los botones de redes sociales). Si lo presiona durante la animación, bloqueará la animación y se verá desagradable.

    Recientemente elogié la requestAnimationFrameanimación del lienzo , entonces, ¿por qué lo odio ahora? Las animaciones basadas en JavaScript no son una mala práctica: te brindan control total cuadro por cuadro y píxel por píxel cuando se combinan canvas, pero regresar a JavaScript 60 veces por segundo es excesivo para las animaciones DOM que tienen un inicio y un final definidos. Idealmente, queremos contarle al navegador todo sobre nuestra animación y dejar que haga lo suyo , mientras nosotros seguimos con otra cosa.

    Por supuesto, ya tenemos esto.

    Usando transiciones CSS

    .whatever { transform: translate(250px, 0); transition: transform 3s linear;}.whatever:hover { transform: translate(500px, 0);}

    Las transiciones y animaciones CSS permiten al navegador realizar todo tipo de optimizaciones porque conoce el punto final de la animación. JavaScript no los bloquea en algunas plataformas, como Chrome para Android y Chrome de escritorio con la composición por subprocesos habilitada about:flags(espere que la composición por subprocesos llegue a más navegadores).

    ¡Vamos a escribirlo!

    function animateLeft(elm, from, to, done) { // Set initial position elm.style.transform = 'translate(' + from + ', 0)'; // Define the transition type elm.style.transition = 'all 3s linear'; function transitionEnd(event) { // Beware of bubbled events if (event.target != elm) { return; } // Clear the transition elm.style.transition = ’; // We don't want that listener firing for future anims elm.removeEventListener('transitionend', transitionEnd); done(); } // Listen for end of transition elm.addEventListener('transitionend', transitionEnd); // start the transition elm.style.transform = 'translate(' + to + ', 0)';}

    Aquí hay un ejemplo en vivo . Es mucho más simple que nuestro rafejemplo, pero se ha introducido un error. Se fromignora; la animación comienza desde la posición actual del elemento, aunque la hayamos configurado explícitamente en otra cosa. ¿Por qué? El Blog de la ginebra y el whisky on the rocks

     

    // Set initial positionelm.style.transform = 'translate(' + from + ', 0)';// Define the transition typeelm.style.transition = 'all 3s linear';// …and later…// Start the transitionelm.style.transform = 'translate(' + to + ', 0)';

    Cambiar las propiedades del styleobjeto no cambia el estilo calculado del elemento. El estilo se calcula solo cuando el navegador necesita saber el impacto que esos estilos tendrán en la página (por ejemplo, cuando es necesario dibujar el elemento). No es necesario dibujar el elemento entre las dos asignaciones elm.style.transform, por lo que se ignora la primera asignación.

    Por supuesto, podemos hackearlo :

    // Set initial positionelm.style.transform = 'translate(' + from + ', 0)';// Abracadabra!elm.offsetWidth;// Define the transition typeelm.style.transition = 'all 3s linear';// …and later…// start the transitionelm.style.transform = 'translate(' + to + ', 0)';

    offsetWidthdevuelve el ancho representado de un elemento, incluido el relleno. Para calcular esto, el navegador debe tener en cuenta todos los estilos de la página, incluido el transformque configuramos para la posición inicial. Eso funciona. Mira el ejemplo en vivo .

    El rendimiento es estable a 60 FPS. Y podemos ver que cada cuadro es un compuesto simple; todo el trabajo pesado se transfiere a la GPU.

    Sin embargo, confiar en offsetWidthforzar el elemento a su posición inicial es complicado, y es posible que una versión futura del navegador encuentre una manera de optimizar el reflujo , rompiendo nuestro truco.

    Los reflujos tampoco están exentos de costes:

    Las herramientas de desarrollo nos advierten sobre este uso offsetWidth, porque el navegador calcula un diseño que nunca dibuja. La página de prueba es muy básica, por lo que el costo del diseño es económico, pero las cosas pueden ser muy diferentes en el mundo real.

    Entonces, ¿existe una forma menos complicada y más confiable?

    Ingrese animaciones CSS

    Las animaciones CSS tienen valores de fotogramas clave explícitos. Escribámoslos:

    function animateLeft(elm, from, to, done) { // Create a style element for our animation var style = document.createElement('style'); // Generate a unique name var animName = 'anim' + Date.now() + Math.floor(Math.random() * 10000); // Build the CSS style.textContent = ’ + '@keyframes ' + animName + ' { ' + 'from { ' + 'transform: translate(' + from + ', 0);' + '}' + 'to {' 'transform: translate(' + to + ', 0);' + '}' + '}'; // Add it to the page document.head.appendChild(style); function transitionEnd(event) { // Beware of bubbled events if (event.target != elm) { return; } // Clear the animation elm.style.animation = ’; // Clean up the DOM document.head.removeChild(style); // Retain the final position elm.style.transform = 'translate(' + to + ', 0)'; // We don't want that listener firing for future anims elm.removeEventListener('animationend', transitionEnd); done(); } // Listen for end of transition elm.addEventListener('animationend', transitionEnd); // Start the animation elm.style.animation = animName + ' 3s linear forwards';}

    ¡Puaj! ¿Todo eso sólo para mover algo? Funciona , pero todo ese trabajo DOM es complicado para lo que estamos tratando de lograr. Además, si una animación se cancela a la mitad (por ejemplo, si se cambia el estilo de la animación), animationendno se activará, lo que significa que nuestra donedevolución de llamada no se activará o, peor aún, se activará al final de alguna animación futura no relacionada. . No hay ningún animationcancelevento.

     

    Animaciones web, ¡sálvanos de este lío!

    Aún es temprano para la especificación de animaciones web , pero es bastante emocionante. Aporta una gran cantidad de funciones de sincronización y rendimiento de animación de forma nativa al DOM que las bibliotecas de JavaScript actualmente tienen que abrirse paso.

    La especificación en sí es un poco aterradora. Mi corazón se hundió cuando abrí la página y vi la barra de desplazamiento hacerse cada vez más pequeña. Pero, afortunadamente, la mayor parte son detalles de implementación.

    Así es como escribiríamos el guión de nuestra animación en el nuevo y valiente mundo de la animación web :

    // Set our start positionelm.style.transform = 'translate(250px, 0)';// Animate to the end positionvar anim = elm.animate({ transform: 'translate(500px, 0)'}, 3);// Do something on completionanim.onend = function() { console.log('Done!');};

    Aquí elmhay un HTMLElement. La API es intuitiva, especialmente si has creado animaciones con algo como jQuery.

    Al igual que las animaciones y transiciones CSS, le brinda al navegador la historia completa desde el principio , por lo que obtenemos las mismas optimizaciones sin tener que crear CSS dinámicamente. Web Animations soluciona esto permitiéndonos contarle al navegador la historia completa de lo que vamos a hacer. Luego, el navegador puede activarse y animar las cosas por sí mismo.

    Las animaciones web nos brindan la API de secuencias de comandos para animaciones impulsadas por el navegador que tanto falta. Arriba está el ejemplo "Hola mundo". La especificación incluye facilitación avanzada, animación basada en rutas, paralelización, sincronización, interrupción y adaptación, todo de una manera que el navegador puede aprovechar el terreno de JavaScript y optimizarlo en consecuencia.

    Todavía es muy temprano, así que no deseches tus bibliotecas de animación todavía. Pero si desea experimentar con la nueva API y brindar comentarios, un polyfill está rastreando la especificación en rápida evolución. ¡Tiempos emocionantes!

    Otras lecturas

    • La guía para la animación CSS: principios y ejemplos
    • Transiciones CSS3: ¡Gracias a Dios que tenemos una especificación!
    • El estado de la animación 2014
    • Una introducción a las animaciones de fotogramas clave CSS3

    (al, señor)Explora más en

    • Codificación
    • CSS
    • javascript
    • Animación

    Explorar todos los temas de Smashing Magazine

    • Accesibilidad
    • Mejores prácticas
    • Negocio
    • Carrera
    • Listas de verificación
    • CSS
    • Visualización de datos
    • Diseño
    • Patrones de diseño
    • Sistemas de diseño
    • Comercio electrónico
    • figura
    • Regalos
    • HTML
    • ilustrador
    • Inspiración
    • javascript
    • Móvil
    • Actuación
    • Privacidad
    • Reaccionar
    • Diseño de respuesta
    • Redondeos
    • SEO
    • Tipografía
    • Herramientas
    • interfaz de usuario
    • Usabilidad
    • experiencia de usuario
    • vista
    • Fondos de pantalla
    • Diseño web
    • Flujo de trabajo

    Con un compromiso con contenidos de calidad para la comunidad del diseño.

    Fundada por Vitaly Friedman y Sven Lennartz . 2006-2024 .

    Smashing se ejecuta con orgullo en Netlify , TinaCMS y Swell .

    Fuentes de Latinotype .

    • ✎ Escribe para nosotros
    • Contáctenos
    • Sobre nosotros (pie de imprenta)
    • Política de privacidad
    • Inicio de sesión de membresía
    • Tiempos de entrega
    • Anunciar






    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    ¡Necesitaremos una API más grande!

    ¡Necesitaremos una API más grande!

    Anuncie en la revista Smashing ¡Registro! Índice ¡Animamos algo!

    programar

    es

    https://aprendeprogramando.es/static/images/programar-necesitaremos-una-api-mas-grande-813-0.jpg

    2024-05-20

     

    ¡Necesitaremos una API más grande!
    ¡Necesitaremos una API más grande!

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20