是否已经为AngularJS制作了画布绘图指令?

Jus*_*cha 50 html5 drawing canvas paint angularjs

是否已有指令在画布上绘制/绘制内容?所以你可以实现像Paint这样的东西甚至像Photoshop等更大的东西,但是一个非常基本的例子就足够了.

我没有在我的搜索中找到一个,如果已经有一个被认为是最佳实践,我想使用它.否则我必须自己实施一个.

Jus*_*cha 83

好的,我做了一个,实际上非常简单:

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();
      }
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

然后你就可以在画布上使用它:

<canvas drawing></canvas>
Run Code Online (Sandbox Code Playgroud)

这是关于Plunkr 的演示:http://plnkr.co/aG4paH

  • 我还在JsPerf中为画布清除编写了一个测试用例:因为我知道如何清理画布的两种方法:http://jsperf.com/canvas-clearing-test (2认同)
  • 我将此添加到我的Angular/Common repo中,并添加了一些增强功能:http://clouddueling.github.io/angular-common/ (2认同)

gan*_*raj 12

Angular非常适合以声明式方式编写应用程序.一旦你点击了canvas元素,你就无法继续使用声明,你必须转向一种必要的写作机制.如果您的大部分应用程序都提供了UI,您在应用程序的其余部分中使用html定义,我强烈建议您使用AngularJS.它是一个惊人的框架.

另一方面,如果你的大部分代码都在canvas元素中,那么AngularJS可能不适合你.如果你真的坚持在大多数应用程序中使用AngularJS,我建议你考虑使用类似D3的东西,这是一个很好的选择,并在幕后使用SVG(这是声明性的,因此是AngularJS的一个很好的搭档).

  • 上述答案具有误导性.AngularJS(和声明性编程)不会妨碍画布的使用.这就是你如何解决问题.许多流行的图表和图形JS库开始通过为其组件提供指令来支持AngularJS.因此,命令性代码隐藏在指令的可重用实现中.这是AngularJS的美妙之处,您可以编写一次命令式代码并以声明方式使用它,如下面的解决方案所示. (12认同)
  • 答案不是误导.如果你写了一堆JQuery spaghetti并将它隐藏在一个指令的构造函数中,你就没有"编写一个Angular Directive".你已经编写了一堆命令性的垃圾,并通过以类似*Angular的方式组织它来安慰自己.这就是代码*可以用Angular正确编写的代码.但是没有$ digest循环可以监视画布的状态,也没有像双向Angular数据绑定到画布那样的东西.您可以通过在命令中包含命令性画布代码来伪装.但这不会使它成为Angular. (7认同)
  • 这里有一个很好的D3 Angular教程:http://www.ng-newsletter.com/posts/d3-on-angular.html (2认同)

pwa*_*ach 5

前段时间我为此构建了一个可配置的指令.

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

该指令创建canvas元素,并为该元素添加mousedown/mousemove/mouseup事件(以及相应的触摸事件)的处理程序.Mousedown和以下mousemove事件使用canvasContext.quadraticCurveTo()更平滑的笔划方法绘制贝塞尔曲线 (而不是仅为每个点绘制圆圈).有关绘图算法的详细信息,请查看本文:http://codetheory.in/html5-canvas-drawing-lines-with-smooth-edges/