I expected this to be 100% a no-brainer, but as it turns out, I cannot figure out what the x and y attributes of an svg created and manipulated with Raphael.js mean. I assumed they were the coordinates of the top-left corner of the object in relation to the canvas, but now I'm not so sure.
After creating a canvas (var paper = new Raphael(container,width,height)) and adding an image or rectangle to it, for example, if I retrieve the "x" and "y" attributes using the attr method (e.g. object.attr("x")), they're both at 0. However, if I rotate that object and then retrieve the values of x and y again, the values don't reflect the position of the top-left corner of my object in relation to the canvas anymore.
Can someone please explain this to me?
I fear #afaf12's answer complacently goes only half the distance. He's absolutely correct that transformation logic occurs after the fundamental attributes of a given element and doesn't effect them, but it is certainly possible to retrieve the x and y of that element after transformations are applied. You'll want to use the getBBox method, like this:
var bbox = elem.getBBox();
console.log("Transformed coordinates of element are %s,%s", bbox.x, bbox.y );
Please note that there is some trickiness involved -- this returns the bounding box of the element, which is often a superset of the space occupied by the element -- so there's no guarantee that the returned point will be IN the element.
Another alternative occurs if you're using paths -- path.getPointAtLength also works with transformed coordinates, so you can get the x,y offset of the beginning of a path by calling
var coord = elem.getPointAtLength(0);
console.log("Transformed coordinates of path are %s,%s", coord.x, coord.y );
Rotation is a transformation and it does not change x and y of the object.
http://raphaeljs.com/reference.html#Element.transform
Related
I have a question that is math and also JavaScript related. I'm trying to come up with a function to get me the true coordinate within an element that was clicked. The difficulty here is that the element could be rotated.
Otherwise, we could easily get the coordinate within the element on a click by doing using jQuery:
const ELEMENT_X = event.pageX - object.offset().left;
const ELEMENT_Y = event.pageY - object.offset().top;
Not too sure if these JavaScript objects can help calculate the true coordinate of the element:
DOMPoint
DOMMatrix
We know the coordinate of the click on the viewport, the width and height of the element, its offset left/top and we know the rotation angle (could be negative or positive [-180, 180]). So the function I'm trying to get to return the true coordinate of of any four-sided shape would look something like this:
function getClickedCoordinateOfElement(event, elementDOM, rotationAngleInDegrees) {
let coordinate[];
let x, y;
...
return(coordinate[x, y]);
}
I think the solution requires some manipulation of the Sin or Cos of a triangle, but I'm not too sure.
I forgot to mention that the element is not anchored to the origin and could be anywhere.
How would we get the coordinate of the green dot in relative to the inside of the element? The top left corner (ax) of the element would be (0, 0).
I have a fabricjs canvas with multiple SVG objects which may or may not overlap.
Some of the SVG objects have transparent areas, such that the transparent area of Object A may be positioned on top of a filled area of Object B, as in the diagram below:
In the above diagram, the black border illustrates the SVG Object's bounding box.
Points X & Y illustrate cursor locations during object selection.
I am interested in retrieving the RGBA value at the cursor position, such that the selected object is taken into account.
If the user clicks at either Point X or Point Y, then the selected object (with normal behaviour of fabricjs) is Object A, as Object A is the topmost object and the user has clicked within the bounding box.
What I want to do is retrieve the RGBA value (or just the alpha value will do) of Object A at the cursor position i.e. at both Point X and Point Y, Object A is transparent.
From what I can gather from the fabricjs documentation - I can only see a way to get the RGBA value at a cursor position from the canvas as a whole - not for specific objects. This means that Point X is a transparent value, whilst Point Y is blue with full opacity.
var pixelData = this.canvas.getContext().getImageData(pointer.x, pointer.y, 1, 1).data;
What I'm looking for is a way to query the pixel data for a single object at a specific cursor location, perhaps something like:
var pixelData = selectedObject.getImageData(pointer.x, pointer.y, 1, 1).data;
I understand that fabricjs may not directly support such a feature, but I'm wondering whether anybody has a nice way of achieving this so that I can accurately determine when the user has clicked on a transparent area of an object.
I'm supposing that as I'm using SVG images, the solution may have something to do with figuring out the cursor position in relation to the SVG paths and determining whether the user has clicked on a filled section of the SVG, but I'm just a bit stuck with working out the best way to tackle the problem so I'm really open to any suggestions!
If anybody has any pointers it'd be much appreciated!
Example: http://codepen.io/heroheman/pen/thdBH
Hi,
i have this boxed path, which changes the it corner points every second.. Also i have 4 icons which should be on the corner of the box.
Both is based on an array which recalculates the points, and sets new position.
But the position of the circles seems to have some kind of scaling - I tried absolute and relative paths (t and T seems to make no difference).
Maybe one of you guys could help!
You will need to account for the offset of the centre of the circles...
If you look at 'bubble' for example, its cx,rx attribute is 113,101.6
So ideally the transform for bubbles would logically be (new transform - original position)
't' + ( boxCoords[4] - 113 ) + ',' + (boxCoords[5] - 101.6 )
You could either hard code this in an array or object. Or if there are lots of icons, possibly you could grab the icons respective circle element, and get its element.attr('cx') value (or x if its a rect, or previous transform if its an arbitrary shape, or do a getBBox() on it to get its centre).
Learning raphael.js, it seems all objects default to having their x and y coordinates be a reference to the center of the object. This is fine in most cases but I would like the ability to also position an object using one of its corners. Is there a way this parameter can be changed for a given object?
No x and y attributes normally point to the top left of an Element this is certainly the case with rectangle and image.
A circle and ellipse do not have x and y attributes but cx and cy which are there centers.
If you use a text by default x is at the very middle of the text as is y.
If you made a circle and and gave the text the cx and cy values of the circle for it's x y attributes it would be painted in the centre of the circle
Look at Element.getBBox() also this will give you attributes of the space the Element occupies
Good luck..
I am trying to get the position of SVG elements using Javascript.
I have managed to get the position on elements that have X/Y attribute set.
But elements, such as paths does not have this attribute.. At least not in my docuements.
Is there a way to calculate the position other than taking the first number in the "path"?
Thank you,
Morten
You can use the function getBBox() to get the bounding box for the path. This will give you the position and size of the tightest rectangle that could contain the rendered path.
An advantage of using this method over reading the x and y values is that it will work with all graphical objects. There are more objects than paths that do not have x and y, for example circles that have cx and cy instead.
Link: getBBox() in the SVG v1.1 standard.