2014-03-05 63 views
1

在stackoverflow的幫助下,我得到了一個簡單的畫布簽名指令。問題在於它適用於鼠標事件(mousedown,mouseup,mousemove),但不適用於觸摸事件(touchstart,touchmove,touchend)。我在我的主應用程序模塊和保存該指令的模塊中都有ngTouch。我希望你能幫助我。下面的代碼:AngularJS Simple Signature Pad指令(不含jQuery)

var sig = angular.module('signature', ['ngTouch']); 

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

      ctx.canvas.width = window.innerWidth - 20; 
      var tempCanvas = document.createElement('nanavas'); 

      // 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.on('touchstart', function (event) { 
       if (event.offsetX !== undefined) { 
        lastX = event.offsetX; 
        lastY = event.offsetY; 
       } else { 
        lastX = event.layerX - event.currentTarget.offsetLeft; 
        lastY = event.layerY - event.currentTarget.offsetTop; 
       } 

       // begins new line 
       ctx.beginPath(); 

       drawing = true; 
      }); 
      element.on('touchmove', 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; 
       } 
      }); 

      $document.on('touchend', 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 = "#000"; 
       // draw it 
       ctx.stroke(); 
      } 
     } 
    }; 
}]); 
+0

帆布在移動設備上也很棒,爲什麼你需要觸摸事件? –

+0

這是簡單簽名的必要條件。我需要觸摸事件,所以我可以在畫布上畫畫。上面的代碼適用於鼠標事件(繪圖在桌面上工作),但不適用於觸摸事件。 – Zoneh

+0

好的,我已經確定TOUCH活動能夠發揮作用!麻煩必須與繪圖。但是什麼?當我使用鼠標事件時,一切正常。膠印特性爲touchevents添加了不同的方式嗎? – Zoneh

回答

3

如果有人需要爲AngularJS一個簡單的簽名指令,這是我最終想出了:

var sig = angular.module('signature', []); 

sig.controller('signatureCtrl', ['$scope', function ($scope) { 
    $scope.clearVal = 0; 
    $scope.saveVal = 0; 

    $scope.clear = function() { 
     $scope.clearVal += 1; //On this value change directive clears the context 
    } 

    $scope.saveToImage = function() { 
     $scope.saveVal = 1; //On this value change directive saves the signature 
    } 
}]); 

sig.directive("signatureDir", ['$document', '$log', '$rootScope', function ($document, $log, $rootScope) { 
    return { 
     restrict: "A", 
     link: function (scope, element, attrs) { 
      var ctx = element[0].getContext('2d'); 

      ctx.canvas.width = window.innerWidth - 30; 

      // the last coordinates before the current move 
      var lastPt; 

      function getOffset(obj) { 
       return { left: 15, top: 116 }; //Got a fixed offset 
      } 

      attrs.$observe("value", function (newValue) { 
       ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); 
      }); 

      attrs.$observe("saveVal", function (newValue, dnid) { 
       var imagedata = ctx.canvas.toDataURL(); 
       $rootScope.signatureTemp.push({'dnid':dnid, 'signature':imagedata}); 
      }); 

      element.on('touchstart', function (e) { 
       e.preventDefault(); 
       ctx.fillRect(e.touches[0].pageX - getOffset(element).left, e.touches[0].pageY - getOffset(element).top, 2, 2); 
       lastPt = { x: e.touches[0].pageX - getOffset(element).left, y: e.touches[0].pageY - getOffset(element).top }; 
      }); 
      element.on('touchmove', function (e) { 
       e.preventDefault(); 
       if (lastPt != null) { 
        ctx.beginPath(); 
        ctx.moveTo(lastPt.x, lastPt.y); 
        ctx.lineTo(e.touches[0].pageX - getOffset(element).left, e.touches[0].pageY - getOffset(element).top); 
        ctx.stroke(); 
       } 
       lastPt = { x: e.touches[0].pageX - getOffset(element).left, y: e.touches[0].pageY - getOffset(element).top }; 
      }); 

      element.on('touchend', function (e) { 
       e.preventDefault(); 
       lastPt = null; 
      }); 
     } 
    }; 
}]); 

標記:

<div ng-controller="signatureCtrl"> 
    <ul class="list-group"> 
     <h3 style="padding-left: 15px;">Signature</h3> 
     <li class="list-group-item"> 
      <canvas saveVal="{{ saveVal }}" value="{{ clearVal }}" style="border: 1px solid black;" id="canvas1" width="200" height="200" signatureDir></canvas> 
      <button class="btn btn-warning" ng-click="clear()">Clear</button> 
      <button class="btn btn-primary" ng-click="ok()">Save</button> 
     </li> 
    </ul> 
</div> 

如果有人在這裏可以看到一些不好的代碼,請糾正我!

+0

嗨,這是什麼dnid – Justin

+0

這是我在應用程序中的自定義邏輯。它與畫布或繪畫無關。這是我附加簽名的文檔的ID。我有一個臨時數組,並在那裏我通過文檔ID保存簽名。該代碼是我在我的應用程序中使用的代碼的直接副本。 – Zoneh

+0

@Zoneh我試圖使用你的指令,但每次我得到空白圖像。而不是推動dataurl signaturetemp,我正在廣播它,並得到控制器。但數據網址始終顯示空白圖像。 –