IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Animer une rotation


Sujet :

JavaScript

  1. #1
    Membre régulier
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juillet 2019
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2019
    Messages : 134
    Points : 75
    Points
    75
    Par défaut Animer une rotation
    Bonjour à tous,
    je suis sur une animation d'une roue en rotation en boucle (linear infinite).
    Je n'ai aucun problème pour la faire tourner et l'arrêter, seulement je souhaite qu'elle commence à ralentir avant qu'elle s'arrête. Elle doit ralentir progressivement sur le passage d'un BOOLEAN de "0" à "1" jusqu'à ce qu'elle s'arrête complètement.

    J'ai essayé de créer un "keyFrame" (100% {transform: rotate(360deg);} qui est attribué dans une fonction avec un "documentgetElementById().style.animation" en déclarant une variable "vitesse = 3" qui sera décrémenté jusqu'à "0" lorsque j'appuie sur un bouton (le bouton est censé mettre le BOOLEAN à 1 et déclencher le ralentissement jusqu'à l'arrêt)

    Cela ne marche pas : la roue tourne toujours. J'ai joué sur la propriété "iteration" pour qu'elle ne passe en "infinite" que si la variable "vitesse" est supérieure à "0".
    Mai cela ne fonctionne pas : la roue reprend sa rotation par à-coup.
    Quelqu'un peut m'aider, svp ?

  2. #2
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 395
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 395
    Points : 15 756
    Points
    15 756
    Par défaut
    il vaut mieux créer une nouvelle discussion pour votre nouvelle question.
    d'après ce que vous avez indiqué, j'ai du mal à voir si c'est plutot un souci de javascript ou de css donc postez dans un de ces forums et un modérateur pourra toujours la déplacer si c'est utile.
    et dernière chose, ajoutez le code de ce que vous essayez de faire pour qu'on puisse le tester.

  3. #3
    Membre régulier
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juillet 2019
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2019
    Messages : 134
    Points : 75
    Points
    75
    Par défaut
    Bonjour Mathieu
    Justement, c'est une difficulté au niveau JS, mais chaque fois que je clique pour créer une discussion JS, je reçois un message me disant "désolé. Le forum est fermé. Vous ne pouvez pas créer une nouvelle discussion" et ce depuis un moment. Je ne comprends pas !!!!
    Le seul moyen d'envoyer ma question était que je reprenne la dernière discussion. Je ne comprends pas.
    Merci encore

  4. #4
    Membre éclairé
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juin 2014
    Messages
    427
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Webdesigner
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Juin 2014
    Messages : 427
    Points : 857
    Points
    857
    Par défaut
    Bonjour.

    Les transitions CSS font cela très bien !

  5. #5
    Membre régulier
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juillet 2019
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2019
    Messages : 134
    Points : 75
    Points
    75
    Par défaut
    Merci beaucoup domi65
    j'ai essayé de le faire avec une simple rotation @keyframe: mon_keyframe; cela fonctionne bien.

    Seulement, lorsque je l'ai essayé avec une rotation linéaire et infinie @keyframe: mon_keyframe 5s linear infinite; cela ne fonctionne pas.

    Encore moins avec document.getElementById("mon_element").style.animationPlayState="paused";.
    en ajoutant document.getElementById("mon_element").style.transition="all 4s";

  6. #6
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    En js avec un svg (biblio snap svg -> sans code de ta part, j'avais la flemme de faire la roue avec canvas...)
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    <!DOCTYPE html>
    <html lang="fr"></html>
    <head>
         <meta charset="UTF-8">
         <meta name="viewport" content="width=device-width, initial-scale=1.0">
         <title>roue</title>
        <style>
        html, body {margin: 0;padding: 0;background: rgb(7, 169, 234);}
         
         #stage{
              display:block;
              background :white;
              margin: 15vh auto 0 auto;
              border:2px solid black; 
        }
        input{
            display: block;
            margin: 8vh auto 0 auto;
        }
        </style>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script>
    </head>
    <body>
        <svg width="60vh" height="60vh" viewBox="0 0 400 400"  id="stage"></svg>
        <input type="button" value="Arrêter progressivement">
    <script>
       let f=40,
           omega=2*Math.PI*f,
           dec_f=.1,
           arret=false;
       const s = Snap("#stage");
       const roue=s.g(
         s.circle(200,200,150).attr({
          'stroke-width' :3,
          stroke: 'black',
          fill: "none"
        }),s.g(
              s.line(50,200,350,200),  
              s.line(200,50,200,350)).attr({
            'stroke-width' :2,
            stroke: 'blue'
          })
        );
        
        let theta=0,
            dtheta,
            dt=.01; //10 ms  fictif ici il faudrait le faire calculer à chaque frame avec Date()...
        const deuxPi=2*Math.PI;
     
    function anime(){ 
     roue.transform(`r${theta}`);
    }
     
    function arret_progressif(){
        if  (arret) {
             f-=dec_f;
             omega=deuxPi*f
        } else return;
    }
     
    function callback(){
        arret_progressif();
        dtheta=omega*dt;
        theta+=dtheta;
        anime();
        omega>0 ? window.requestAnimationFrame(callback) : window.cancelAnimationFrame(callback);   
    }
    window.requestAnimationFrame(callback);
    const button=document.querySelector("input");
    button.addEventListener('click',()=>{arret=true});
    </script>
    </body>
    </html>

  7. #7
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    J'ajoute une version sans canvas ni bibliothèque :
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    <!DOCTYPE html>
    <html lang="fr">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Roue</title>
        <style>
            html, body {
                margin: 0;
                padding: 0;
                background: rgb(7, 169, 234);
            }
            #content{
             background-color: white;
             border: 2px solid black;
             width: 60vh;
             height: 60vh;
             margin: 10vh auto 0 auto;
            }
            #roue{
                border: 4px solid black;
                border-radius: 50vh;
                width:50vh;
                height:50vh;
                margin: 5vh auto 0 auto;
                background-color:white ;
            }
            #rayon_v{
                width:.5vh;
                height:50vh;
                background-color: blue;
                margin:auto;
            }
     
            #rayon_h{
                width:50vh;
                height:.5vh;
                background-color: blue;
                margin:-25vh auto 0 auto;
            }
            input{
              display: block;
              margin: 8vh auto 0 auto;
            }
        </style>
    </head>
    <body>
        <div id="content">
         <div id="roue">
            <div id="rayon_v"></div>
            <div id="rayon_h"></div>
         </div>
       </div>
     
       <input type="button" value="Arrêter progressivement">
     
        <script>
            const roue=document.querySelector("#roue");
            let f=1,//1 tr/s
                omega=2*Math.PI*f,
                dec_f=.005,
                arret=false,
                theta=0,
                dtheta,
                dt=.010; //10 ms  fictif ici il faudrait le faire calculer à chaque frame avec Date()...
            const deuxPi=2*Math.PI;
     
            function anime(){ 
             roue.style.transform = 'rotate(' +theta +'rad)';
            }
            
            function arret_progressif(){
                if  (arret){
                    f-=dec_f;
                    omega=deuxPi*f
                } else return;
            }
            
            function callback(){
                arret_progressif();
                dtheta=omega*dt;
                theta+=dtheta;
                anime();
                omega>0 ? window.requestAnimationFrame(callback) : window.cancelAnimationFrame(callback);   
            }
            window.requestAnimationFrame(callback);
            const button=document.querySelector("input");
            button.addEventListener('click',()=>{arret=true});
        </script>
    </body>
    </html>

  8. #8
    Membre régulier
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juillet 2019
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2019
    Messages : 134
    Points : 75
    Points
    75
    Par défaut
    Merci beaucoup Archimède
    J'ai oublié de préciser que la roue est une image, mais j'apprécie le travail que tu as fait avec le convas et sans (je suis admiratif !!!!)
    Je suis en train d'adapter le script de "arret_progressif" à mon code: j'ai remplacé "roue" dans le "querySelector" par "image_roue" (const roue=document.querySelector("#image_roue");) et attribué le "addEventListener" à ""mon_bouton_arret" (document.getElementById("mon_bouton_arret").addEventListener('click',()=>{arret=true})

    J'ai fait un essai; ça a l'air de pouvoir fonctionner (je garde espoir )

    Merci encore et pardon du dérangement

  9. #9
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    Si tu as besoin d'aide, je peux te le faire avec une image...( je n'en avais pas avec un fond transparent...)

  10. #10
    Membre régulier
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juillet 2019
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2019
    Messages : 134
    Points : 75
    Points
    75
    Par défaut
    tu es vraiment très aimable, Archmède...
    L'essai d'adaptation que j'ai réalisé a l'air de fonctionner, seulement je n'arrive pas à relancer la rotation avec le bouton "lance_rotation_roue" (car je signale qu'en plus du bouton d'arrêt qui met le BOOLEAN "arret" à "true", l'animation de la rotation est lancée (ou relancée) elle aussi par un bouton de "marche" qui met le "BOOLEAN" à "false" (ou un BOOLEAN "marche" à "true"))
    Comme je suis dans l'urgence, je te prie de m'envoyer un exemple avec une image, en te remerciant par avance.

  11. #11
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    Re, sur ton bouton relancer, il faut mettre arret à false, réinitialiser f (ainsi ajouter aussi: omega=2*Math.PI*f) et theta, et refaire un
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
     window.requestAnimationFrame(callback);
    .
    Après je te refais ça avec une image ce soir en regardant la télé.

    Rq: si tu as ton image à me fournir, ce serait plus pratique...

  12. #12
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    Voilà :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    <!DOCTYPE html>
    <html lang="fr">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Roue image</title>
        <style>
            html, body {
                margin: 0;
                padding: 0;
                background: rgb(7, 169, 234);
            }
            #content{
                background-color: white;
                border: 2px solid black;
                width: 60vh;
                height: 60vh;
                margin: 10vh auto 0;
            }
            #roue{
                width:50vh;
                height:50vh;
                margin: 5vh auto 0;
                background-image:url('roue.png');
                background-size: cover;
            }
           
            #container_button{
                width:86vmin;
                height:auto;
                margin: 4vmin auto 0;
            }
            input{
              display:inline-block;  
              width:36vmin;
              height:12vmin;
              margin: auto 3vmin auto;
              font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
              font-size: 2.5vmin;
            }
     
        </style>
    </head>
    <body>
      <div id="content">
         <div id="roue">
      </div>
       </div>
       <div id="container_button">
         <input type="button" id="relancer" value="Lancer">
         <input type="button" id="arret" value="Arrêter progressivement">
       </div>
     
        <script>
            const roue=document.querySelector("#roue");
            let f=1,//1 tr/s
                omega=2*Math.PI*f,
                dec_f=.003,
                arret=false,
                first=true,
                theta=0,
                dtheta,
                dt=.010; //10 ms  fictif ici il faudrait le faire calculer à chaque frame avec Date()...
            const deuxPi=2*Math.PI;
     
            function anime(){ 
             roue.style.transform = 'rotate(' +theta +'rad)';
            }
            
            function arret_progressif(){
                if (arret){
                    f-=dec_f;
                    omega=deuxPi*f
                } else return;
            }
            
            function callback(){
                arret_progressif();
                dtheta=omega*dt;
                theta+=dtheta;
                anime();
                omega>0 ? window.requestAnimationFrame(callback) : window.cancelAnimationFrame(callback);   
            }
     
            const button1=document.querySelector("#relancer");
            button1.addEventListener('click',(e)=>{
                if (first){
                  e.currentTarget.value='Relancer';
                  window.requestAnimationFrame(callback);
                  first=false;
                } 
                else if ( (arret) && (omega<=0) ){
                    arret=false; 
                    f=1;
                    omega=2*Math.PI*f;
                    theta=0;
                    window.requestAnimationFrame(callback);
                } else return;
            });
     
            const button2=document.querySelector("#arret");
            button2.addEventListener('click',()=>{arret=true});
        </script>
    </body>
    </html>

    L'image:Nom : roue.png
