Is there already a canvas drawing directive for An

2019-01-16 03:07发布

问题:

Is there already a directive to draw/paint things on a canvas? So you can implement something like Paint or even something bigger like Photoshop etc., but a very basic example would suffice.

I haven't found one in my search and if there's already one that is considered best practice I would like to use it. Else I have to implement one myself.

回答1:

Ok I did one and it is actually pretty easy:

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

And then you can use it on canvas like this:

<canvas drawing></canvas>

Here's a demo on Plunkr: http://plnkr.co/aG4paH



回答2:

Angular is ideally suited for writing applications in declarative style. Once you hit the canvas element you cannot go any further with declarative and you have to switch towards an imperative way of writing mechanism. If the majority of your application is providing UI, which you define in html in the rest of your application I would highly encourage you to use AngularJS. Its an amazing framework for that.

On the other hand if the majority of your code is going to be inside the canvas element, then perhaps AngularJS is not the ideal tool for you. If you really insist on using AngularJS for the majority of your application I would suggest you to consider using something like D3 which is an excellent alternative and uses SVG behind the scenes ( which is declarative in nature and hence a great sidekick for AngularJS ).



回答3:

Some time ago i built a configurable directive for that.

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

The directive creates the canvas element and adds handlers for mousedown/mousemove/mouseup events (and corresponding touch events) to the element. Mousedown and following mousemove events draw bezier curves with the canvasContext.quadraticCurveTo() method for smoother strokes (instead of just painting circles for every point). For details on the drawing algorithm have a look at this article: http://codetheory.in/html5-canvas-drawing-lines-with-smooth-edges/



回答4:

That's a really nice implementation! I could add the method if you want to convert the canvas on an image

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

This will make you a image tag with the source as base64 element.

Hope it helps you