title: How to get the context X and Y position within a canvas html5
body: <p>I have this <a href="http://jsfiddle.net/mNu9E/11/" rel="nofollow">fiddle</a> and i need to know the position from where my grid begins all the time;</p>
  
  <p>I can zoom and even drag and drop the grid.</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;!-- saved from url=(0048)http://phrogz.net/tmp/canvas_zoom_to_cursor.html --&gt;
  &lt;html lang="en"&gt;
      &lt;head&gt;
          &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
          &lt;title&gt;Zooming via HTML5 Canvas Context&lt;/title&gt;
          &lt;style type="text/css" media="screen"&gt;
              body { background:#eee; margin:1em; text-align:center; }
              canvas { display:block; margin:1em auto; background:#fff; border:1px solid #ccc }
          &lt;/style&gt;
      &lt;/head&gt;
      &lt;body style="-webkit-user-select: none;"&gt;
  
          &lt;canvas width="800" height="600"&gt;&lt;/canvas&gt;
  
          &lt;script type="text/javascript" charset="utf-8"&gt;
  
              var start_x = start_y = position_x = position_y = 50;
  
              var canvas = document.getElementsByTagName('canvas')[0];
  
              canvas.width = 800;
  
              canvas.height = 600;
  
              var gkhead = new Image;
  
              var ball = new Image;
  
              var square_size = 10;
  
              window.onload = function() {
  
                  var ctx = canvas.getContext('2d');
  
                  trackTransforms(ctx);
  
                  function redraw() {
                      // Clear the entire canvas
                      var p1 = ctx.transformedPoint(0, 0);
                      var p2 = ctx.transformedPoint(canvas.width, canvas.height);
                      ctx.clearRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);
  
                      ctx.drawImage(gkhead, 50, 50);//punct stanga sus imagine cu marton
                      //console.log(ctx);
                      color = 'ff0000';
                      w = gkhead.width;
                      //console.log(w);
                      h = gkhead.height;
                      //console.log(h);
                      var i = 0;
                      i = i + 1;
                      if (i == 1)
                          color = 'ff0000';
                      if (i == 2)
                          color = '00ff00';
                      if (i == 3) {
                          color = '0000ff';
                          i = 0;
                      }
  
                      ctx.beginPath();
                      ctx.rect(50, 50, gkhead.width, gkhead.height);
                      ctx.lineWidth = 1;
                      ctx.strokeStyle = "#" + color;
                      ctx.stroke();
  
                      ctx.beginPath();
                      ctx.rect(51, 51, 8, 8);
                      ctx.lineWidth = 1;
                      ctx.fillStyle="#ffff00";
                      ctx.fill();
                      ctx.strokeStyle = "#ffff00";
                      ctx.stroke();
  
                      var ind = 0;
                      for (var j = 0; j &lt; gkhead.width - square_size; j = j + square_size) {
                          ind++;
                          ctx.beginPath();
                          ctx.lineWidth = 1;
                          ctx.strokeStyle = 'black';
                          ctx.moveTo(50 + (ind * square_size), 50);
                          ctx.lineTo(50 + (ind * square_size), 50 + gkhead.height);
                          ctx.stroke();
                      }
  
                      var ind = 0;
                      for (var j = 0; j &lt; gkhead.height - square_size; j = j + square_size) {
                          ind++;
                          ctx.beginPath();
                          ctx.lineWidth = 1;
                          ctx.strokeStyle = 'blue';
                          ctx.moveTo(50, 50 + (ind * square_size));
                          ctx.lineTo(50 + gkhead.width, 50 + (ind * square_size));
                          ctx.stroke();
                      }
  
                      ctx.save();
                      ctx.translate(438.5, 223);
                      ctx.strokeStyle = '#06c';
                      ctx.beginPath();
                      ctx.lineWidth = 0.05;
  
                      for (var i = 0; i &lt; 60; ++i) {
                          ctx.rotate(6 * i * Math.PI / 180);
                          ctx.moveTo(9, 0);
                          ctx.lineTo(10, 0);
                          ctx.rotate(-6 * i * Math.PI / 180);
                      }
                      ctx.stroke();
                      ctx.restore();
                  }
                  redraw();
  
                  var lastX = canvas.width / 2, lastY = canvas.height / 2;
                  var dragStart, dragged;
  
                  canvas.addEventListener('mousedown', function(evt) {
                      document.body.style.mozUserSelect = document.body.style.webkitUserSelect = document.body.style.userSelect = 'none';
                      lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
                      lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
                      console.log('mousedown' + ' ' + lastX + ' ' + lastY);
                      dragStart = ctx.transformedPoint(lastX, lastY);
                      dragged = false;
                  }, false);
  
                  canvas.addEventListener('mousemove', function(evt) {
                      lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
                      lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
                      dragged = true;
                      if (dragStart) {
                          var pt = ctx.transformedPoint(lastX, lastY);
                          ctx.translate(pt.x - dragStart.x, pt.y - dragStart.y);
                          console.log('dragStart: ' + ' ' + dragStart.x + ' ' + dragStart.y);
                          console.log('mousemove dragStart' + ' ' + (lastX) + ' ' + (lastY));
                          if (lastX != start_x) {
                              if (lastX &gt; start_x)
                                  position_x = position_x + lastX - start_x;
                              else
                                  position_x = position_x + start_x - lastX;
                          }
                          if (lastY != start_y) {
                              if (lastY &gt; start_y)
                                  position_y = position_y + lastY - start_y;
                              else
                                  position_y = position_y + start_y - lastY;
                          }
                          console.log('position: ' + position_x + ' ' + position_y);
                          redraw();
                      }
                  }, false);
  
                  canvas.addEventListener('mouseup', function(evt) {
                      dragStart = null;
                      if (!dragged)
                          zoom(evt.shiftKey ? -1 : 1);
                  }, false);
  
                  var scaleFactor = 1.1;
                  var zoom = function(clicks) {
                      var pt = ctx.transformedPoint(lastX, lastY);
                      ctx.translate(pt.x, pt.y);
                      var factor = Math.pow(scaleFactor, clicks);
                      ctx.scale(factor, factor);
                      ctx.translate(-pt.x, -pt.y);
                      redraw();
                  }
  
                  var handleScroll = function(evt) {
                      var delta = evt.wheelDelta ? evt.wheelDelta / 40 : evt.detail ? -evt.detail : 0;
             if (delta)
              zoom(delta);
                      return evt.preventDefault() &amp;&amp; false;
                  };
                  canvas.addEventListener('DOMMouseScroll', handleScroll, false);
                  canvas.addEventListener('mousewheel', handleScroll, false);
              };
  
              gkhead.src = 'http://www.william.ro/wp-content/uploads/2013/07/13.jpg';
  
              ball.src = 'http://phrogz.net/tmp/alphaball.png';
  
              // Adds ctx.getTransform() - returns an SVGMatrix
              // Adds ctx.transformedPoint(x,y) - returns an SVGPoint
              function trackTransforms(ctx) {
                  var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
                  var xform = svg.createSVGMatrix();
                  ctx.getTransform = function() {
                      return xform;
                  };
  
                  var savedTransforms = [];
                  var save = ctx.save;
                  ctx.save = function() {
                      savedTransforms.push(xform.translate(0, 0));
                      return save.call(ctx);
                  };
                  var restore = ctx.restore;
                  ctx.restore = function() {
                      xform = savedTransforms.pop();
                      return restore.call(ctx);
                  };
  
                  var scale = ctx.scale;
                  ctx.scale = function(sx, sy) {
                      xform = xform.scaleNonUniform(sx, sy);
                      return scale.call(ctx, sx, sy);
                  };
                  var rotate = ctx.rotate;
                  ctx.rotate = function(radians) {
                      xform = xform.rotate(radians * 180 / Math.PI);
                      return rotate.call(ctx, radians);
                  };
                  var translate = ctx.translate;
                  ctx.translate = function(dx, dy) {
                      xform = xform.translate(dx, dy);
                      return translate.call(ctx, dx, dy);
                  };
                  var transform = ctx.transform;
                  ctx.transform = function(a, b, c, d, e, f) {
                      var m2 = svg.createSVGMatrix();
                      m2.a = a;
                      m2.b = b;
                      m2.c = c;
                      m2.d = d;
                      m2.e = e;
                      m2.f = f;
                      xform = xform.multiply(m2);
                      return transform.call(ctx, a, b, c, d, e, f);
                  };
                  var setTransform = ctx.setTransform;
                  ctx.setTransform = function(a, b, c, d, e, f) {
                      xform.a = a;
                      xform.b = b;
                      xform.c = c;
                      xform.d = d;
                      xform.e = e;
                      xform.f = f;
                      return setTransform.call(ctx, a, b, c, d, e, f);
                  };
                  var pt = svg.createSVGPoint();
                  ctx.transformedPoint = function(x, y) {
                      pt.x = x;
                      pt.y = y;
                      return pt.matrixTransform(xform.inverse());
                  }
              }
          &lt;/script&gt;
  
      &lt;/body&gt;
  
  &lt;/html&gt;
  </code></pre>