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 :

Optimisation d'une animation dans canvas de html5


Sujet :

JavaScript

  1. #1
    Membre Expert
    Avatar de Archim�de
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 60
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activit� : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Par d�faut Optimisation d'une animation dans canvas de html5
    Bonjour, ayant plut�t l'habitude de r�aliser mes animations en actionscript, je cherchais � comparer les deux technologies d'un point de vue fluidit� et facilit� de conception.
    Je me suis focalis� sur une animation simple de dessin avec translation et rotation. une roue en d�placement avec un rep�re qui tourne � l'int�rieur.

    ci-joint mes deux tentatives de r�alisation en javascript/html5

    une sans utilisation de translate() rotate() et l'autre avec...
    ci-joint :
    Code : 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
     
    <!DOCTYPE html>
    <!--
    To change this license header, choose License Headers in Project Properties.
    To change this template file, choose Tools | Templates
    and open the template in the editor.
    -->
    <html>
        <head>
            <title>Roue javascript</title>
            <meta charset="UTF-8">   
        </head>
        <body>
            <canvas id="canvas" width="1024" height="600">
                <p> votre navigateur ne supporte pas Canvas. Mettez-le à jour</p>
            </canvas>
            <script type="text/javascript">
                var canvas = document.querySelector('#canvas');
                var context = canvas.getContext('2d');
                var theta = 0;  //angle de rotation en radian
                var oldtheta = 0;//angle de rotation correspondant à la frame précédente
                var R = 100;  //rayon de la roue
                var retour = new Boolean(false);
                var penw = 3;
                var pi=Math.PI;
     
                function draw()
                {
                    context.save();
                    context.strokeStyle = "black";
                    context.lineWidth = penw;
     
     
                    context.clearRect(R * oldtheta-penw, 10-penw, 2 * R+2*penw, 2 * R+2*penw); //obturation (on efface l'image précédente à chaque fois en tenant compte du pen width)
                    //dessin du contour de la roue
                    context.beginPath();
                    context.arc(R * theta+R, R + 10, R, 0, 2*pi);
                    context.stroke();
     
                    //dessin des quatre rayons
                    for (var i = 0; i <= 3; i++)
                    {
                        context.beginPath();
                        context.moveTo(R * (1+theta), R + 10);
                        context.lineTo(R * (1+theta+ Math.cos(theta + i * pi/2)), 10 + R * (1 + Math.sin(theta + i * pi/2)));
                        context.stroke();
                    }
     
                    //dessin du sol
     
                    context.beginPath();
                    context.moveTo(0, 2 * R + 13);
                    context.lineTo(canvas.width, 2 * R + 10+penw);
                    context.stroke();
     
                    if ((R * theta > canvas.width - 2*R) || (theta < 0)) {
                        retour = !retour;
                    }
                }
     
                function render()
                {
                    draw();
                    window.requestAnimationFrame(render);
                    oldtheta = theta;
                    if (retour) {
                        theta += Math.PI / 180;
                    } else {
                        theta -= Math.PI / 180;
                    }
     
                }
     
                render();
     
                window.requestAnimFrame =
                        window.requestAnimationFrame || // La fonction standard
                        window.webkitRequestAnimationFrame || // Chrome et Safari.
                        window.mozRequestAnimationFrame || //  Firefox.
                        window.ORequestAnimationFrame || //  Opera.
                        window.msRequestAnimationFrame; // Internet Explorer. 
            </script>
        </body>
    </html>
    la seconde :
    Code : 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
     
    <!DOCTYPE html>
     
    <html>
        <head>
            <title>roue en javascript</title>
            <meta charset="UTF-8">
     
        </head>
        <body>
            <canvas id="canvas" width="1024" height="600">
                <p> votre navigateur ne supporte pas Canvas. Mettez-le à jour</p>
            </canvas>
            <script type="text/javascript">
                var canvas = document.querySelector('#canvas');
                var context = canvas.getContext('2d');
                var theta = 0;  //angle de rotation en radian
                var R = 100;  //rayon de la roue
                var retour = new Boolean(false);
                var penw = 3;
     
                function draw()
                {
                    context.save();
                      //obturation (on efface la frame précédente=> peu efficace ici-ça plombe l'animation)
                    context.clearRect(0, 0, canvas.width, canvas.height);
     
     
                    context.translate(R * theta + R, R + 10);//déplacement de l'origine du canvas au centre de la roue
                    context.rotate(theta);//rotation des axes du canvas
     
     
     
                    context.strokeStyle = "black";
                    context.lineWidth = penw;
                    //dessin du contour de la roue
                    context.beginPath();
                    context.arc(0, 0, R, 0, 2 * Math.PI);
                    context.stroke();
     
                    //dessin des quatre rayons
                    for (var i = 0; i <= 3; i++)
                    {
                        context.beginPath();
                        context.moveTo(0, 0);
                        context.lineTo(R * Math.cos(i * Math.PI / 2), R * Math.sin(i * Math.PI / 2));
                        context.stroke();
                    }
     
     
                    context.restore();//retour de l'origine du contexte graphique sur (0,0) en supprimant la rotation
                    //dessin du sol
                    context.beginPath();
                    context.moveTo(0, 2 * R + 10 + penw);
                    context.lineTo(canvas.width, 2 * R + 10 + penw);
                    context.stroke();
                    //gestion de l'aller et retour
                    if ((R * theta >= canvas.width - 2 * R) || (theta < 0)) {
                        retour = !retour;
                    }
                }
     
                function render()
                {
                    draw();
                    window.requestAnimationFrame(render);
     
                    if (retour) {
                        theta += Math.PI / 180;
                    } else {
                        theta -= Math.PI / 180;
                    }
     
                }
     
                render();
     
                window.requestAnimFrame =
                        window.requestAnimationFrame || // La fonction standard
                        window.webkitRequestAnimationFrame || // Chrome et Safari.
                        window.mozRequestAnimationFrame || //  Firefox.
                        window.ORequestAnimationFrame || //  Opera.
                        window.msRequestAnimationFrame; // Internet Explorer. 
            </script>
        </body>
    </html>
    Ma question est : quelle est la meilleure m�thode � adopter... faut-il privil�gier la seconde m�thode (translate() rotate() du canvas) plut�t que la premi�re ?
    Sachant qu'il faudrait que j'obture uniquement sur le dessin de la pr�c�dente frame dont le canvas a subi une rotation...

    Des id�es d'optimisation puisque je d�bute presque dans ce langage et que je ne suis pas convaincu de l'int�r�t de migrer vers html5/javascript hormis les plantages de flashplayer et la d�saffection de flash par les distributeurs de pub.

  2. #2
    Membre chevronn�

    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    311
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 311
    Par d�faut
    Je te conseille la 2eme m�thode, auquel j�aurai pouss� le vice jusqu�� utiliser un context.rotate dans la boucle des rayons !

    Le context 2D peut utiliser l�acc�l�ration mat�rielle donc il est pr�f�rable de r�duire tes calcules trigos du javascript en utilisant les m�thode de changement de rep�re matriciel ( scale , rotate, translate et transform). De mani�re plus g�n�rale, quel que soit le langage ou la techno, il est pr�f�rable de rechercher une solution g�om�trique, plut�t qu�arithm�tique, si tes �quations sont lineaire ----> utilisation direct des calcules matriciel !

    Concernant ton obturation partielle, je suis pas convaincu que cela soit plus rapide, surtout si ta sc�ne devient plus Complexe !

    Apres si tu recherches la performance ultime, je te conseille d�utiliser les contextes WebGL et WebGL2

  3. #3
    Membre Expert
    Avatar de Archim�de
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 60
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activit� : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Par d�faut
    Je te conseille la 2eme m�thode, auquel j�aurai pouss� le vice jusqu�� utiliser un context.rotate dans la boucle des rayons !

    Le context 2D peut utiliser l�acc�l�ration mat�rielle donc il est pr�f�rable de r�duire tes calcules trigos du javascript en utilisant les m�thode de changement de rep�re matriciel ( scale , rotate, translate et transform). De mani�re plus g�n�rale, quel que soit le langage ou la techno, il est pr�f�rable de rechercher une solution g�om�trique, plut�t qu�arithm�tique, si tes �quations sont lineaire ----> utilisation direct des calcules matriciel !
    En effet, c'est ce que je pensais en ayant envisag� de reprendre ma premi�re mouture...Cependant la premi�re m�thode donne un r�sultat nettement plus fluide.

    Concernant ton obturation partielle, je suis pas convaincu que cela soit plus rapide, surtout si ta sc�ne devient plus Complexe !
    La taille du clearRect a pourtant une importance non n�gligeable... Il suffit de mettre : canvas.height/2 pour gagner d�j� en fluidit�.
    Ce qui fait la diff�rence avec la seconde mouture au niveau de la fluidit�, c'est que j'obture uniquement sur la surface de dessin de la frame pr�c�dente.

    Apres si tu recherches la performance ultime, je te conseille d�utiliser les contextes WebGL et WebGL2
    Merci pour l'info... Sinon j'ai vu KineticJS qui n'a pas l'air mal ! et qui travaille avec une m�thode qui ressemble � celle de flash dans la fa�on de coder...
    Je ne sais pas si tu connais ? je n'ai pas encore test�...

    merci pour ta r�ponse.

  4. #4
    Mod�rateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 211
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Is�re (Rh�ne Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 211
    Par d�faut
    Bonjour,
    je constate que tu fais pas mal de calcul trigo, une m�thode est de pr�-calculer et d'enregistrer dans une table les valeurs, on tourne en rond c'est le cas de le dire.

    Je rejoins p3ga5e dans le sens o� tu pourrais tout �galement cr�er ta roue, la r�cup�rer sous forme d'image et n'appliquer la rotation qu'� celle ci via un rotate.

  5. #5
    Membre Expert
    Avatar de Archim�de
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 60
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activit� : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Par d�faut
    Merci pour les remarques . Je regarde tout �a...

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Une animation dans des DIV
    Par edophie dans le forum ActionScript 1 & ActionScript 2
    R�ponses: 2
    Dernier message: 30/08/2007, 20h46
  2. Optimisation d'une insertion dans une BD Oracle
    Par Hamma_TUN dans le forum Oracle
    R�ponses: 5
    Dernier message: 13/07/2006, 10h55
  3. [Strat�gie] Afficher une animation dans un JScrollPane
    Par patmaba dans le forum AWT/Swing
    R�ponses: 8
    Dernier message: 11/10/2005, 09h49
  4. R�ponses: 6
    Dernier message: 14/12/2004, 02h47
  5. R�ponses: 4
    Dernier message: 18/04/2004, 13h36

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