我想用我的Nexus 4在画布上画线。它在我的电脑上完美运行,但在我的Nexus 4上它会跳过线条。
你可以try it here。
我认为问题是touchend
事件经常被触发。
为什么会这样?
<!DOCTYPE html>
<html>
<head>
<title>Write Mathematical Formulas</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/> <!--320-->
<style type="text/css">
#myCanvas
{
border = 1px solid black;
}
#controls
{
bottom: 0;
left: 0;
position: absolute;
width: 100%;
}
</style>
</head>
<body>
<div id="container"></div>
<canvas id = "myCanvas"></canvas>
<input type="button" style="z-index:2; position:absolute; top:0; left:0" value="Clear" onclick="clearDr()"/>
<script src="js/recognition.js"></script>
</body>
</html>
var canvasWidth = document.documentElement.getElementsByTagName('body')[0].clientWidth - 1;
var canvasHeight = document.documentElement.clientHeight - 25;
var context = document.getElementById('myCanvas').getContext("2d");
var canvas = document.getElementById('myCanvas');
canvas.setAttribute('width', canvasWidth);
canvas.setAttribute('height', canvasHeight);
context = canvas.getContext("2d");
function mouseDownEventHandler(e){
paint = true;
if(paint){
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, false);
redraw();
}
}
function touchstartEventHandler(e){
paint = true;
if(paint){
addClick(e.touches[0].pageX - this.offsetLeft, e.touches[0].pageY - this.offsetTop, false);
redraw();
}
}
function mouseUpEventHandler(e){
paint = false;
}
function mouseMoveEventHandler(e){
if(paint){
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
redraw();
}
}
function touchMoveEventHandler(e){
if(paint){
addClick(e.touches[0].pageX - this.offsetLeft, e.touches[0].pageY - this.offsetTop, true);
redraw();
}
}
function addClick(x, y, dragging)
{
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
function redraw(){
// Clears the canvas
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
context.strokeStyle = "#df4b26";
context.lineJoin = "round";
context.lineWidth = 5;
for(var i=0; i < clickX.length; i++) {
context.beginPath();
if(clickDrag[i] && i){
context.moveTo(clickX[i-1], clickY[i-1]);
}else{
context.moveTo(clickX[i]-1, clickY[i]);
}
context.lineTo(clickX[i], clickY[i]);
context.closePath();
context.stroke();
}
}
function clearDr() {
context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas
clickX = new Array();
clickY = new Array();
clickDrag = new Array();
}
canvas.addEventListener('mousedown', mouseDownEventHandler);
canvas.addEventListener('touchstart', touchstartEventHandler);
canvas.addEventListener('mousemove',mouseMoveEventHandler);
canvas.addEventListener('touchmove',touchMoveEventHandler);
canvas.addEventListener('mouseup', mouseUpEventHandler);
canvas.addEventListener('touchend', mouseUpEventHandler);
var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;
答案 0 :(得分:0)
即使使用触摸确保兼容性,大多数(?所有?)浏览器也会模拟鼠标 尝试在触摸事件处理程序上使用stopPropagation和preventDefault来防止两个处理程序都触发。 或者事实上,“干净”的方法是通过开始“比赛”来检测您是否在触摸或鼠标设备上。一旦你知道了设备,只需挂钩相关的处理程序。
function mouseWins(e) { setUpHandler ( true , e ); }
function touchWins(e) { setUpHandler ( false , e); }
canvas.addEventListener('mousedown', mouseWins);
canvas.addEventListener('touchstart', touchWins);
function removeRaceHandlers() {
canvas.removeEventListener('mousedown', mouseWins);
canvas.removeEventListener('touchstart', touchWins);
}
function setUpHandler(isMouseandNotTouch, detectEvent) {
removeRaceHandlers();
if (isMouseandNotTouch) {
canvas.addEventListener('mouseup', mouseUpEventHandler);
canvas.addEventListener('mousemove',mouseMoveEventHandler);
canvas.addEventListener('mousedown', mouseDownEventHandler);
mouseDownEventHandler (detectEvent)
} else {
canvas.addEventListener('touchstart', touchstartEventHandler);
canvas.addEventListener('touchmove',touchMoveEventHandler);
canvas.addEventListener('touchend', mouseUpEventHandler);
touchstartEventHandler (detectEvent)
}
}
编辑:我添加了第一次检测事件的处理 你可以在你的触摸处理器中阻止默认()/ stopPropagation(),这样我就可以在没有滚动问题的设备上进行测试吗?