0

The situation:

The canvas contains an image, which can be rotated, scaled and translated (moved). The image is an SVG with many paths inside, thus the original coordinates must be retrieved to check which path is encapsulating the mouse.

The SVG is rendered on a canvas.

      //calculates the distance between two points
      var distance = function(x1, y1, x2, y2) {
        return Math.sqrt(Math.pow(Math.abs(x1 - x2), 2),
            Math.pow(Math.abs(y1 - y2), 2));
      };

      //defines the center of the image
      //this is also the rotational point
      var center = {
        x : target.getWidth() / 2,
        y : target.getHeight() / 2
      };

      //defines the click location
      var click = {
        x : event.layerX / target.getScaleX() - target.getLeft(),
        y : event.layerY / target.getScaleY() - target.getTop()
      };

Above code makes sure the x and y are the correct values used within the paths, provided there is no rotation.

So basically: provided the user has rotated the image 45 degrees and clicks on the image: the click coordinates need to be rotated back 45 degrees to get the needed coordinates. But it's been a few years since I've done maths like that...

The origin (rotational point) of the image is its center.

Stephan Bijzitter
  • 4,425
  • 5
  • 24
  • 44

1 Answers1

2

You are looking for toLocalPoint, which does most of the work for you : http://fabricjs.com/docs/fabric.Object.html#toLocalPoint

As you can see in the source of the function, it does not take into account scaling, but it does the rotation and translation of the object.

var p = canvas.getPointer(event);
var loc = target.toLocalPoint(new fabric.Point(p.x,p.y), "left", "top");

var pos_in_target = {
    x : loc.x / target.getScaleX(),
    y : loc.y / target.getScaleY()
};
Cimbali
  • 11,012
  • 1
  • 39
  • 68
  • With your first answer I felt blessed because you went into so much detail and when I got back from my break I saw the edit (current version as of typing) and I was like what nooo where did it go! I do understand now (because of your earlier revision) how it all works, and with an implementation as simple as this... you're the best man, thanks a lot – Stephan Bijzitter Jan 05 '15 at 12:48
  • Haha yeah, I went into some detail, that you can access here : http://stackoverflow.com/revisions/27757399/7, but though I get the opposite matrix just fine, I get into trouble getting the matrix from fabricjs. Using `getTransformMatrix()` always returns `null`, and `fabric.parseTransformAttribute(target.getSvgTransform())` fails by forgetting a degree to radians conversion, so I had to build the matrix manually. Then going through the code, I found lots of useful functions that are less obvious in the doc... hence the shorter answer. But see a comparison here : http://jsfiddle.net/1fy8s309/4 – Cimbali Jan 05 '15 at 14:50