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 :

[Snap.svg] Optimisation animation


Sujet :

JavaScript

  1. #1
    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 [Snap.svg] Optimisation animation
    Salut, voilà, j'ai besoin d'un petit conseil. Je me suis lancé dans des aminations et je trouve que c'est un peu poussif dans la fluidité (surtout sur ff). Ici, j'ai commencé à reprendre un truc que j'avais fait en delphi, il y a une bonne dizaine d'années...
    Le but est de faire un lâcher de balle à vélo et de tracer la trajectoire de la balle (entre autres)... Donc il va falloir que je rajoute un tableau des positions de la balle et faire un polyline pour le tracé qui va encore bien faire plomber l'animation...
    Sur une précédente animation, j'avais précalculé mes positions avant d'animer et je faisais un polyline à chaque frame avec un slice sur mon tableau pour ne retenir que les positions correspondantes.
    ça n'a pas amélioré outre mesure la fluidité de l'animation...

    Je me demande si j'utilise la bonne méthode pour animer. Faut-il que j'utilise la fonction intégrée animate() sur mes objets plutôt que de procéder comme ci-dessous...
    animate fait une animation sur une durée précise et on fixe le point d'arrivée... ce qui n'est pas très pratique (d'autant plus qu'il faut faire recommencer l'animation à chaque fois)


    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
     
    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
         <style>
        html, body {margin: 0;padding: 0;background: Skyblue;  }
         
         #stage{
             background :#101010;
         }
        </style>
       <script src="snap.svg-min.js"></script>
    </head>
    <body>
     <svg width="100%" height="auto" viewBox="0 0 1000 350"  id="stage"></svg>
    <script>
        var paper= Snap("#stage");
        
        class Roue{
            constructor(cx,cy,R){ 
              this.cx = cx || 0;
              this.cy = cy || 0;
              this.R = R || 100;
              this.snapgroup = this.createRoue();
            }
            
            createRoue(){
                let group=paper.g();
                let cercle=paper.circle(this.cx,this.cy,this.R).attr({
                    'stroke-width' :3,
                     stroke: '#00FF00',
                     fill:'none'});
                group.add(cercle);
                let rayon=[];
                for (let i=0;i<=8;i++) {
                    rayon.push(paper.line(this.cx,this.cy,this.cx+this.R,this.cy).attr({'stroke-width' :2,stroke: 'white'}) );
                    rayon[i].transform('r'+(45*i)+','+(this.cx)+','+(this.cy)  );
                    group.add(rayon[i]);
                }  
                return group;  
            } 
        }
        var rouearriere = new Roue(52,236,50);
        var roueavant = new Roue(218,236,50);
        var velo=paper.image('cadre.svg',15,10,204,255);
        let sol=paper.line(0,288,1000,288).attr( {'stroke-width' :3, stroke: 'white'} ); 
        var balle= paper.circle(225,25,15).attr({
           fill:'yellow'
        });
        var bicycle=paper.g(roueavant.snapgroup,rouearriere.snapgroup,velo,balle);
      
        const f=0.25;  //tr/s
        const ftp=60; //images/s
        const deg=180/Math.PI;
        
         var tau=1/ftp;
         var omega=2*Math.PI*f;
         var theta=0,frame=-1;
       
        
        function anime(){
            frame++;
            if (roueavant.R*theta>1000) frame=0;
            theta=omega*tau*frame;
            bicycle.transform('t'+ ( roueavant.R*theta) );
            roueavant.snapgroup.transform('r'+(theta*deg)+','+ 218 +','+ 236 );
            rouearriere.snapgroup.transform('r'+(theta*deg)+','+ 52 +','+ 236 );
      
            window.requestAnimFrame(anime);
         }
        window.requestAnimFrame = (function(){
        return window.requestAnimationFrame       || 
               window.webkitRequestAnimationFrame || 
               window.mozRequestAnimationFrame    || 
               window.oRequestAnimationFrame      || 
               window.msRequestAnimationFrame     || 
     
               function(callback){                 
                  window.setTimeout(callback, 1000*tau);
               };
         })();      
         anime();      
    </script>
     
    </body>
    Fichiers attachés Fichiers attachés

  2. #2
    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'ai avancé un petit peu avec la trajectoire de la balle, on peut sans doute améliorer la fluidité... Le stockage au préalable des positions et des angles dans des tableaux avant l'animation n'améliore pas franchement le rendu (j'ai déjà testé sur une autre animation du même genre où je trace une cycloïde... les slice sur trajectoire pour afficher la bonne partie de la courbe doivent aussi plomber le tout.

    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
     
    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
         <style>
        html, body {margin: 0;padding: 0;background: Skyblue;  }
         
         #stage{
             background :#101010;
         }
        </style>
       <script src="snap.svg-min.js"></script>
    </head>
    <body>
     <svg width="100%" height="auto" viewBox="0 0 1000 350"  id="stage"></svg>
    <script>
        var paper= Snap("#stage");
        
        class Roue{
            constructor(cx,cy,R){ 
              this.cx = cx || 0;
              this.cy = cy || 0;
              this.R = R || 100;
              this.snapgroup = this.createRoue();
            }
            
            createRoue(){
                let group=paper.g();
                let cercle=paper.circle(this.cx,this.cy,this.R).attr({
                    'stroke-width' :3,
                     stroke: '#00FF00',
                     fill:'none'});
                group.add(cercle);
                let rayon=[];
                for (let i=0;i<8;i++) {
                    rayon.push(paper.line(this.cx,this.cy,this.cx+this.R,this.cy).attr({'stroke-width' :2,stroke: 'white'}) );
                    rayon[i].transform('r'+(45*i)+','+(this.cx)+','+(this.cy)  );
                    group.add(rayon[i]);
                }  
                return group;  
            } 
        }
        var rouearriere = new Roue(52,236,50);
        var roueavant = new Roue(218,236,50);
        var velo=paper.image('cadre.svg',15,10,204,255);
        var bicycle=paper.g(roueavant.snapgroup,rouearriere.snapgroup,velo);
        let sol=paper.line(0,288,1000,288).attr( {'stroke-width' :3, stroke: 'white'} ); 
        var balle= paper.circle(218,25,15).attr({
           fill:'yellow'
        });
     
        const f=0.25;  //tr/s
        const ftp=60; //images/s
        const deg=180/Math.PI;
        const coeff=4;
        const g=9.81*coeff;
        
         var tau=1/ftp;
         var omega=2*Math.PI*f;
         var theta=0,frame=-1;
         var traj=[218,25];
         var parabole=paper.polyline(traj);
         
        function anime(){
            parabole.remove();
            frame++;
            theta=omega*tau*frame;
            let Rtheta=roueavant.R*theta;
            let dh=0.5*g*Math.pow(tau*frame,2);
            
            if (Rtheta>1000) {frame=0;traj=[218,25];}
            bicycle.transform('t'+ (Rtheta) );
            roueavant.snapgroup.transform('r'+(theta*deg)+','+ 218 +','+ 236 );
            rouearriere.snapgroup.transform('r'+(theta*deg)+','+ 52 +','+ 236 );
            if (25+dh<273) {
                      traj.push(Rtheta+218,25+dh);
                      parabole= paper.polyline(traj).attr({
                                 'stroke-width' :2,
                                  stroke: '#FF0000',
                                  fill:'none'
                                  });
                       balle.transform('t'+ (Rtheta) + ','+ (dh) );
            } 
            window.requestAnimFrame(anime);
         }
        window.requestAnimFrame = (function(){
        return window.requestAnimationFrame       || 
               window.webkitRequestAnimationFrame || 
               window.mozRequestAnimationFrame    || 
               window.oRequestAnimationFrame      || 
               window.msRequestAnimationFrame     || 
     
               function(callback){                 
                  window.setTimeout(callback, 1000*tau);
               };
         })();      
         anime();      
    </script>
    </body>
    </html>

  3. #3
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 148
    Points : 44 958
    Points
    44 958
    Par défaut
    Bonjour,
    je commence par une remarque sur le code.
    Si tu utilises les « class », donc navigateurs modernes, alors inutile de passer par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    window.requestAnimFrame = (function(){
    return window.requestAnimationFrame       ||
           window.webkitRequestAnimationFrame ||
           window.mozRequestAnimationFrame    ||
           window.oRequestAnimationFrame      ||
           window.msRequestAnimationFrame     ||
     
           function(callback){
              window.setTimeout(callback, 1000*tau);
           };
     })();
    tu peux utiliser directement requestAnimationFrame.

    J'ai tester le nombre de frame d'affichage et le résultat est correct il n'y a rien qui « plombe » ton animation même si FireFox est plus sensible que Chrome.

    Si tu as un problème de fluidité c'est plutôt dû aux choix de tes pas d'avance, par exemple pourquoi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const ftp=60; //images/s
    en mettant 30 cela serait suffisant par exemple. La fluidité est également dans le choix des paramètres.

    Je me demande si j'utilise la bonne méthode pour animer. Faut-il que j'utilise la fonction intégrée animate() sur mes objets plutôt que de procéder comme ci-dessous...
    Si tu veux animer sans trop te soucier de la gestion le animate me paraît un bon choix, mais si ton animation est un peu plus sophistiquée et que tu as des besoins de synchronisation alors, mais pas regardé en détail, ta façon de procéder me paraît correcte.

  4. #4
    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
    Salut, merci pour ta réponse... Le mieux étant, je crois, de virer le setTimeout et de faire calculer le tau réel à chaque frame ...quitte à avoir quelques accélérations ou ralentissements mais ça éviterait sans doute des ratés sur un interval Timer trop court par rapport au rafraichissement du navigateur...
    Merci pour la remarque sur les class qui ne sont compatibles que sur les navigateurs modernes => d'où aucun intérêt des multiples choix de signature de requestAnimationFrame... Ok

  5. #5
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 912
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 912
    Points : 6 705
    Points
    6 705
    Par défaut
    Juste la manière dont j'écrirais ce passage:
    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
         var tau=1/ftp;
         var tauC = tau * tau;
         var omega=2*Math.PI*f;
         var omegatau = omega*tau;
         var theta=0,frame=-1;
         var traj=[218,25];
         var parabole=paper.polyline(traj);
     
        function anime(){
            parabole.remove();
            frame++;
            theta=omegatau*frame;
            let thetadeg = theta*deg;
            let Rtheta=roueavant.R*theta;
            //let dh=0.5*g*Math.pow(tau*frame,2);
            let dh = .5*g*tauC*frame*frame;
     
            if (Rtheta>1000) {
                frame = 0;
                traj = [218, 25];
            }
            bicycle.transform(`t${Rtheta}`);
     
            roueavant.snapgroup.transform(`r${thetadeg},218,236`);
                //'r'+(theta*deg)+','+ 218 +','+ 236 );
            rouearriere.snapgroup.transform(`r${thetadeg},52,236`);
                //'r'+(theta*deg)+','+ 52 +','+ 236 );
            //if (25+dh<273) {
            if (dh < 248 ) {
                      traj.push(Rtheta+218,25+dh);
                      parabole= paper.polyline(traj).attr({
                                 'stroke-width': 2,
                                  stroke: '#FF0000',
                                  fill:'none'
                                  });
                       balle.transform(`t${Rtheta},${dh}`);
            }
    Rien de révolutionnaire, mais bout à bout ça m'a l'air plus fluide.

  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
    Merci pour ta contribution, tout ce qui peut limiter le temps de passage dans le callback est bienvenu. Je n'ai pas essayé mais tes modifs sont pertinentes...
    Après, j'ai réfléchi à un problème avec l'objet polyline... A chaque fois, je l'ai recréé et je fais un remove() alors que l'intérêt étant de le modifier avec attr() sans le détruire à chaque fois...
    Du coup, on peut modifier le paramètre tableau trajectoire en gardant l'instance de objet. Il suffit de faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
         parabole.attr('points', traj);
    Le passage sur la trajectoire de la balle devient plus fluide...sans remove()
    Après, j'ai viré le setTimeout et j'ai joué sur tau et f. Même si ça ne respecte pas un interval timer cohérent, ce n'est pas grave. Et là, c'est nettement meilleur.
    Je vais rajouter ta proposition...

    merci

  7. #7
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 148
    Points : 44 958
    Points
    44 958
    Par défaut
    Je n'avais pas franchement regaré le code mais ...
    Citation Envoyé par CosmoKnacki
    Rien de révolutionnaire,
    cela reste du domaine de l'optimisation, grande ou petite, que de ne pas faire deux fois la même chose.
    Je suis plus circonspect en ce qui concerne les « template string », mais là encore autant par soucis de lecture adopter l'« écriture moderne ».

    Et en regardant de plus près
    Citation Envoyé par Archimède
    Après, j'ai réfléchi à un problème avec l'objet polyline...
    effectivement la recréation n'est pas nécessaire et la modification de l'attribut est bonne.

    Après, j'ai viré le setTimeout
    Je ne vois pas où tu utilisais un setTimeout, comme window.requestAnimationFrame est reconnue tu ne l'utilises pas.


    J'ai fais quelques essais de mesure de vitesse, en me passant de l'affichage, (en fait le moteur de rendu n'a jamais la main), et en ne faisant tourner que les différentes versions de ta fonction et ... le gain n'est pas probant

    Moyenne des valeurs (en ms) de 10 x 1000 boucles en enlevant la meilleur et la plus mauvaise valeur.
    Fct Chrome FireFox
    Archimède 4269 3312
    CosmoKnacki 4193 3245
    without remove 4225 3194
    Les résultats sont à prendre en relatif, je n'ai pas une bête de course, et ne tiennent pas compte du rendu par le navigateur.

    Je m'attendais à de bons écarts mais je note qu'il n'existe pas franchement de différence entre les méthodes.
    Il faut également dire que les moteurs JavaScript sont capables d'optimisation.

  8. #8
    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, je suis assez étonné du résultat... En fait, c'est faire des économies de bouts de chandelle mais bon.

  9. #9
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 148
    Points : 44 958
    Points
    44 958
    Par défaut
    faire des économies de bouts de chandelle mais bon.
    non il n'y a pas de petites économies, il y a une habitude à prendre et tôt ou tard cela est payant.


    PS :
    J'ai fais quelques essais supplémentaires juste pour bien me rendre compte :

    Moyenne sur 1000 passages avec affichage via requestAnimationFrame
    Fct Chrome FireFox
    Archimède 17021 18212
    CosmoKnacki 17058 18071
    noRemove 16741 17610
    Il ne ressort pas qu'une méthode prenne vraiment le pas sur les autres.

    La tendance c'est inversée, Chrome est devenu « plus efficace » avec affichage compris, visiblement le moteur de rendu s'en sort nettement mieux.

    On peut considérer qu'autour de 16666 ms on est proche de la fréquence visée par requestAnimationFrame, à savoir 60 fps vérifié sur les deux navigateurs.

  10. #10
    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 pour cet échantillon, on voit tout de même que le noremove a son efficacité, ce qui est complétement logique. Après perso, j'avais laissé ça comme ça pour une meilleure compréhension de ce que je faisais. Tu me déconseilles les template strings, je trouvais que c'était une bonne idée avec une écriture plus compacte dans les transform... mais bon si ça devient désuet...
    Voilà, merci encore à vous deux, je me fais la main sur inkscape pour les images svg à intégrer et pour compléter le rendu des animations. (c'est complémentaire...)
    Mais je suis super content de cette bibliothèque qui permet de faire l'équivalent de flash. C'est super !

  11. #11
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 148
    Points : 44 958
    Points
    44 958
    Par défaut
    Tu me déconseilles les template strings, je trouvais que c'était une bonne idée avec une écriture plus compacte dans les transform... mais bon si ça devient désuet...
    je n'ai pas dis cela, je me prononçais juste sur le gain que cette écriture pouvait apporter, pour moi pas grand chose voir rien en raison du parsage.

    Je t'encourage néanmoins à adopter cette écriture, c'est l'« écriture du future »

  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
    Je t'encourage néanmoins à adopter cette écriture, c'est l'« écriture du future »
    J'avais mal compris, autant pour moi... je l'adopte.

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

Discussions similaires

  1. [Snap.svg] Créer un texte éditable
    Par Archimède dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 28/04/2021, 20h25
  2. [Snap.svg] Utiliser mina.bounce
    Par Archimède dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 09/04/2021, 10h09
  3. Fabric.js VS Snap SVG
    Par arnaud_verlaine dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 27/08/2020, 15h15
  4. optimisation animation par fps >60Hz
    Par Archimède dans le forum Débuter
    Réponses: 6
    Dernier message: 20/01/2010, 18h18
  5. Optimisations animation gif?
    Par LEK dans le forum Webdesign & Ergonomie
    Réponses: 3
    Dernier message: 06/06/2008, 16h32

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