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 :

Canvas signature (Js pur - POO)


Sujet :

JavaScript

  1. #1
    Nouveau membre du Club Avatar de Elztx
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 72
    Points : 28
    Points
    28
    Par défaut Canvas signature (Js pur - POO)
    Bonjour à tous et à toutes !

    J'essaie de créer un Canvas en JS pur et en POO.
    Seulement... il ne fonctionne pas haha, j'ai dû me planter quelque part..

    Si quelqu'un a le temps de jeter un oeil je veux bien

    Voilà le code du canvas :
    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
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    class CanvasObjet {
      constructor(){ //Paramètres du canvas
        this.canvas = document.getElementById("canvas");
        this.ctx = this.canvas.getContext('2d');
        this.ctx.strokeStyle = '#000000';
        this.ctx.lineWidth = 3;
        this.draw = false;
        this.mousePosition = { x:0, y:0 };
        this.lastPosition = this.mousePosition;
        this.clearButton = document.getElementById("bt-clear");
        this.canvas.width = 200;
        this.canvas.height = 150;
      }
     
    //Gestion des événements 
    evenements(){
        //Souris
      this.canvas.addEventListener("mousedown", function(e) {
        this.draw = true;
        this.lastPosition = this.getMposition(e);
      }); 
     
      this.canvas.addEventListener("mousemove", function(e) {
        this.mousePosition = this.getMposition(e);
        this.canvasResult()
      });
     
      this.canvas.addEventListener("mouseup", function(e) {
        this.draw = false;
      });
     
     
      // Stop scrolling (touch)
      document.body.addEventListener("touchstart", function(e){
        if (e.target == this.canvas){
          e.preventDefault();
        }
      });
     
      document.body.addEventListener("touchend", function(e){
        if (e.target == this.canvas){
          e.preventDefault();
        }
      });
     
      document.body.addEventListener("touchmove", function(e){
        if (e.target == this.canvas){
          e.preventDefault();
        }
      });
     
     
        // Touchpad
      this.canvas.addEventListener("touchstart", function(e) {
        mousePosition = this.getTposition(e);
        var touch = e.touches[0];
        var mouseEvent = new MouseEvent("mousedown", {
          clientX: touch.clientX,
          clientY: touch.clientY
        });
        this.canvas.dispatchEvent(mouseEvent);
      });
     
      this.canvas.addEventListener("touchmove", function(e) {
        var touch = e.touches[0];
        var mouseEvent = new MouseEvent("mousemove", {
          clientX: touch.clientX,
          clientY: touch.clientY
        });
        this.canvas.dispatchEvent(mouseEvent);
      });
     
      this.canvas.addEventListener("touchend", function(e) {
        var mouseEvent = new MouseEvent("mouseup", {});
        this.canvas.dispatchEvent(mouseEvent);
      });
     
     
      //Effacer
      this.clearButton.addEventListener("click", function(e) {
        this.clearCanvas()
      });
    }
     
    // Renvoie les coordonnées de la souris 
    getMposition(mouseEvent){
      if (this.draw) {
        var oRect = this.canvas.getBoundingClientRect();
        return {
          x: mouseEvent.clientX - oRect.left,
          y: mouseEvent.clientY - oRect.top
        };
      }
    }
     
    // Renvoie les coordonnées du pad 
    getTposition(touchEvent){
      var oRect = this.canvas.getBoundingClientRect();
      return {
        x: touchEvent.touches[0].clientX - oRect.left,
        y: touchEvent.touches[0].clientY - oRect.top
      };
    }
     
    // Dessin du canvas
    canvasResult() {
      if(this.draw){
        this.ctx.beginPath(); 
        this.ctx.moveTo(this.lastPosition.x, this.lastPosition.y);
        this.ctx.lineTo(this.mousePosition.x, this.mousePosition.y);
        this.ctx.stroke();
        this.lastPosition = this.mousePosition;
      }
    };
     
    // Vide le dessin du canvas
    clearCanvas(){
      this.canvas.width = this.canvas.width;
        this.ctx.lineWidth = 3;
    }
     
    }
    Voilà le HTML :
    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
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Canvas</title>
       <link rel="stylesheet" href="style.css" />
        <script type="text/javascript" src="jsv.js"></script>
    </head>
     
      <body>
     
    <h1>Canvas</h1>
    <div class="mise-en-page">
      <div class="bloc-mise-en-page">
        <h2>Signer (<span id="bt-clear">nettoyer</span>)</h2>
        <canvas id="canvas"></canvas>
      </div>
    </div> 
     
    </body>

    Et le CSS :
    Code CSS : 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
    #canvas{
      width:250px;
      height:150px;
      border:1px solid #000
    }
    #capture{ 
      border:1px solid black;
      width:200px;
      height:150px;
    }
     
    /* MISE EN PAGE*/
    .mise-en-page{}
    .bloc-mise-en-page{margin:10px;
      flex:1 0 0px;   
      min-width:500px;
    }
     
    body{
      font-family: Arial;
    }

    Merci beaucoup

  2. #2
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Salut,

    On n'a pas le fichier jsv.js...

    Sinon un des problèmes c'est le fameux this*, celui-ci ne pointe pas comme vous l'attendez vers une instance de la class CanvasObjet mais vers l'élément html canvas...

    *Je parle du this utilisé à l'intérieur des fonctions addEventListener...

    EDIT :

    pour résoudre le problème dont je parle j'ai modifié la fonction evenements comme ceci :

    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
    evenements() {
            var self = this ;
            //Souris
            this.canvas.addEventListener("mousedown", function (e) {
                self.draw = true;
                self.lastPosition = self.getMposition(e);
            });
     
            this.canvas.addEventListener("mousemove", function (e) {
                self.mousePosition = self.getMposition(e);
                self.canvasResult()
            });
     
            this.canvas.addEventListener("mouseup", function (e) {
                self.draw = false;
            });
     
     
            // Stop scrolling (touch)
            document.body.addEventListener("touchstart", function (e) {
                if (e.target == self.canvas) {
                    e.preventDefault();
                }
            });
     
            document.body.addEventListener("touchend", function (e) {
                if (e.target == self.canvas) {
                    e.preventDefault();
                }
            });
     
            document.body.addEventListener("touchmove", function (e) {
                if (e.target == self.canvas) {
                    e.preventDefault();
                }
            });
     
     
            // Touchpad
            this.canvas.addEventListener("touchstart", function (e) {
                mousePosition = self.getTposition(e);
                var touch = e.touches[0];
                var mouseEvent = new MouseEvent("mousedown", {
                    clientX: touch.clientX,
                    clientY: touch.clientY
                });
                self.canvas.dispatchEvent(mouseEvent);
            });
     
            this.canvas.addEventListener("touchmove", function (e) {
                var touch = e.touches[0];
                var mouseEvent = new MouseEvent("mousemove", {
                    clientX: touch.clientX,
                    clientY: touch.clientY
                });
                self.canvas.dispatchEvent(mouseEvent);
            });
     
            this.canvas.addEventListener("touchend", function (e) {
                var mouseEvent = new MouseEvent("mouseup", {});
                self.canvas.dispatchEvent(mouseEvent);
            });
     
     
            //Effacer
            this.clearButton.addEventListener("click", function (e) {
                self.clearCanvas()
            });
        }
    Et cela fonctionne mieux...

  3. #3
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Je constate cependant qu'il y a d'autres problèmes...
    Il y a un décalage entre la ligne dessinée et le curseur de la souris,
    Et parfois cela continue de dessiner la ligne alors qu'on a relâché la souris...

  4. #4
    Nouveau membre du Club Avatar de Elztx
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 72
    Points : 28
    Points
    28
    Par défaut
    Hello, merci pour ton retour !

    Le fichier jsv.js c'est le js du canvas
    Mmmh même avec tes modifications ça ne semble pas fonctionner de mon côté

    Je regarderai du côté des offsets quand j'arriverai à afficher le tracé pour le décalage ^^

  5. #5
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    chez moi le tracé fonctionne, testez ici pour voir : https://jsbin.com/jimiqibago/edit?js,output

  6. #6
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Bonjour,
    Beginner. a bien vu le problème.
    Plusieurs solutions :
    - utiliser des fonctions fléchées.
    - utiliser bind(this).
    - Ajouter une variable pointant sur this dans evenements (solution de Beginner.).
    - Définir une propriété sur l'élément canvas pointant sur this et dans ce cas, on utilise this.gestionnaire.faireCeci() : le petit défaut est de rajouter dynamiquement des propriétés sur cet objet, des propriétés non prévues de base donc. Si j'en parle c'est que dans d'autres situations, c'est une bonne solution.

    Citation Envoyé par Elztx Voir le message
    Mmmh même avec tes modifications ça ne semble pas fonctionner de mon côté
    Y a-t-il une instance de la classe au moins ?

  7. #7
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Citation Envoyé par Loralina Voir le message
    Y a-t-il une instance de la classe au moins ?
    Effectivement il fallait ajouter du code pour tester : avoir une instance et aussi lancer l'exécution de la fonction evenements, j'ai rajouté cela pour tester :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var obj = new CanvasObjet();
    obj.evenements();

  8. #8
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Citation Envoyé par Beginner. Voir le message
    ...
    Et parfois cela continue de dessiner la ligne alors qu'on a relâché la souris...
    Ce problème a lieu quand on relâche la souris en dehors du canvas, pour le résoudre j'ai remplacé cette fonction :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            this.canvas.addEventListener("mouseup", function (e) {
                self.draw = false;
            });
    par celle-ci :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            document.addEventListener("mouseup", function (e) {
                self.draw = false;
            });

  9. #9
    Nouveau membre du Club Avatar de Elztx
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 72
    Points : 28
    Points
    28
    Par défaut
    Bonjour Loralina Merci pour les explications !

    Oui oui en fin de code. J'ai testé de reprendre le code de Beginner. pour tester, ça ne fonctionne pas non plus c'est vraiment étrange, mon cache est vidé etc pourtant. Il fonctionne bien via le lien fourni.. Je vais tester depuis un autre navigateur/ordi en rentrant !

    Oh, merci ! Je vais regarder ça de plus près tout à l'heure en espérant que ça fonctionne enfin chez moi ^^

  10. #10
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Bonjour,
    regarde dans la console, F12, les erreurs qui peuvent apparaître.

    Si l’initialisation de ton objet est réalisé dans ton fichier JS, placé en début de ta page, alors le DOM n'est pas encore construit ce qui conduit à une erreur.

  11. #11
    Nouveau membre du Club Avatar de Elztx
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 72
    Points : 28
    Points
    28
    Par défaut
    Hello,

    En effet, c'était bien le souci !! Merci beaucoup à tous, ça fonctionne, je vais me pencher sur les décalages

  12. #12
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    je vais me pencher sur les décalages
    Attention à la chute

    Tu as introduit un rapport d'échelle entre ton canvas et sa représentation à l'écran.

    Lorsque que tu écris dans ton CSS
    Code css : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #canvas{
      width:250px;
      height:150px;
    }
    tu définies les dimensions d'affichage sur ton viewPort, ton canvas occupe une largeur de 250 pixels viewPort et une hauteur de 150 pixels viewPort.

    Lorsque tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    this.canvas.width = 200;
    this.canvas.height = 150;
    tu définies la résolution, largeur/hauteur, de ton canvas, « unité canvas ».

    Tu te retrouves avec un rapport d'échelle comme suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    scaleX = 250 / 200 ;  // soit 1.25
    scaleX = 150 / 150 ;  // soit  1
    Lorsque d'un déplacement, sur ton viewPort, de 10 pixels en X cela représente un tracé de 10 x 1.25 unités sur ton canvas, d'où le décalage que tu constates en X et pas en Y attendu que le rapport est de 1.

    Pour remédier à cela tu peux ne pas attribuer de largeur/hauteur en CSS et laisser faire le navigateur, par défaut il t"affichera ton canvas avec un rapport de 1 en X et Y, soit tu en tiens compte et il te faut calculer lors de l'initialisation ces ratios, par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    this.canvas.width = 200;
    this.canvas.height = 150;
    this.scaleX = this.canvas.clientWidth / this.canvas.width;
    this.scaleY = this.canvas.clientHeight / this.canvas.height;
    ... ensuite dans ton code, lors de la récupération de la position de la souris tu en tiens compte
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // Renvoie les coordonnées de la souris 
    getMposition(mouseEvent) {
      if (this.draw) {
        var oRect = this.canvas.getBoundingClientRect();
        return {
          x: (mouseEvent.clientX - oRect.left) / this.scaleX,
          y: (mouseEvent.clientY - oRect.top) / this.scaleY
        };
      }
    }
    Un remarque concernant l'initialisation de ton objet, en l'état il n'est pas utilisable pour gérer plusieurs canavs attendu que tu places en dur l'id du canvas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class CanvasObjet {
      constructor() {
        this.canvas = document.getElementById("canvas");
        // ...
    Tu aurais meilleur compte à passer l'id de l'élément
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class CanvasObjet {
      constructor(id) { //Paramètres du canvas
        this.canvas = document.getElementById(id);//"canvas");
    de la sorte tu pourras gérer, si besoin, plusieurs canvas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const o1 = new CanvasObjet ("canvas1");
    const o2 = new CanvasObjet ("canvas2");
    o1.evenements();
    o2.evenements();

  13. #13
    Nouveau membre du Club Avatar de Elztx
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 72
    Points : 28
    Points
    28
    Par défaut
    Hello,
    Merci pour tes remarques si bien expliquées !
    J'ai paré au problème de décalage en mettant
    Code Javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    this.canvas.width = 250; //250 au lieu de 200 pour contrer le décalage
            this.canvas.height = 150;

    Et côté CSS :
    Code CSS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #canvas{
        margin: auto;
        width: 200;
        height: 150px;
        background-color: white;
        border-radius: 25px;
        border:1px solid #000;
    }

    Actuellement je n'ai plus de décalage. Je ne sais pas si la méthode est mauvaise mais ça fonctionne bien...

    Ah oui, merci pour l'initialisation de l'objet, pas bête du tout, je vais regarder ça

  14. #14
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.canvas.width = 250; //250 au lieu de 200 pour contrer le décalage
    et si tu rajoutes l'unité manquante
    Code css : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #canvas{
        width: 200;   /* MANQUE l'unité */
    }
    tu vas avoir le problème inverse !

  15. #15
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Salut,

    1- NoSmoking a donné une solution pour régler la plus importante source de décalage mais je voulais préciser qu'il y en a une autre...

    Elle est due à la bordure, là elle est de 1px donc le décalage ne se voit pas beaucoup mais si on l'augmente le décalage devient visible...

    C'est dû au fait que la fonction getBoundingClientRect renvoi les coordonnées de la borderBox, il faudrait les coordonnées par rapport à la paddingBox...

    J'ai corrigé cela en remplaçant :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
                return {
                    x: mouseEvent.clientX - oRect.left ,
                    y: mouseEvent.clientY - oRect.top
                };
    par :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
                return {
                    x: mouseEvent.clientX - oRect.left - this.canvas.clientLeft,
                    y: mouseEvent.clientY - oRect.top - this.canvas.clientTop 
                };

    2- Il y a un autre problème, la largeur du tracé n'est pas prise en compte au début dans le constructeur, je veux parler de la ligne this.ctx.lineWidth = 3;, il faudrait la placer après :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    this.canvas.width = 250;
    this.canvas.height = 150;

  16. #16
    Nouveau membre du Club Avatar de Elztx
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 72
    Points : 28
    Points
    28
    Par défaut
    Hello,

    Oups NoSmoking je suis fatiguée ! C’est réglé ! Par contre je l’ai hébergé pour tester et le scrolling n’est pas stoppé sur mobile....

    Oh top Beginner ! Je teste tout ça demain !! Merci

  17. #17
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Je me suis plutôt prononcé sur la forme et non sur la fond, maintenant voyons le fond

    Concernant les bordures :
    Compte tenu du fait que l'on ne dessine pas sur les bordures d'un canvas, celui-ci ne devrait pas avoir de border.
    Si il s'agit de délimiter celui-ci à l'écran on peut avoir recours à un cadre, que l'on style comme bon nous semble, ou utiliser la propriété CSS box-shadow, plus discret, directement sur le canvas.
    D'un autre côté une bordure de 1px n'est pas en soit préjudiciable, le décalage n'étant pas vraiment perceptible et ce d'autant sur un support tactile.

    Position de la souris :
    Il n'est pas forcément utile de se torturer l'esprit, outre le problème éventuel de ratio X/Y.
    Il suffit d'utiliser la propriété offsetX/Y de l'événement mouse
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Renvoie les coordonnées de la souris 
    getMposition(mouseEvent) {
      if (this.draw) {
        return {
          x: mouseEvent.offsetX / this.scaleX,
          y: mouseEvent.offsetY / this.scaleY
        };
      }
    }
    Une remarque au passage, je serais plutôt en clin d'affecter l'événement de gestion du déplacement sur le mousedown et de le retirer sur le mouseup, de ce fait la gestion via le this.draw ne servirait plus à rien et on ne maintiendrait pas un événement devenu inutile au survol simple du canvas.

    Effacement dessin :
    Il existe la méthode clearRect qui me semble bien plus appropriée dans ce cas et tellement simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // Vide le dessin du canvas
    clearCanvas() {
      // utilise la couleur d'arrière plan du canvas
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    }
    Initialisations diverses :
    Le fait de (re)dimensionner le canvas fait que celui-ci est effectivement « reseter », il faut donc bien mettre toutes les initialisations après le (re)dimensionnement.

    De plus, dans un soucis de paramétrage, pourquoi ne pas passer également d'éventuelles options ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class CanvasObjet {
      constructor(id, opt) {
        opt = opt || {};
        this.canvas = document.getElementById(id);
        this.ctx = this.canvas.getContext('2d');
        //    /!\ définir une largeur/hauteur en premier
        this.canvas.width = 250;
        this.canvas.height = 150;;
        this.ctx.strokeStyle = opt.strokeStyle || "#000";
        this.ctx.lineWidth = opt.lineWidth || 1;
        // ...
    c'est juste un exemple ... et donc un appel du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    const o1 = new CanvasObjet("canvas1", {
      strokeStyle: "#F00",
      lineWidth: 2
    });
    const o2 = new CanvasObjet("canvas2"); // options par défaut
    Petit complément :
    Pour illustrer les propos de Loralina concernant l'utilisation des fonctions fléchées je joint un petit bout de code à tester
    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
    //Gestion des événements 
    evenements() {
      //Souris
      const thisObjet = this;
      this.canvas.addEventListener("mousedown", /*(e) => */ function(e) {
        //this.draw = true;
        //this.lastPosition = this.getMposition(e);
        thisObjet.draw = true;
        thisObjet.lastPosition = thisObjet.getMposition(e);
      });
      this.canvas.addEventListener("mousemove", (e) => /*function(e)*/ {
        this.mousePosition = this.getMposition(e);
        this.canvasResult()
        //thisObjet.mousePosition = thisObjet.getMposition(e);
        //thisObjet.canvasResult()
      });
      // ...
    en voilà un peu plus sur le fond.

  18. #18
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Une petite remarque à propos de ce scaling. Pour moi, du point de vue de CSS, un canevas est traité comme une image. Je ne sais pas si vous avez déjà essayé d’appliquer des width et height via CSS à une image, le résultat est pas terrible à cause du rééchantillonage.

    Avec un canevas, c’est un peu la même chose : il a, en tout temps, ses propriétés intrinsèques .width et .height (DOM, pas CSS) qui sont utilisées pour le dessin. Si les dimensions demandées via CSS sont différentes des dimensions intrinsèques, il va y avoir un redimensionnement, et ça sera aussi moche qu’avec une image.

    Personnellement, je préfère ne jamais donner de règles CSS width et height à un canevas.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  19. #19
    Nouveau membre du Club Avatar de Elztx
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2019
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2019
    Messages : 72
    Points : 28
    Points
    28
    Par défaut
    Bonjour,

    Merci à tous pour vos remarques, je vais me pencher sur vos dernières suggestions.

    En ce qui concerne la suppression du scrolling sur mobile, celle-ci n'est pas appliquée.. si quelqu'un a une piste !
    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
    // Stop scrolling (touch)
            document.body.addEventListener("touchstart", function (e) {
                if (e.target == self.canvas) {
                    e.preventDefault();
                }
            });
     
            document.body.addEventListener("touchend", function (e) {
                if (e.target == self.canvas) {
                    e.preventDefault();
                }
            });
     
            document.body.addEventListener("touchmove", function (e) {
                if (e.target == self.canvas) {
                    e.preventDefault();
                }
            });

  20. #20
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    @Watilin :
    je suis d'accord avec toi mais il est des cas où il peut être intéressant de « grossir » grâce au CSS et l'exemple de la signature est à mon sens un bon exemple.

    Dans un soucis de confort pour l'utilisateur on peut définir une zone écran de 400 x 400, par exemple, mais la qualité du visa n'étant qu'approximative, un enregistrement de celle-ci au format 200 x 200, voire moins, peut être largement suffisante.

    Avec des données, récupérées via un getImageData, on aura un rapport de 1/4, même si le format final transmis, via un toDataURL, sera moins gagnant mais gagnant quand même.

    Mais te le concède dans la plupart des cas, je n'ai pas trouvé rapidement d'autre cas, cela est inutile.


    @Elztx :
    tu n'appliques pas le e.preventDefault() au bon endroit, là où tu le places l’événement à déjà eu lieu.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    this.canvas.addEventListener("touchstart", function(e) {
      e.preventDefault();

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Diaporama JS pur (POO)
    Par Elztx dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 08/04/2019, 14h17
  2. [POO] Flux webcam dans un Canvas/Frame
    Par nicolivier dans le forum Tkinter
    Réponses: 11
    Dernier message: 26/05/2013, 09h36
  3. [POO] Destructeur virtuel pur
    Par Nesto dans le forum C++
    Réponses: 3
    Dernier message: 08/11/2008, 17h18
  4. Timage et Canvas??
    Par vanack dans le forum C++Builder
    Réponses: 4
    Dernier message: 14/04/2007, 11h38
  5. Réponses: 2
    Dernier message: 17/05/2002, 20h37

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