签名板离开画布时停止书写

问题描述 投票:0回答:1

我需要一个可以转换为图像的签名板。 我开始使用 VMAJSTER 的代码。

我删除了羽毛并添加了图像创建选项。

现在我遇到了问题,当书写(当鼠标按下时)并离开你仍在书写的区域时,当鼠标松开时。如何在离开画布时添加书写停止?

// SOURCE https://codepen.io/vmajster/pen/zYxowrv
// by VMAJSTER

(function() {
/*
To do:
Implement a more natural dragging movements with the formula from this script:

https://github.com/nashvail/SmootherTrello/blob/master/content.js

Read more at:
https://uxdesign.cc/how-to-fix-dragging-animation-in-ui-with-simple-math-4bbc10deccf7
*/

    var devicePixelRatio = window.devicePixelRatio || 1;

    var main = document.getElementById("main");

    var canvas = document.getElementById("paint");
    var ctx = canvas.getContext("2d");

    var sketch = document.getElementById("sketch");
    var sketch_style = getComputedStyle(sketch);

    var inputType = "mouse";

    canvas.width = parseInt(sketch_style.getPropertyValue("width"), 10);
    canvas.height = parseInt(sketch_style.getPropertyValue("height"), 10);

    // Creating a tmp canvas
    var tmp_canvas = document.createElement("canvas");
    var tmp_ctx = tmp_canvas.getContext("2d");

    tmp_canvas.id = "tmp_canvas";
    tmp_canvas.width = canvas.width;
    tmp_canvas.height = canvas.height;

    sketch.appendChild(tmp_canvas);

    var mouse = {
        x: 0,
        y: 0
    };

    // Pen Points
    var ppts = [];

    /* Mouse Capturing Work */
    tmp_canvas.addEventListener("mousemove", function(e) {
            mouse.x = typeof e.offsetX !== "undefined" ? e.offsetX : e.layerX;
            mouse.y = typeof e.offsetY !== "undefined" ? e.offsetY : e.layerY;

          e.stopPropagation();
          e.preventDefault();
          return false;
        }, false);

    /* Drawing */
    tmp_ctx.lineWidth = 1.5 * devicePixelRatio; /* Size of the drawn line * devicePixelRatio */
    tmp_ctx.lineJoin = "round";
    tmp_ctx.lineCap = "round";
    tmp_ctx.strokeStyle = "rgba(0, 0, 0, 0.8)";
    tmp_ctx.fillStyle = "rgba(0, 0, 0, 0.8)";

    tmp_canvas.addEventListener("mousedown", function(e) {

        tmp_canvas.addEventListener("mousemove", onPaint, false);

            mouse.x = typeof e.offsetX !== "undefined" ? e.offsetX : e.layerX;
            mouse.y = typeof e.offsetY !== "undefined" ? e.offsetY : e.layerY;

            ppts.push({
                x: mouse.x,
                y: mouse.y
            });

            onPaint(e);
        }, false);

    tmp_canvas.addEventListener("mouseup", function() {
        if (inputType === "touch") {
        }
        else {
          inputType = "mouse";
        }

            tmp_canvas.removeEventListener("mousemove", onPaint, false);

            // Writing to real canvas now
            ctx.drawImage(tmp_canvas, 0, 0);

            // Clearing tmp canvas
            tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);

            // Emptying up Pen Points
            ppts = [];
        }, false);

    var onPaint = function(e) {
        // Saving all the points in an array
        ppts.push({
            x: mouse.x,
            y: mouse.y
        });

        if (ppts.length < 3) {
            var b = ppts[0];
            tmp_ctx.beginPath();
            tmp_ctx.arc(b.x, b.y, tmp_ctx.lineWidth / 2, 0, Math.PI * 2, !0);
            tmp_ctx.fill();
            tmp_ctx.closePath();

            e.preventDefault();
            e.stopPropagation();
            return false;
        }

        // Tmp canvas is always cleared up before drawing.
        tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);

        tmp_ctx.beginPath();
        tmp_ctx.moveTo(ppts[0].x, ppts[0].y);

        for (var i = 1; i < ppts.length - 2; i++) {
            var c = (ppts[i].x + ppts[i + 1].x) / 2;
            var d = (ppts[i].y + ppts[i + 1].y) / 2;

            tmp_ctx.quadraticCurveTo(ppts[i].x, ppts[i].y, c, d);
        }

        // For the last 2 points
        tmp_ctx.quadraticCurveTo(ppts[i].x, ppts[i].y, ppts[i + 1].x, ppts[i + 1].y);

        tmp_ctx.stroke();

        e.preventDefault();
        e.stopPropagation();
        return false;
    };

    // Clear canvas
    document.getElementById("clear").onmousedown = document.getElementById("clear").ontouchstart = function() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    };
    
    // Save canvas
    document.getElementById("create").onmousedown = document.getElementById("create").ontouchstart = function() {
        if(!!document.getElementById("signature") === false) {
            var sig_image = document.createElement('img');
            sig_image.id = 'signature';
            document.getElementById("actions").after(sig_image);
        }
        else {
            var sig_image = document.getElementById("signature");
        }
        var paint = document.getElementById("paint");
        var p_image = paint.toDataURL("image/png");        
        sig_image.src = p_image;        
    };

    function touchHandler(event) {
        var touch = event.changedTouches[0];
        inputType = "touch";

        var simulatedEvent = document.createEvent("MouseEvent");
        simulatedEvent.initMouseEvent({ touchstart: "mousedown", touchmove: "mousemove", touchend: "mouseup" }[event.type], true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);

        touch.target.dispatchEvent(simulatedEvent);

        event.preventDefault();
        event.stopPropagation();
        return false;
    }

    main.addEventListener("touchstart", touchHandler, true);
    main.addEventListener("touchmove", touchHandler, true);
    main.addEventListener("touchend", touchHandler, true);

