【问题标题】:AngularJS Simple Signature Pad Directive (without jQuery)AngularJS 简单签名板指令(无 jQuery)
【发布时间】:2014-03-10 21:32:47
【问题描述】:

在 stackoverflow 的帮助下,我得到了一个简单的画布签名指令。问题是它适用于鼠标事件(mousedown、mouseup、mousemove),但不适用于触摸事件(touchstart、touchmove、touchend)。我的主应用程序模块和包含指令的模块中有 ngTouch。我希望你能帮助我。代码如下:

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

【问题讨论】:

  • 画布在移动设备上也能很好地工作,为什么需要触摸事件?
  • 这是用于简单签名的。我需要触摸事件,以便我可以在画布上绘图。上面的代码适用于鼠标事件(绘图适用于桌面),但不适用于触摸事件。
  • 好的,我已经确定 TOUCH 事件确实有效!麻烦在于绘图。但是什么?当我使用鼠标事件时,一切正常。是否为触摸事件添加了不同的 offsetx 属性?

标签: angularjs angularjs-directive


【解决方案1】:

如果有人需要一个简单的 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>

如果有人可以在这里看到一些错误的代码,请纠正我!

【讨论】:

  • 这是我自己在应用程序中的自定义逻辑。它与画布或绘图无关。这是我要附加签名的文档的 ID。我有一个临时数组,在那里我按文档 ID 保存签名。该代码是我在应用中使用的代码的直接副本。
  • @Zoneh 我正在尝试使用您的指令,但每次我得到空白图像。我没有将 dataurl 推送到 signaturetemp ,而是广播它并进入控制器。但数据 url 总是显示空白图片。
  • 在 saveToImage() 函数中将代码更改为 $scope.saveVal += 1 以支持多次清除和保存按钮点击。
  • 对我来说效果不佳。没有绘制标记。
猜你喜欢
  • 2013-10-26
  • 1970-01-01
  • 2015-08-04
  • 1970-01-01
  • 1970-01-01
  • 2017-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多