2

I have a form that needs to be signed by three people. I initially set it up to be signed by one person, but found out I needed three. I can't get all three to work.

Canvas Containers:

<div class="rowElem">
    <div id="container2">
    </div>
</div> 
<div class="rowElem">
    <div id="container3">
    </div>
</div>
<div class="rowElem">
    <div id="container4">
    </div>
</div> 

Javascript:

<script>


       (function (ns) {
    "use strict";

    ns.SignatureControl = function (options) {
        var containerId = options && options.canvasId || "container2",
            callback = options && options.callback || {},
            label = options && options.label || "Teacher Signature",
            cWidth = options && options.width || "300px",
            cHeight = options && options.height || "300px",
            btnClearId,
            canvas,
            ctx;

        function initCotnrol() {
            createControlElements();
            wireButtonEvents();
            canvas = _("signatureCanvas");
            canvas.addEventListener("mousedown", pointerDown, false);
            canvas.addEventListener("mouseup", pointerUp, false);
            ctx = canvas.getContext("2d");            
        }

        function createControlElements() {            
            var signatureArea = document.createElement("div"),
                labelDiv = document.createElement("div"),
                canvasDiv = document.createElement("div"),
                canvasElement = document.createElement("canvas"),
                buttonsContainer = document.createElement("div"),
                buttonClear = document.createElement("button");

            labelDiv.className = "signatureLabel";
            labelDiv.textContent = label;

            canvasElement.id = "signatureCanvas";
            canvasElement.clientWidth = cWidth;
            canvasElement.clientHeight = cHeight;
            canvasElement.style.border = "solid 2px black";
            canvasElement.style.background = "white";

            buttonClear.id = "btnClear";
            buttonClear.textContent = "Clear Signature Panel";

            canvasDiv.appendChild(canvasElement);
            buttonsContainer.appendChild(buttonClear);

            signatureArea.className = "signatureArea";
            signatureArea.appendChild(labelDiv);
            signatureArea.appendChild(canvasDiv);
            signatureArea.appendChild(buttonsContainer);

            _(containerId).appendChild(signatureArea);
        }

        function pointerDown(evt) {
            ctx.beginPath();
            ctx.moveTo(evt.offsetX, evt.offsetY);
            canvas.addEventListener("mousemove", paint, false);
        }

        function pointerUp(evt) {
            canvas.removeEventListener("mousemove", paint);
            paint(evt);
        }

        function paint(evt) {
            ctx.lineTo(evt.offsetX, evt.offsetY);
            ctx.stroke();
        }

        function wireButtonEvents() {
            var btnClear = _("btnClear");
            btnClear.addEventListener("click", function () {
                ctx.clearRect(0, 0, canvas.width, canvas.height);
            }, false);
        }

        function getSignatureImage() {
            return ctx.getImageData(0, 0, canvas.width, canvas.height).data;
        }

        return {
            init: initCotnrol,
            getSignatureImage: getSignatureImage
        };
    }
})(this.ns = this.ns || {});

This is the initiator script:

    function teacherSig() {
            var signature = new ns.SignatureControl({ containerId: 'container2', callback: function () {
                } 
            });
            signature.init();
            _('btnClear').className = "greyishBtn";
        }

        window.addEventListener('DOMContentLoaded', teacherSig, false);
</script>

The "_" are a variable set in another file for document.getElementById - I already know that works, I'm using it in all my js files.

I tried duplicating the initiator script and changing the function name/element names, but it did not do any good.

Any help would be greatly appreciated.

If anyone knows a better way to do this, I can try that as well. I'm running out of time on this project, and this was something the client added on in the end. If anyone knows another solution, a plugin or anything for multiple, I'm open to that as well.

4

1 回答 1

2

当您要求更好的方法时,我建议您为此使用easyCanvasJS,它设置了大多数非平凡的事情,但允许您像往常一样使用上下文和画布。

在线小提琴在这里

对于三个签名框,您只需执行以下操作(保留原始 HTML 代码,如帖子所示:

/// setup three canvases referencing parent Id and setting size:
var ez1 = new easyCanvas('container2', 350, 100),
    ez2 = new easyCanvas('container3', 350, 100),
    ez3 = new easyCanvas('container4', 350, 100);

/// common handler when mouse is held down, this = current easyCanvas instance
ez1.onmousemove =  ez2.onmousemove =  ez3.onmousemove = function(x, y) {
    /// instead of this.ctx.moveTo etc.. :
    this.strokeLine(this.prevX, this.prevY, x, y);
}

现在您有了三个可以登录的框。这strokeLine是一个用于画线的速记函数,prevX/Y存储在easyCanvas实例内部,x并且y已经相对于画布进行了更正。

(要访问画布,您只需引用ez.canvas和获取上下文ez.ctxez.context)。

为了演示,我在 HTML 中添加了一些保存按钮,以便您将画布保存为图像:

save1.addEventListener('click', function(){download(ez1,1)}, false);
save2.addEventListener('click', function(){download(ez2,2)}, false);
save3.addEventListener('click', function(){download(ez3,3)}, false);

function download(ez, index) {
    /// show a save dialog with filename to save image here as png
    ez.download('Signature' + index + '.png');
}

如果您在内部需要数据,则可以这样做:

ez.canvas.toDataURL();

而不是每个实例。

更新 - 例如:在单个保存按钮上:

function saveSignatures() {

    var sig1 = ez1.canvas.toDataURL();
    var sig2 = ez2.canvas.toDataURL();
    var sig3 = ez3.canvas.toDataURL();

    saveByAjax(sig1, sig2, sig3); // some ajax function to save the data
}

免责声明:用于 JavaScript 的easyCanvas是我自己制作的,是免费的,并在 GPL-3.0 下获得许可。

于 2013-08-01T16:02:41.610 回答