web-dev-qa-db-ja.com

AngularJS用のキャンバス描画ディレクティブはすでにありますか?

キャンバスに物を描く/ペイントするためのディレクティブはすでにありますか?したがって、ペイントのようなもの、またはPhotoshopなどのような大きなものを実装することもできますが、非常に基本的な例で十分です。

私は検索で1つを見つけていません。すでにベストプラクティスと考えられるものがあれば、それを使いたいです。それ以外の場合は、自分で実装する必要があります。

50
JustGoscha

わかりました、実際にかなり簡単です:

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();
      }
    }
  };
});

そして、次のようにキャンバス上で使用できます:

<canvas drawing></canvas>

Plunkrのdemohttp://plnkr.co/aG4paH

83
JustGoscha

Angularは、宣言スタイルでアプリケーションを作成するのに最適です。キャンバス要素にヒットすると、宣言でこれ以上進むことができず、メカニズムを記述するための命令的な方法に切り替える必要があります。アプリケーションの大部分がUIを提供している場合は、アプリケーションの残りの部分でhtmlで定義しますが、AngularJSを使用することを強くお勧めします。そのためのすばらしいフレームワークです。

一方、コードの大部分がcanvas要素内にある場合、AngularJSはおそらく理想的なツールではありません。アプリケーションの大部分でAngularJSの使用を本当に主張する場合、優れた代替手段であり、SVGを舞台裏で使用するD3のようなものを使用することを検討することをお勧めします(本質的に宣言的であり、したがってAngularJSの素晴らしい相棒です)。

12
ganaraj

しばらく前に、そのための構成可能なディレクティブを作成しました。

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

ディレクティブは、キャンバス要素を作成し、mousedown/mousemove/mouseupイベント(および対応するタッチイベント)のハンドラーを要素に追加します。 Mousedownイベントとそれに続くmousemoveイベントでは、canvasContext.quadraticCurveTo()メソッドを使用してベジェ曲線を描画し、ストロークをより滑らかにします(すべてのポイントに円を描くだけではありません)。描画アルゴリズムの詳細については、この記事をご覧ください。 http://codetheory.in/html5-canvas-drawing-lines-with-smooth-edges/

5
pwambach

それは本当に素晴らしい実装です!画像のキャンバスを変換する場合は、メソッドを追加できます

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

これにより、base64要素としてソースを持つイメージタグが作成されます。

それがあなたを助けることを願っています

1
Pablo Ascencao