Activar la animación CSS3 cuando el contenido se desplaza a la vista


Tengo un gráfico de barras que se anima con CSS3 y la animación se activa actualmente a medida que se carga la página.

El problema que tengo es que el gráfico de barras dado se coloca fuera de la pantalla debido a que hay mucho contenido antes de él, por lo que para cuando un usuario se desplaza hacia abajo, la animación ya ha terminado.

Estaba buscando formas, ya sea a través de CSS3 o jQuery para activar solo la animación CSS3 en el gráfico de barras cuando el espectador ve el gráfico.

<div>lots of content here, it fills the height of the screen and then some</div>
<div>animating bar chat here</div>

Si te desplazas hacia abajo muy rápido justo después de cargar la página, puedes verla animando.

Aquí está un jsfiddle de mi código. Además, no sé si esto importa, pero tengo varias instancias de este gráfico de barras en la página.

Me he encontrado con un complemento de jQuery llamado waypoint, pero no tuve absolutamente ninguna suerte de hacerlo funcionar.

Si alguien pudiera indicarme en la dirección correcta, sería realmente útil.

Gracias!

Author: Matt Coughlin, 2013-05-02

5 answers

Capturar eventos de desplazamiento

Esto requiere el uso de JavaScript o jQuery para capturar eventos de desplazamiento, comprobando cada vez que se dispara un evento de desplazamiento para ver si el elemento está a la vista.

Una vez que el elemento está a la vista, inicie la animación. En el siguiente código, esto se hace agregando una clase "start" al elemento, que activa la animación.

Demo actualizada

HTML

<div class="bar">
    <div class="level eighty">80%</div>
</div>

CSS

.eighty.start {
    width: 0px;
    background: #aae0aa;
    -webkit-animation: eighty 2s ease-out forwards;
       -moz-animation: eighty 2s ease-out forwards;
        -ms-animation: eighty 2s ease-out forwards;
         -o-animation: eighty 2s ease-out forwards;
            animation: eighty 2s ease-out forwards;
}

JQuery

function isElementInViewport(elem) {
    var $elem = $(elem);

    // Get the scroll position of the page.
    var scrollElem = ((navigator.userAgent.toLowerCase().indexOf('webkit') != -1) ? 'body' : 'html');
    var viewportTop = $(scrollElem).scrollTop();
    var viewportBottom = viewportTop + $(window).height();

    // Get the position of the element on the page.
    var elemTop = Math.round( $elem.offset().top );
    var elemBottom = elemTop + $elem.height();

    return ((elemTop < viewportBottom) && (elemBottom > viewportTop));
}

// Check if it's time to start the animation.
function checkAnimation() {
    var $elem = $('.bar .level');

    // If the animation has already been started
    if ($elem.hasClass('start')) return;

    if (isElementInViewport($elem)) {
        // Start the animation
        $elem.addClass('start');
    }
}

// Capture scroll events
$(window).scroll(function(){
    checkAnimation();
});
 61
Author: Matt Coughlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-01 23:15:01

A veces necesita que la animación siempre ocurra cuando el elemento está en la ventana. Si este es tu caso, modifiqué ligeramente el código Matt jsfiddle para reflejar esto.

[1]} jQuery
// Check if it's time to start the animation.
function checkAnimation() {
    var $elem = $('.bar .level');

    if (isElementInViewport($elem)) {
        // Start the animation
        $elem.addClass('start');
    } else {
        $elem.removeClass('start');
    }
}
 15
Author: Bogdan Gersak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-27 21:20:54

Para activar una animación CSS, se debe agregar una clase al elemento cuando se haga visible. Como otras respuestas han indicado, JS es necesario para esto y Waypoints es un script JS que se puede utilizar.

Waypoints es la forma más fácil de activar una función cuando se desplaza a elemento.

Hasta Waypoints versión 2, este solía ser un plugin jquery relativamente simple. En la versión 3 y superior (esta guía versión 3.1.1) varias características tienen presentado. Para lograr lo anterior con esto, se puede usar el 'atajo inview' del script:

  1. Descargue y agregue los archivos de script desde este enlace o desde Github (la versión 3 no está aún disponible a través de CDNJS, aunque RawGit siempre es una opción también).

  2. Agregue el script a su HTML como de costumbre.

    <script src="/path/to/lib/jquery.waypoints.min.js"></script>
    <script src="/path/to/shortcuts/inview.min.js"></script>
    
  3. Añadir el siguiente código JS, sustituyendo #myelement por el selector de jQuery de elemento HTML apropiado:

    $(window).load(function () {
        var in_view = new Waypoint.Inview({
            element: $('#myelement')[0],
            enter: function() {
                $('#myelement').addClass('start');
            },
            exit: function() {  // optionally
                $('#myelement').removeClass('start');
            }
        });
    });
    

Usamos $(window).load()para las razones explicadas aquí.

Actualizado el violín de Matt aquí.

 9
Author: Wtower,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:25

Además de estas respuestas, por favor considere estos puntos :

1-Comprobar el elemento en vista tiene muchas consideraciones :
¿Cómo saber si un elemento DOM es visible en la ventana actual?

2-Si alguien quería tener más control sobre la animación (por ejemplo, establecer "el tipo de animación" y "start delay") aquí hay un buen artículo al respecto :
http://blog.webbb.be/trigger-css-animation-scroll /

3-Y también parece esa llamada a addClass sin demora (usando setTimeout ) no es efectiva.

 0
Author: Spongebob Comrade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:32
CSS FOR TRIGGER : 
.trigger{
  width: 100px;
  height: 2px;
  position: fixed;
  top: 20%;
  left: 0;
  background: red;
  opacity: 0;
  z-index: -1;
}
<script>
$('body').append('<div class="trigger js-trigger"></div>');

        $(document).scroll(function () {


           $('YOUR SECTIONS NAME').each(function () {

               let $this = $(this);

               if($this.offset().top <= $('.js-trigger').offset().top) {

                   if (!$this.hasClass('CLASS NAME FOR CHECK ACTIVE SECTION')) {
                       $this
                           .addClass('currSec')
                           .siblings()
                           .removeClass('currSec');

                   }
               }

           });

        });
</script>
 0
Author: Sanya Kravchuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-06 09:20:23