Вялый пользовательский интерфейс в веб-приложении для рисования / создания эскизов в Mobile Safari (HTML5 canvas) - PullRequest
1 голос
/ 02 марта 2012

Мы поиграли с элементом canvas, но в Mobile Safari мы наблюдаем медлительность, в то время как приложение отлично работает на рабочем столе.

Тестовое приложение очень примитивно.Он позволяет пользователю нарисовать линию с помощью мыши на рабочем столе или пальца на смартфоне.

В Mobile 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();
  }
}

1 Ответ

0 голосов
/ 02 марта 2012

Я следовал этому: http://dev.opera.com/articles/view/html5-canvas-painting/ и он плавно работает на телефоне (вы увидите закомментированную строку для img_update (), которая используется в методе canvas, упомянутом 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>
...