/*
    main.addEventListener("touchstart", function(e) {
        e.preventDefault();
        e.stopPropagation();
        return false;
    }, false);
*/
})();
:root {
    background-color: #F3F3F3;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    -o-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    -moz-tap-highlight-color: transparent;
    -ms-tap-highlight-color: transparent;
    -o-tap-highlight-color: transparent;
    tap-highlight-color: transparent;
}

*,
:before,
:after {
    -webkit-box-sizing: inherit;
    -moz-box-sizing: inherit;
    -ms-box-sizing: inherit;
    -o-box-sizing: inherit;
    box-sizing: inherit;
}

body {
    margin: 0;
    padding: 0;
}

#sketch {
    left: 0;
    right: 0;
    bottom: 0;
    top: 0;
    display: block;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
    contain: strict;
}

canvas {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    top: 0;
    display: block;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
    contain: strict;
}


canvas, #clear {
    -webkit-touch-action: manipulation;
    -moz-touch-action: manipulation;
    -ms-touch-action: manipulation;
    -o-touch-action: manipulation;
    touch-action: manipulation;
}
#main {
    background: #ccc;
    padding: 20px;
}
#sketch {
    display: block;
    position: relative;
    border: 1px solid #000;
    width: 500px;
    height: 180px;
    background: #fff;
    margin: 0 auto;
}
#sketch:before {
    position: absolute;
    display: block;
    height: 1px;
    background: transparent;
    border-bottom: 1px solid #aaa;
    padding: 20px;
    bottom: 40px;
    left: 20px;
    right: 20px;
    top: auto;
    content: "";   
}
#sketch_redzone {
    display: block;
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    border: 20px solid rgba(255,0,0,0.1);
}

#actions {
    display: block;
    text-align: center;
}

#signature {
    display: block;
    margin: 0 auto;
}
<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Signature</title>
  </head>

  <body>
    <main id="main" role="main" tabindex="0">
      <div id="sketch">
        <div id="sketch_redzone"></div>
        <canvas id="paint"></canvas>
      </div>
      <div id="actions">
        <button type="button" id="clear">Clear</button>
        <button type="button" id="create">Create PNG</button>
      </div>
    </main>
  </body>
</html>

javascript canvas touch signature
1个回答
0
投票

让它工作,但我不确定这是否是最好的方法。 我将“mouseup”的事件监听器函数的操作存储到预定义函数中,并在“mouseleave”时触发该函数。

如果有更好的方法请评论,否则我认为还可以

function stopDrawing() {
    if (inputType === "touch") {
    }
    else {
      inputType = "mouse";
    }

        tmp_canvas.removeEventListener("mousemove", onPaint, false);

        // Writing to real canvas now
        ctx.drawImage(tmp_canvas, 0, 0);

        // Clearing tmp canvas
        tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);

        // Emptying up Pen Points
        ppts = [];
}

tmp_canvas.addEventListener("mouseup", function() {
    stopDrawing();
    }, false);

tmp_canvas.addEventListener("mouseleave", function(e) {
    stopDrawing();
}, false);
© www.soinside.com 2019 - 2024. All rights reserved.