Défilement de texte dans un canvas, texte qui accélère chaque fois

zzzzzooooooooooooooooooooooooooooouuuuuuuuum

Le problème exposé dans ce sujet a été résolu.

Salut les agrumes,

Je suis en train de jouer avec Canvas et j’ai pas mal de soucis. L’actuel est que je veux faire défiler du texte quand j’appuie sur un bouton, et que l’animation recommence à chaque appui.

Sauf que, à chaque appui, le texte défile de plus en plus vite, et je n’ai pas la moindre idée de pourquoi.

Il semblerait que la speed augmente à chaque fois, ce que je conclus comme étant que les animations se superposent les unes sur les autres, mais je ne vois pas comment "annuler" l’ancienne.

Je vous donne le MVP et un jsfiddle:

<!DOCTYPE html>
<html>

    <canvas id="animationCanvas" width="500" height="500"></canvas>

    <br>

    <button onclick="draw()">send</button>


<script>
    canvas = document.getElementById('animationCanvas');
    context = canvas.getContext('2d');


function draw() {
    text_x = 100
    speed = 5
    context.fillStyle = '#FF0000';

    text = 'hello'

    animate()
}


function animate() {
    context.clearRect(0, 0, canvas.width, canvas.height)


    context.fillText(text, text_x, 300)
    var metrics = context.measureText(text);
    var textWidth = metrics.width


    if(text_x < 400 - 10 - textWidth) {
        text_x = text_x + speed;
    }

    requestAnimationFrame(animate)
}
</script>

</html>

Des idées de comment faire ?

+0 -0

En continuant mes recherches j’ai trouvé ce post qui m’a fait découvrir cancelAnimationFrame qui me fait le café. Il suffit juste d’enregistrer l’ID de l’animation actuelle dans un coin et le tour est joué.

<!DOCTYPE html>
<html>

    <canvas id="animationCanvas" width="500" height="500"></canvas>
    <br>
    <button onclick="draw()">send</button>


<script>
    canvas = document.getElementById('animationCanvas');
    context = canvas.getContext('2d');

function draw() {
    text_x = 100
    speed = 5
    context.fillStyle = '#FF0000';

    text = 'hello'
    if(window.animation) {
        cancelAnimationFrame(window.animation)
    }
    animate()
}

function animate() {
    context.clearRect(0, 0, canvas.width, canvas.height)


    context.fillText(text, text_x, 300)
    var metrics = context.measureText(text);
    var textWidth = metrics.width


    if(text_x < 400 - 10 - textWidth) {
        text_x = text_x + speed;
    }

    window.animation = requestAnimationFrame(animate)            
}
</script>

</html>
+0 -0

En fait ta première animation ne termine jamais puisque requestAnimationFrame est toujours appelée, donc lorsque tu clique une deuxième fois tu lances une deuxième animation qui incrémente la même variable, donc les deux callbacks font + speed sur la position et donc ça avance deux fois plus vite, etc…

Tu devrais appeler la prochaine récursion seulement si l’animation est en court, c’est à dire qu’elle n’a pas atteint sa position finale

canvas = document.getElementById('animationCanvas');
context = canvas.getContext('2d');


function draw() {
    text_x = 100
    speed = 5
    context.fillStyle = '#FF0000';

    text = 'hello'

    animate()
}


function animate() {
    context.clearRect(0, 0, canvas.width, canvas.height)


    context.fillText(text, text_x, 300)
    var metrics = context.measureText(text);
    var textWidth = metrics.width


    if(text_x < 400 - 10 - textWidth) {
        text_x = text_x + speed;
        requestAnimationFrame(animate)
    }
}
+0 -0

oui, j’avais pensé à cette solution, mais j’avais deux problèmes :

  • Si je clique deux fois sur le bouton pendant l’animation, l’animation continue mais la vitesse augmente
  • J’ai plein d’autres bouts d’animation dans tous les sens il aurait fallu rajouter des if partout pour savoir si continuer l’animation.

Là, je recommence de zéro à chaque clic, je pense que c’est plus clair. :)

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte