2012-03-01 95 views
1

我们一直在玩弄canvas元素,但在移动Safari浏览器正遭遇低迷,而应用工程进展顺利桌面上勾画的Web应用程序。低迷的UI /在移动Safari浏览器(HTML5画布)

测试应用程序是非常原始。它只是让用户在桌面上使用鼠标或在智能手机上使用手指画线。

在移动Safari,所述线的绘制往往是非常干。一行的第一位将实时呈现,但其余部分将不会呈现,直到手指从屏幕上抬起为止。

任何想法,为什么?

下面的代码。

HTML:

<!DOCTYPE html> 
<html> 
    <head>  
      <link rel='stylesheet' href='http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css' /> 
      <script src='http://code.jquery.com/jquery-1.6.4.min.js'></script> 
      <script src='http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js'></script>    
      <style type='text/css'> 
       #canvas { border:1px solid red } 
      </style>   
    </head> 

    <body>  
      <div id='draw_page' data-role='page'> 
       <canvas id="canvas" width="500" height="350"></canvas> 
      </div> 

      <script type="text/javascript"> 
       $('#draw_page').live('pageinit', function() { 
       prep_canvas(); 
       }); 
      </script> 
    </body> 
</html> 

的JavaScript:

var clickX = new Array(); 
var clickY = new Array(); 
var clickDrag = new Array(); 
var paint; 
var canvas; 
var context; 

function prep_canvas() { 

canvas = $('#canvas')[0]; 
context = canvas.getContext("2d"); 

} 

$('#canvas').live('vmousedown', function(e){ 
    var mouseX = e.pageX - this.offsetLeft; 
    var mouseY = e.pageY - this.offsetTop; 

    paint = true; 
    addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop); 
    redraw(); 
}); 


$('#canvas').live('vmousemove', function(e){ 
    if(paint){ 
    addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true); 
    redraw(); 
    } 
}); 


$('#canvas').live('vmouseup', function(e){ 
    paint = false; 
}); 


function addClick(x, y, dragging) 
{ 
    clickX.push(x); 
    clickY.push(y); 
    clickDrag.push(dragging); 
} 


function redraw(){ 
    canvas.width = canvas.width; // Clears the canvas 

    context.strokeStyle = "black"; 
    context.lineJoin = "round"; 
    context.lineWidth = 2; 

    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(); 
    } 
} 
+0

确保你没有在iPhone模拟器上测试。还运行在全屏模式下在画布或运行作为一个应用程序在移植用的PhoneGap会导致JavaScript在IOS 5至像的iOS 4.运行 – BumbleB2na 2012-03-01 23:10:32

+0

此外,存在使用画布的多个层,以避免在每个帧重绘一切的方式,这在移动浏览器中非常麻烦。如果您有两层帆布层,那么您可以每隔一段时间将当前线条画到后面的画布上,然后只将线条的最新部分画到前面的画布上。 – BumbleB2na 2012-03-01 23:13:31

+0

希望我可以进一步帮助。它看起来像这里的答案有一个现场演示,你可以尝试在你的手机上,我不认为这个人每次都重绘画布:http://stackoverflow.com/questions/7478501/how-to-get-smooth -mouse-events-for-a-canvas-drawing-style-app – BumbleB2na 2012-03-01 23:40:32

回答

0

