javascript - How to account for scaling, translating, and rotating in canvas mouse clicks -


i'm working on app requires scaling (by way of style.width, not scale(...)), translating (translate(x, y)) , rotating (e.g. rotate(90deg)) canvas element. need calculate proper mouse click positions on canvas. is, need make ends of lines appear user clicked. right now, when try incorporate translation, calculations come out off little bit, can see when clicking twice in demo canvas below.

part of confuses me order should untranslating, unrotating, , unscaling in produce correct result.

demo code:

var canvas = document.getelementbyid("canvas");    var scalex = 0.5;  var scaley = 0.5;  var rot = 1;  var dispwidth = (canvas.width * scalex);  var dispheight = (canvas.height * scaley);  var xlatex = math.floor((dispheight - dispwidth) / 2);  var xlatey = math.floor((dispwidth - dispheight) / 2);    var transform = "translate(" + xlatex + "px, " + xlatey + "px) rotate(" + (rot * 90) + "deg)";  canvas.style.width = dispwidth + "px";  canvas.style.height = dispheight + "px";  canvas.style.transform = transform;    var context = canvas.getcontext("2d");  var stack = [];  canvas.onclick = function (e) {          var rect = canvas.getboundingclientrect();      console.log('rect', rect.left, rect.top);          // position within canvas, ignoring scroll      var x = e.clientx - rect.left;      var y = e.clienty - rect.top;      console.log('original', x, y);          // scale      x /= scalex;      y /= scaley;      console.log('scaled', x, y);            // translate      x -= xlatex;      y -= xlatey;      console.log('translated', x, y);            var tmp;      switch (rot % 4) {          case 1:              tmp = x;              x = y;              y = canvas.height - tmp;              break;          case 2:              y = canvas.height - tmp;              x = canvas.width - tmp;              break;          case 3:              tmp = y;              y = x;              x = canvas.width - tmp;              break;          default:              break;      }      console.log('rotated', x, y);            stack.push({x: x, y: y});      if (stack.length > 1) {          context.beginpath();          context.moveto(stack[0].x, stack[0].y);          context.lineto(stack[1].x, stack[1].y);          context.stroke();          stack = [];      }  };
click once start line. click again finish it.  <br>  <canvas id="canvas" width="600" height="400" style="border: 1px solid black;"></canvas>


Comments

Popular posts from this blog

c# - Binding a comma separated list to a List<int> in asp.net web api -

Delphi 7 and decode UTF-8 base64 -

html - Is there any way to exclude a single element from the style? (Bootstrap) -