11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

J'ai une page avec 3 SVG animés mais je voudrais déclencher l'animation uniquement lorsqu'on scroll et qu'on arrive à l'emplacement du SVG. Sinon, le temps de scroller, toutes les animations des derniers SVG sont terminées...

J'ai créé un codepen avec le code simplifié pour tester mais je n'arrive qu'à déclencher qu'un seul élément de mon premier SVG. Les autres ne se lancent pas...
https://codepen.io/zorel/pen/XqMmqO

J'utilise ce bout de code javascript pour changer l'état de mon animation de "paused" à "running".

// Get the position on the page of the SVG
var svgLocation = document.getElementById("SvgOutils").getBoundingClientRect();
// Scroll offset that triggers animation start.
// In this case it is the bottom of the SVG.
var offsetToTriggerAnimation = svgLocation.y + svgLocation.height;
// Function to handle the scroll event.
// Add an event handler to the document for the "onscroll" event
function scrollAnimTriggerCheck(evt)
{
  var viewBottom = window.scrollY + window.innerHeight;
  if (viewBottom > offsetToTriggerAnimation) {
    // Start the CSS animation by setting the animation-play-state to "running"
    document.querySelector(".Anim").style.animationPlayState = "running";  
    // Remove the event handler so it doesn't trigger again
    document.removeEventListener("scroll", scrollAnimTriggerCheck);
  }
}
// Add an event handler to the document for the "onscroll" event
document.addEventListener("scroll", scrollAnimTriggerCheck);


Je n'arrive pas à comprendre pourquoi mes autres éléments SVG ne se lancent pas...
Auriez-vous une solution?

Merci beaucoup
Modérateur
Et l'eau,

AurelB a écrit :
Je n'arrive pas à comprendre pourquoi mes autres éléments SVG ne se lancent pas...



document.removeEventListener("scroll", scrollAnimTriggerCheck);


Je te laisse réfléchir pour contourner ce problème.
Aussi, c'est une très mauvaise idée de tuer un event Smiley cligne

Je vois également un autre problème :

document.querySelector(".Anim").style.animationPlayState = "running";  

Modifié par niuxe (02 May 2018 - 23:06)
Merci Niuxe pour ta réponse.
Mais je t'avoue que je suis à court de solutions. Je ne suis pas un as du javascript et j'ai du mal à résoudre le problème.
J'ai essayé de ne pas tuer l'event mais ça n'a rien changé (ou alors je ne l'ai pas fait de la bonne façon Smiley cligne ).

Pour le deuxième problème que tu relèves, je ne vois pas... J'avais essayé avec un querySelectorAll mais idem, sans changements.

Pourrais-tu préciser un peu les différents problèmes que tu as soulevé?

Merci encore!
Modérateur
AurelB a écrit :

J'ai essayé de ne pas tuer l'event mais ça n'a rien changé (ou alors je ne l'ai pas fait de la bonne façon Smiley cligne ).

C'est bien que tu essaies de contourner cette contrainte. Mais c'est encore plus pertinant que tu nous dises comment tu essaies afin que l'on puisse corriger ce souci.

AurelB a écrit :

Pour le deuxième problème que tu relèves, je ne vois pas... J'avais essayé avec un querySelectorAll mais idem, sans changements.


l'élément attraper dans un querySelector sera le premier trouvé ! Tu écris :
document.querySelector('.Anim')

Je te donne une petite marche à suivre :
- récupérer dans un tableau tous les éléments animés ou du moins les sections parente. Quand le event.scrollY est supérieur au prochain élément ou tous les éléments inférieurs (position des élements), tu lances ton anim. Smiley cligne

C'est un cas de figure où tu peux le faire très proprement en POO et en utilisant un design pattern approprié.
Modifié par niuxe (03 May 2018 - 19:26)
J'ai essayé une autre solution. Elle fonctionne bien sur la plateforme de test mais dès que j'intègre sur un Wordpress, le SVG ne s'affiche pas...

Est-ce que vous voyez un bug dans le code?
https://jsfiddle.net/aurelien/j5f9qoxx/

$( function () {
    
    var charts = $( ".chart" );
    
    /* FUNCTIONS */
    
    // Return boolean when an element is partially visible on screen
    function isPartialVisible ( element ) {
        var
            viewPortHeight = $( window ).height(), // Viewport Height
            scrollTop = $( window ).scrollTop(), // Scroll Top
            currElementPosY = $( element ).offset().top,
            elementHeight = $( element ).height();
        
        return ( ( currElementPosY + elementHeight + elementHeight ) > scrollTop && currElementPosY < ( viewPortHeight + scrollTop ) );
    }
    
    // Return boolean when an element is wholly visible on screen
    function isWholeVisible( element ) { 
        var 
            viewPortHeight = $( window ).height(), // Viewport Height
            scrollTop = $( window ).scrollTop(), // Scroll Top
            currElementPosY = $( element ).offset().top,
            elementHeight = $( element ).height();
        
        return ( currElementPosY > scrollTop && currElementPosY + elementHeight < ( viewPortHeight + scrollTop ) );
    }
    
    // Animate chart only when you see it
    function animateChartWhenVisible ( chart ) {
        for ( var i = 0, count = chart.length; i < count; i++ ) {
            if ( isWholeVisible( chart[ i ] )  ) {
                $( chart[ i ] ).addClass("mymove-animation");
            }
        }
    }
    
    /* FUNCTIONS END */
    
    // On scroll
    $( window ).scroll( function () {  
        animateChartWhenVisible( charts );
    } );
    
    /* On load */    
    animateChartWhenVisible( charts );
    
} );


Merci!!!