我也跟着这样的:http://dev.opera.com/articles/view/html5-canvas-painting/,它工作流体在手机上(你会看到一个img_update注释掉线(),它使用在BumbleB2na提到的两种画布方法中...但我没有使用任何形状,只是线条,所以不用它)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<meta name="viewport" content="width=device-width, user-scalable=no,initial-scale = 1.0"> 
<link rel="apple-touch-icon" href="touch-icon-iphone.png" /> 
<link rel="apple-touch-icon" sizes="72x72" href="touch-icon-ipad.png" /> 
<link rel="apple-touch-icon" sizes="114x114" href="touch-icon-iphone4.png" /> 
<link rel="apple-touch-startup-image" href="startup-iphone.png"> 
<meta name="apple-mobile-web-app-capable" content="yes" /> 
<meta name="apple-mobile-web-app-status-bar-style" content="black" /> 
<title>Untitled Document</title> 
<style type="text/css"> 
body {background:#ccc; margin:0; padding:0} 
html {margin:0; padding:0;} 
#container { position: relative; margin:0; padding:0px; } 
#canvas { border: 1px solid #000; background-color:#FFF; position:relative; width:298px; margin-left:11px; margin-top:5px; } 
</style> 
</head> 

<body onload="listen()"> 
<div id="container"> 
    <canvas id="canvas" width="298" height="298"> 
    </canvas><br/> 
    <button onclick="clearImage()">Clear</button> 
    </div> 
</body> 
<script type="text/javascript"> 
var canvas = document.getElementById('canvas'); 
if(canvas){var context= canvas.getContext('2d');} 
var tool; 
tool = new tool_pencil(); 

document.body.addEventListener('touchmove',function(event){ event.preventDefault(); },false); 
function listen(){ 
    canvas = document.getElementById('canvas'); 
    if(canvas){ 
     context= canvas.getContext('2d'); 
     context.fillStyle = "rgb(255,255,255)"; 
     context.fillRect(0, 0, canvas.width, canvas.height); 
     iphone = ((window.navigator.userAgent.match('iPhone'))||(window.navigator.userAgent.match('iPod')))?true:false; 
     ipad = (window.navigator.userAgent.match('iPad'))?true:false; 
     if(iphone||ipad){ 
      canvas.addEventListener('touchstart', ev_canvas, false); 
      canvas.addEventListener('touchend', ev_canvas, false); 
      canvas.addEventListener('touchmove', ev_canvas, false); 
     } 
     else{ 
      canvas.addEventListener('mousedown', ev_canvas, false); 
      canvas.addEventListener('mousemove', ev_canvas, false); 
      canvas.addEventListener('mouseup', ev_canvas, false); 
     } 
    } 
} 

function tool_pencil() { 
    var tool = this; 
    this.started = false; 
    this.mousedown = function (ev) { 
     context.beginPath(); 
     context.moveTo(ev._x, ev._y); 
     tool.started = true; 
    }; 

    this.mousemove = function (ev) { 
     if (tool.started) { 
      context.lineTo(ev._x, ev._y); 
      context.stroke(); 
     } 
    }; 

    this.mouseup = function (ev) { 
     if (tool.started) { 
      tool.mousemove(ev); 
      tool.started = false; 
      //img_update(); 
     } 
    }; 
    this.touchstart = function (ev) { 
     ev.preventDefault(); 
     context.beginPath(); 
     context.moveTo(ev._x, ev._y); 
     tool.started = true; 
    }; 

    this.touchmove = function (ev) { 
     ev.preventDefault(); 
     if (tool.started) { 
      context.lineTo(ev._x, ev._y); 
      context.stroke(); 
     } 
    }; 

    this.touchend = function (ev) { 
     ev.preventDefault(); 
     if (tool.started) { 
      tool.started = false; 
     } 
    }; 
} 

// The general-purpose event handler. This function just determines the mouse position relative to the canvas element. 
function ev_canvas (ev) { 
    iphone = ((window.navigator.userAgent.match('iPhone'))||(window.navigator.userAgent.match('iPod')))?true:false; 
    ipad = (window.navigator.userAgent.match('iPad'))?true:false; 
    if (((iphone)||(ipad))&&(ev.touches[0])){ //iPad 
     ev._x = ev.touches[0].clientX; 
     ev._y = ev.touches[0].clientY; 
    } 
    else if (ev.layerX || ev.layerX == 0) { // Firefox 
     ev._x = ev.layerX; 
     ev._y = ev.layerY; 
    } 
    else if (ev.offsetX || ev.offsetX == 0) { // Opera 
     ev._x = ev.offsetX; 
     ev._y = ev.offsetY; 
    } 
    // Call the event handler of the tool. 
    var func = tool[ev.type]; 
    if (func) { 
     func(ev); 
    } 
} 

function clearImage(){ 
    var yes=confirm('Clear drawing?'); 
    if(yes){ 
     context.clearRect(0, 0, canvas.width, canvas.height); 
     context.fillStyle = "rgb(255,255,255)"; 
     context.fillRect(0, 0, canvas.width, canvas.height); 
    } 
} 

</script> 
</html> 
+0

完美工作!你怎么找到这个,BTW?希望下次我能找到答案。 :) – Crashalot 2012-03-02 08:27:24

+1

我想我已经在寻找'帆布漆程序'或类似的东西......但后来我对触摸事件做了自己的调整。很高兴帮助 – 2012-03-02 15:44:34

+0

嗨@RobotWoods,你知道我们如何平滑用铅笔工具绘制的线条吗?除非用户绘制完美的直线,否则会出现锯齿状和略微模糊,这意味着绘制光滑的圆形或曲线是不可能的。 – Crashalot 2012-03-27 18:48:00