Affichages : 101
Taille : 8,7 Ko

  13. #13
    Membre régulier
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juillet 2019
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2019
    Messages : 134
    Points : 75
    Points
    75
    Par défaut
    Parfait, c'est vraiment cela
    Merci beaucoup de ton aide Archimède et bravo !!!
    Passe une bonne soirée

  14. #14
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    Merci à toi ! (sympa pour une roue de la fortune avec lancement à la souris (c'est toujours adaptable)... ou un tirage au sort pour des sujets d'oraux sur chaque secteur de la roue.
    Si tu veux un dt adaptable en fonction des frames :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
             let f=.5,//1/2 tr/s
                omega=2*Math.PI*f,
                dec_f=.003,
                arret=false,
                first=true,
                theta=0,
                dtheta,
                ti=performance.now(),
                tf,
                dt; 
     
            const deuxPi=2*Math.PI;
     
            function anime(){  
             roue.style.transform = 'rotate(' +theta +'rad)';
            }
     
            function arret_progressif(){
                if (arret){
                    f-=dec_f;
                    omega=deuxPi*f
                } else return;
            }
     
            function callback(){
                tf=performance.now();
                dt = (tf - ti)*.001; 
                console.log(dt);  
                ti = performance.now();
                arret_progressif();
                dtheta=omega*dt;
                theta+=dtheta;
                anime();
                omega>0 ? window.requestAnimationFrame(callback) : window.cancelAnimationFrame(callback);   
                ti=tf;
            }

    Bonne soirée !

+ Répondre à la discussion
Cette discussion est résolue.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo