javascript - 我怎样才能使这个 HTML5 Canvas 绘画应用程序同时适用于触摸和鼠标事件?

标签 javascript android html html5-canvas

这是我正在尝试做的事情的源代码:

http://jsfiddle.net/3nGtM/

Javascript:

    window.addEventListener('load', function () {
    // get the canvas element and its context
    var canvas = document.getElementById('sketchpad');
    var context = canvas.getContext('2d');

    // create a drawer which tracks touch movements
    var drawer = {
        isDrawing: false,
        touchstart: function (coors) {
            context.beginPath();
            context.moveTo(coors.x, coors.y);
            this.isDrawing = true;
        },
        touchmove: function (coors) {
            if (this.isDrawing) {
                context.lineTo(coors.x, coors.y);
                context.stroke();
            }
        },
        touchend: function (coors) {
            if (this.isDrawing) {
                this.touchmove(coors);
                this.isDrawing = false;
            }
        }
    };
    // create a function to pass touch events and coordinates to drawer
    function draw(event) {
        // get the touch coordinates
        var coors = {
            x: event.targetTouches[0].pageX,
            y: event.targetTouches[0].pageY
        };
        // pass the coordinates to the appropriate handler
        drawer[event.type](coors);
    }

    // attach the touchstart, touchmove, touchend event listeners.
    canvas.addEventListener('touchstart', draw, false);
    canvas.addEventListener('touchmove', draw, false);
    canvas.addEventListener('touchend', draw, false);

    // prevent elastic scrolling
    document.body.addEventListener('touchmove', function (event) {
        event.preventDefault();
    }, false); // end body.onTouchMove

}, false); // end window.onLoad

HTML:

<body>
    <div id="container">
        <canvas id="sketchpad" width="400" height="400">Sorry, your browser is not supported.</canvas>
    </div>
</body>

CSS:

body {
    margin:0;
    padding:0;
    font-family:Arial;
}
#container {
    position:relative;
}
#sketchpad {
    border: 1px solid #000;
}

我尝试为鼠标按下/向上/移动添加事件监听器,但这些似乎不起作用。

或者,如果有人对可在计算机和平板电脑上运行的开源 Canvas 绘画应用程序有任何建议,我宁愿使用它。

到目前为止,唯一脱颖而出的是 https://github.com/PlayMyCode/SkyBrush但不幸的是,它不适用于 Android 平板电脑(至少我已经尝试过的平板电脑)。

最佳答案

检查 modified fiddle

我添加了一种检测何时在触摸设备中运行的方法,以及一个将鼠标事件映射到触摸事件的开关。

另请注意,当发生 touchend 时,我们需要使用 event.changedTouches 来正确获取 coors

window.addEventListener('load', function () {
// get the canvas element and its context
var canvas = document.getElementById('sketchpad');
var context = canvas.getContext('2d');

// create a drawer which tracks touch movements
var drawer = {
    isDrawing: false,
    touchstart: function (coors) {
        context.beginPath();
        context.moveTo(coors.x, coors.y);
        this.isDrawing = true;
    },
    touchmove: function (coors) {
        if (this.isDrawing) {
            context.lineTo(coors.x, coors.y);
            context.stroke();
        }
    },
    touchend: function (coors) {
        if (this.isDrawing) {
            this.touchmove(coors);
            this.isDrawing = false;
        }
    }
};
// create a function to pass touch events and coordinates to drawer
function draw(event) { 
    var type = null;
    // map mouse events to touch events
    switch(event.type){
        case "mousedown":
                event.touches = [];
                event.touches[0] = { 
                    pageX: event.pageX,
                    pageY: event.pageY
                };
                type = "touchstart";                  
        break;
        case "mousemove":                
                event.touches = [];
                event.touches[0] = { 
                    pageX: event.pageX,
                    pageY: event.pageY
                };
                type = "touchmove";                
        break;
        case "mouseup":                
                event.touches = [];
                event.touches[0] = { 
                    pageX: event.pageX,
                    pageY: event.pageY
                };
                type = "touchend";
        break;
    }        

    // touchend clear the touches[0], so we need to use changedTouches[0]
    var coors;
    if(event.type === "touchend") {
        coors = {
            x: event.changedTouches[0].pageX,
            y: event.changedTouches[0].pageY
        };
    }
    else {
        // get the touch coordinates
        coors = {
            x: event.touches[0].pageX,
            y: event.touches[0].pageY
        };
    }
    type = type || event.type
    // pass the coordinates to the appropriate handler
    drawer[type](coors);
}

// detect touch capabilities
var touchAvailable = ('createTouch' in document) || ('ontouchstart' in window);

// attach the touchstart, touchmove, touchend event listeners.
if(touchAvailable){
    canvas.addEventListener('touchstart', draw, false);
    canvas.addEventListener('touchmove', draw, false);
    canvas.addEventListener('touchend', draw, false);        
}    
// attach the mousedown, mousemove, mouseup event listeners.
else {
    canvas.addEventListener('mousedown', draw, false);
    canvas.addEventListener('mousemove', draw, false);
    canvas.addEventListener('mouseup', draw, false);
}

// prevent elastic scrolling
document.body.addEventListener('touchmove', function (event) {
    event.preventDefault();
}, false); // end body.onTouchMove

}, false); // end window.onLoad

关于javascript - 我怎样才能使这个 HTML5 Canvas 绘画应用程序同时适用于触摸和鼠标事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16629086/

相关文章:

javascript - 访问 chrome/firefox 图像缓存

c# - 将名字中的第一个和第三个字母大写,例如 McArthur 或 McMinn

html - CSS缩小浏览器窗口, float 空白

javascript - Javascript 中的左 trim

javascript - Piwik - 如何跟踪点击事件?

javascript - for-await-of 是否等待当前迭代完成后再进行下一次迭代?

android - 启用我的位置图标 Googlemap v2

android - 在 iOS 和 Android 上点赞支付

android - 在android studio中执行自定义的独立gradle任务

regex - 让 HTML5 的输入模式属性忽略大小写