创建一个响应鼠标点击和触摸的画布

时间:2016-06-13 14:05:00

标签: html5 canvas touch mouselistener

我有一个画布将响应鼠标点击(或直到我更改了代码),并且我正在尝试实现一部分将响应触摸的脚本(ipad,智能手机,平板电脑等)。但是,我被困在两者之间;当我尝试一种方法时,它会打破另一种方法,反之亦然。

思想?

<script type="text/javascript">
    var canvas, ctx, canvasX, canvasY, mouseIsDown = 0;

    function init() {
        canvas = document.getElementById("can");
        ctx = canvas.getContext("2d");

        canvas.addEventListener("mousedown", mouseDown, false);
        canvas.addEventListener("mousemove", mouseXY, false);
        canvas.addEventListener("touchstart", touchDown, false);
        canvas.addEventListener("touchmove", touchXY, true);
        canvas.addEventListener("touchend", touchUp, false);

        document.body.addEventListener("mouseup", mouseUp, false);
        document.body.addEventListener("touchcancel", touchUp, false);
    }

    function mouseUp() {
        mouseIsDown = 0;
        mouseXY();
    }

    function touchUp() {
        mouseIsDown = 0;
        // no touch to track, so just show state
        showPos();
    }

    function mouseDown() {
        mouseIsDown = 1;
        mouseXY();
    }

    function touchDown() {
        mouseIsDown = 1;
        touchXY();
    }

    function mouseXY(e) {
        if (!e)
            var e = event;
        canvasX = e.pageX - canvas.offsetLeft;
        canvasY = e.pageY - canvas.offsetTop;
        showPos();
    }

    function touchXY(e) {
        if (!e)
            var e = event;
        e.preventDefault();
        canvasX = e.targetTouches[0].pageX - canvas.offsetLeft;
        canvasY = e.targetTouches[0].pageY - canvas.offsetTop;
        showPos();
    }

function color(obj) {
    switch (obj.id) {
        case "green":
            x = "green";
            break;
        case "blue":
            x = "blue";
            break;
        case "red":
            x = "red";
            break;
        case "yellow":
            x = "yellow";
            break;
        case "orange":
            x = "orange";
            break;
        case "black":
            x = "black";
            break;
        case "white":
            x = "white";
            break;
    }
    if (x == "white") y = 14;
    else y = 2;

}

function draw() {
    ctx.beginPath();
    ctx.moveTo(prevX, prevY);
    ctx.lineTo(currX, currY);
    ctx.strokeStyle = x;
    ctx.lineWidth = y;
    ctx.stroke();
    ctx.closePath();
}

function erase() {
    var m = confirm("Want to clear");
    if (m) {
        ctx.clearRect(0, 0, w, h);
        document.getElementById("canvasimg").style.display = "none";
    }
}

function save() {
    document.getElementById("canvasimg").style.border = "2px solid";
    var dataURL = canvas.toDataURL();
    document.getElementById("canvasimg").src = dataURL;
    document.getElementById("canvasimg").style.display = "inline";
}

function findxy(res, e) {
    if (res == 'down') {
        prevX = currX;
        prevY = currY;
        currX = e.clientX - canvas.offsetLeft;
        currY = e.clientY - canvas.offsetTop;

        flag = true;
        dot_flag = true;
        if (dot_flag) {
            ctx.beginPath();
            ctx.fillStyle = x;
            ctx.fillRect(currX, currY, 2, 2);
            ctx.closePath();
            dot_flag = false;
        }
    }
    if (res == 'up' || res == "out") {
        flag = false;
    }
    if (res == 'move') {
        if (flag) {
            prevX = currX;
            prevY = currY;
            currX = e.clientX - canvas.offsetLeft;
            currY = e.clientY - canvas.offsetTop;
            draw();
        }
    }
}
</script>

1 个答案:

答案 0 :(得分:0)

您没有将事件对象传递给任何处理程序:

此:

function mouseUp() {
    mouseIsDown = 0;
    mouseXY();
}

应该是:

function mouseUp(e) {  // <- e
    mouseIsDown = 0;
    mouseXY(e);        // e ->
}

(和其他人类似)

使用pageX/Y也要小心,因为它们是not part of any standard

  

此功能不符合标准,不符合标准。不要   在面向Web的生产站点上使用它:它不会适用于所有人   用户。两者之间可能存在很大的不兼容性   实现和行为可能在未来发生变化。

更好地使用getBoundingClientRect()结合clientX/Y

function mouseXY(e) {
    var rect = canvas.getBoundingClientRect();
    canvasX = e.clientX - rect.left;
    canvasY = e.clientY - rect.top;
    showPos();
}

您还可以通过从触摸处理程序传入触摸对象来合并mouseXY() / touchXY()

function touchDown(e) {
    mouseIsDown = 1;
    mouseXY(e.targetTouches[0]);
}