title: HTML5 Canvas touch joystick performance issues
body: <p>I'm trying to create virtual touch joystick on HTML5 canvas. I found several solutions, one really working, but it was too complicated for me to modify, so I did a lot of work on my own, but it had some issues. It doesn't support two joysticks at a time and also it's terribly slow :( Please show me the way I should go. My html code looks like this:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
    &lt;html&gt;
    &lt;head&gt;
      &lt;meta http-equiv="content-type" content="text/html; charset=UTF-8"&gt;
      &lt;meta name="viewport" content="width=device-width; height=device-height; initial-scale=1.0; maximum-scale=1.0;"&gt; 
    &lt;title&gt;Touch controller&lt;/title&gt;
    &lt;link rel="stylesheet" href="css/virtualjoystick.css"&gt;
    &lt;script src="js/jquery-1.11.0.min.js"&gt;&lt;/script&gt;
    &lt;script src="js/touch.js"&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div class="container" id="video"&gt;
      &lt;canvas height="977" width="1920" id="canvas"&gt;&lt;/canvas&gt;
    &lt;/div&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>And touch.js is like this:</p>
  
  <pre><code>//touch control JavaScript
  $(document).ready(function(){
    //setup
    var c = document.getElementById("canvas");
    var ctx = c.getContext("2d");
    resetCanvas(c);
  
    //handlers
    $("#canvas").mousedown(function(e){
      if(side(e.clientX) == "left"){
        if(!left.isset){
          //alert("left");
          left.isset = true;
          left.startX = e.clientX;
          left.startY = e.clientY;
          left.curX = e.clientX;
          left.curY = e.clientY;
          refreshCanvas(ctx);
        }
      }
      else if(side(e.clientX) == "right"){
        if(!right.isset){
          //alert("left");
          right.isset = true;
          right.startX = e.clientX;
          right.startY = e.clientY;
          right.curX = e.clientX;
          right.curY = e.clientY;
          refreshCanvas(ctx);
        }
      }
    });
    $("#canvas").mousemove(function(e){
      if(side(e.clientX) == "left"){
        if(left.isset){
          left.curX = e.clientX;
          left.curY = e.clientY;
          refreshCanvas(ctx);
        }
      }
      else if(side(e.clientX) == "right"){
        if(right.isset){
          right.curX = e.clientX;
          right.curY = e.clientY;
          refreshCanvas(ctx);
        }
      }
    });
    $("#canvas").mouseup(function(e){
      if(side(e.clientX) == "left"){
        if(left.isset){
          //alert("left");
          left.isset = false;
          left.startX = false;
          left.startY = false;
          left.curX = false;
          left.curY = false;
          refreshCanvas(ctx);
        }
      }
      else if(side(e.clientX) == "right"){
        if(right.isset){
          //alert("left");
          right.isset = false;
          right.startX = false;
          right.startY = false;
          right.curX = false;
          right.curY = false;
          refreshCanvas(ctx);
        }
      }
    });
  });
  
  var left = {isset:false};
  var right = {isset:false};
  
  function resetCanvas(c){
    c.width = $(window).innerWidth();
    c.height = $(window).innerHeight();
    //c.scrollTo(0,0);
  }
  
  function refreshCanvas(ctx){
    ctx.clearRect(0,0,1920,1080);
    if(left.isset){
      drawBase(ctx, left.startX, left.startY);
      drawHandle(ctx, left.startX, left.startY, left.curX, left.curY);
    }
    if(right.isset){
      drawBase(ctx, right.startX, right.startY);
      drawHandle(ctx, right.startX, right.startY, right.curX, right.curY);
    }
  }
  
  function drawBase(ctx, x, y){
    ctx.beginPath();
    ctx.lineWidth = 2;
    ctx.arc(x,y,40,0,2*Math.PI);
    ctx.stroke();
  }
  
  function drawHandle(ctx, startX, startY, curX, curY){
    //stop handle when leaving joystick
    var x = curX - startX;
    var y = curY - startY;
    if( ( (x*x) + (y*y) ) &gt;= (1600) ){
      var f = y/x;
      if(x &lt; 0) var invert = true;    
      x = 0;
      y = 0;
      while( ( (x*x) + (y*y) ) &lt;= (1600) ){
        y = x*f;
        if(invert) x--;
        else x++;
      }
      x += startX;
      y += startY;    
    }
    else {
      x = curX;
      y = curY;
    }
  
    ctx.beginPath();
    ctx.lineWidth = 4;
    ctx.arc(x,y,20,0,2*Math.PI);
    ctx.stroke();
  }
  
  function side(x){
    var c = document.getElementById("canvas");
    var dead = c.width/20;
    var left = (c.width - dead)/2;
    var right = left + dead;
    if(x &lt; left) return "left";
    else if(x &gt; right) return "right";
    else return false;
  }
  </code></pre>
  
  <p>I'm trying to do it as simple as possible, because I need it to be fast. However I wasn't successful yet. Thanks for advices</p>