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).
Related
I'm making a diagramming library in Blazor which uses HTML nodes and SVG links. I am wondering how can I draw links between two nodes when they aren't always rectangular.
All the solutions I find are based on nodes that are rectangles/squares, where it's easy to draw a link on the borders (or even the center, but only works for direct links).
But what about nodes that have custom stuff in them that makes them non rectangular, for example a div with border-radius: 50%?
One possible solution is to draw the lines from/to the center of the elements, but that would only work with simple lines, curved lines would look weird.
In this example:
How does arrow position get calculated?
You need to have an container, width and height of the container, then inside the container find the x / y point of the element that you want to connect and draw a line to the next elements x / y point, the x/y points can be calculated using x,y,w,h of the element, for an example x:100 y:100 w:100 h:100 the center point sits at x:150, y:150 x = x + ( w / 2 ), y = y + ( h / 2 ).. using math just calculate the point of connection of the elements, the complexity of math for calculating the connection point is in the shape of the element, for each different shape you need a different calculation metod if not in center
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
I would appreciate your help with the following issue: I want to use CSS3 transforms in order to center the view-port of the browser around the position of a mouse click.
Please have a look at my commented example at http://jsfiddle.net/XjpdU/.
The problem that I have is that the translation works fine only on the first click. After the first click the distance between the center of the view-port and the mouse click position seems to be computed correctly, but the translation seems to jump just anywhere.
I have tried to explicitly set 'transform-origin' (-webkit-translate-origin in my example) to the position of the last click (i.e., the current center of the view-port) but it seems that with 'translate' the 'transform-origin' directive simply gets ignored.
Thanks for helping out!y
Yep, transform-origin has no effect on the translation. It works like this:
Start with the identity matrix.
Translate by the computed X, Y and Z values of ‘transform-origin’
Multiply by each of the transform functions in ‘transform’ property in turn
Translate by the negated computed X, Y and Z values of ‘transform-origin’
http://www.w3.org/TR/css3-transforms/#transform-rendering
What you could do is remember the translate, and add the newly calculated one to it, this will cause a relative translation starting from the previous point.
x = prevX = prevX + newX
y = prevY = prevY + newY
http://jsfiddle.net/XjpdU/1/
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..
Using Javascript how can I identify the element at a given position? Basically I'm looking to write a function that takes two input parameters (the x and y coordinates) and returns the html element at the position on the screen represented by the parameters.
document.elementFromPoint(x, y)
document.elementsFromPoint(x, y)
https://drafts.csswg.org/cssom-view/#dom-document-elementfrompoint
https://developer.mozilla.org/en-US/docs/Web/API/Document/elementFromPoint
https://developer.mozilla.org/en-US/docs/Web/API/Document/elementsFromPoint
You can use the native JavaScript elementFromPoint(x, y) method, that returns the element at coordinates x,y in the viewport.
See the elementFromPoint w3c draft
And, a code sample:
function changeColor(newColor) {
// Get the element placed at coords (2, 2)
var elem = document.elementFromPoint(2, 2);
// Set the foreground color to the element
elem.style.color = newColor;
}
<p id="para1">Change this text color using the following buttons.</p>
<button onclick="changeColor('blue');">Blue</button>
<button onclick="changeColor('red');">Red</button>
You can use setInterval() to continuously check the element's hover event but it's not recommended, try to use .hover(...) and css instead to enhance the application performance.
To get the topmost element at a specific position relative to the viewport, document.elementFromPoint(x, y) can be used.
To obtain an array of all the elements at a specific position, use document.elementsFromPoint(x, y).
In both cases, x is the horizontal coordinate which is relative to the left of the viewport and y is the vertical coordinate which is relative to the top of the viewport.