web-dev-qa-db-fra.com

Existe-t-il déjà une directive de dessin sur toile pour AngularJS?

Existe-t-il déjà une directive pour dessiner/peindre des objets sur une toile? Vous pouvez donc implémenter quelque chose comme Paint ou même quelque chose de plus gros comme Photoshop, etc., mais un exemple très basique suffirait.

Je n'en ai pas trouvé dans ma recherche et s'il y en a déjà une qui est considérée comme la meilleure pratique, j'aimerais l'utiliser. Sinon, je dois en appliquer un moi-même.

50
JustGoscha

Ok j'en ai fait un et c'est en fait assez facile:

app.directive("drawing", function(){
  return {
    restrict: "A",
    link: function(scope, element){
      var ctx = element[0].getContext('2d');

      // variable that decides if something should be drawn on mousemove
      var drawing = false;

      // the last coordinates before the current move
      var lastX;
      var lastY;

      element.bind('mousedown', function(event){
        if(event.offsetX!==undefined){
          lastX = event.offsetX;
          lastY = event.offsetY;
        } else { // Firefox compatibility
          lastX = event.layerX - event.currentTarget.offsetLeft;
          lastY = event.layerY - event.currentTarget.offsetTop;
        }

        // begins new line
        ctx.beginPath();

        drawing = true;
      });
      element.bind('mousemove', function(event){
        if(drawing){
          // get current mouse position
          if(event.offsetX!==undefined){
            currentX = event.offsetX;
            currentY = event.offsetY;
          } else {
            currentX = event.layerX - event.currentTarget.offsetLeft;
            currentY = event.layerY - event.currentTarget.offsetTop;
          }

          draw(lastX, lastY, currentX, currentY);

          // set current coordinates to last one
          lastX = currentX;
          lastY = currentY;
        }

      });
      element.bind('mouseup', function(event){
        // stop drawing
        drawing = false;
      });

      // canvas reset
      function reset(){
       element[0].width = element[0].width; 
      }

      function draw(lX, lY, cX, cY){
        // line from
        ctx.moveTo(lX,lY);
        // to
        ctx.lineTo(cX,cY);
        // color
        ctx.strokeStyle = "#4bf";
        // draw it
        ctx.stroke();
      }
    }
  };
});

Et ensuite, vous pouvez l’utiliser sur une toile comme ceci:

<canvas drawing></canvas>

Voici une demo sur Plunkr: http://plnkr.co/aG4paH

83
JustGoscha

Angular convient parfaitement à l’écriture d’applications dans un style déclaratif. Une fois que vous avez touché l'élément canvas, vous ne pouvez pas aller plus loin avec le déclaratif et vous devez basculer vers un mécanisme d'écriture impératif. Si la majorité de votre application fournit une interface utilisateur, que vous définissez en HTML dans le reste de votre application, je vous encourage vivement à utiliser AngularJS. C'est un cadre incroyable pour ça. 

D'un autre côté, si la majorité de votre code doit se trouver à l'intérieur de l'élément canvas, alors AngularJS n'est peut-être pas l'outil idéal pour vous. Si vous insistez vraiment pour utiliser AngularJS pour la majorité de votre application, je vous suggérerais d'utiliser D3, qui est une excellente alternative et qui utilise SVG en coulisse (de nature déclarative et donc très utile pour AngularJS).

12
ganaraj

Il y a quelque temps, j'ai construit une directive configurable pour cela.

https://github.com/pwambach/angular-canvas-Painter

La directive crée l'élément de canevas et ajoute des gestionnaires pour les événements mousedown/mousemove/mouseup (et les événements tactiles correspondants) à l'élément. Les événements Mousedown et suivants Mousemove dessinent des courbes de Bézier avec la méthode canvasContext.quadraticCurveTo() pour des traits plus lisses (au lieu de simplement peindre des cercles pour chaque point). Pour plus de détails sur l’algorithme de dessin, consultez cet article: http://codetheory.in/html5-canvas-drawing-lines-with-smooth-edges/

5
pwambach

C'est une très belle implémentation! Je pourrais ajouter la méthode si vous voulez convertir la toile sur une image

    function convertCanvasToImage(canvas) {
       var image = new Image();
       image.src = canvas.toDataURL("image/png");
       return image;
    }

Cela vous fera une balise d'image avec la source comme élément base64.

J'espère que ça vous aide

1
Pablo Ascencao