Detect element position on a screen using javascript - javascript

Is there a way using javascript to detect the absolute position of where you are positioned on a monitor? For example Intersection Observer can tell you if your element is within the viewport of the browser, but it cannot tell you if the browser is halfway off the users monitor, and your element is outside of an actual persons view.

You can find the position of the element using getBoundingClientRect
var x = document.getElementById("elementId").getBoundingClientRect().x;
var y = document.getElementById("elementId").getBoundingClientRect().y;
//Your element position
var position = [x, y];
If your element is off the viewport, it would have negative values depending on its position from top-left.

Related

How to move an unknown object to center screen? HTML/CSS/JS

I am developing a VueJS project and have created a set of cards appearing on the page, when one of these cards is selected, I wish for it to move to centre screen but keep the position it has moved from in the list of options.
I know that by changing the position from 'unset' to 'relative' the card now has move functionality with 'left', 'top' etc. but I still need to find a way to automatically move the card to centre screen regardless of where on the screen the card is moving from.
Does anyone know how to achieve this with the use of JS?
I imagine there is a way of receiving the current location of the node and moving it to the center of the screen, but I am not sure on the specifics of how to achieve it...
Image for context:
CardsProject
EDIT: I have for now gone with rendering an absolute position for the card which means there's no CSS transition from the card's original place to the centre of the screen and the card also temporarily loses its place within the deck.
Before click: click here for image
After click: click here for image
I found the answer after many, many hours of scouring the internet and deepfrying my code.
The answer: Don't use 'relative' positioning!
There's a far nice option to hold the position the element is moving from, but allow for the item to move freely with the use of CSS' top or left etc. and this option is position:sticky;!
With this and the use of JavaScript's coordinates documentation
.getBoundingClientRect()
...I managed to solve the mystery. The function I made to pull a vector between the current object and it the centre of the screen can be found here, returning an array of size 2 of X and Y vectors respectively.
function calcCenterMove(element){
/*
X and Y are the current position of the element to be moved (top left corner).
Width and Height are the width and height of the element to be moved.
CX and CY are the X and Y coordinates of the centre of the screen.
*/
var x = element.getBoundingClientRect().x;
var y = element.getBoundingClientRect().y;
var width = element.getBoundingClientRect().width;
var height = element.getBoundingClientRect().height;
var cx = window.innerWidth / 2;
var cy = window.innerHeight / 2;
var xVector = cx-(width/2)-x;
var yVector = cy-(height/2)-y;
return [xVector, yVector];
}
var xAxisMove = calcCenterMove(element)[0];
var yAxisMove = calcCenterMove(element)[1];
element.style = "transform: translate("+xAxisMove+"px,"+yAxisMove+"px);";
I have paired the above code with a z-index to place the element above all others, and a screen dimming cover, to prevent the user from scrolling elsewhere or interacting with any other options.
Issues still arise here if the user resizes the screen, but I believe that is a different issue to address, possibly by using an event listener to assess a window resize and translate the element from the previous centre to the new centre using the same cx and cy properties above (or perhaps even the entire function!).
Nevertheless, I have come to the answer I was looking for, anyone feel free to use the code above, if needed!
Here are images for reference:
Before click
After click
Regards!

How to get screen coordinates with getBoundingClientRect() in the presence of CSS zoom?

I'm trying to find the bounding box of an HTML element using Javascript in screen coordinates so that I can use external tools (such as ffmpeg's x11grab screen recording functionality) to take screenshots/videos of that element by itself.
If there is no CSS zoom present, then I can find the bounding box for element elem like this:
let viewportTop = window.screenY + (window.outerHeight - window.innerHeight);
let viewportLeft = window.screenX;
let rect = elem.getBoundingClientRect();
let width = rect.width;
let height = rect.height;
let left = viewportLeft + rect.left;
let top = viewportTop + rect.top;
I can then use these width, height, left, top coordinates to record the desired box on the browser window.
However, sometimes I want to increase the zoom of the element to make things easier to see:
elem.style.zoom = "2";
Having done this, the bounding box returned by elem.getBoundingClientRect() is now scaled down by a factor of 2. If I use the approach above to calculate my recording bounding box, it no longer lines up with the element.
I've had some success with calling window.getComputedStyle(elem, null).getPropertyValue("zoom"), parsing the zoom number, and using it to correct the bounding box. However, this isn't a perfect solution--what if I want to zoom document.body by some amount and also zoom the target element by some amount?
So, I'm wondering if there's a universal way to convert the coordinates from elem.getBoundingClientRect to screen coords that works even when CSS zoom is applied to various elements.
I considered using the browser's own zoom rather than CSS zoom, but I would rather not since I'm using Selenium to set this stuff up and I've seen dire warnings about adjusting the browser zoom with Selenium here.

How to find position of a web element in relation to another web element?

I have a scenario where I have to assert the presence of a web element with its position. To be more clear I have a web element X and another web element Y. Now I have to assert that after clicking a button I can see X sitting above Y. How to do that?
You should get the two elements‘ positions in the document and subtract the position value of X from the value of Y. If that value is positive, you know that X is sitting farther up than Y.
Getting the position
Use
boxPositionOfX = getElementById(“myX”).getBoundingClientRect();
boxPositionOfY = getElementById(“myY”).getBoundingClientRect();
This returns an object containing all four position values: top, right, bottom and left, relative to the viewport. You do not need to convert the viewport positions to the document positions, since the document offset you'd have to add is the same for both elements and will be cut in the subtraction.
Comparing positions
Now subtract their positions:
positionDifference = boxPositionOfY.top - boxPositionOfX.top;
If the positionDifference is greater than 0, X’s top border lies above Y’s top border.
If you want to make sure the elements do not overlap, use this:
If ( (boxPositionOfY.top - boxPositionOfX.bottom) >= 0) {
alert("X is above Y. They do not overlap.");
}

Firefox svg rendering: how to get real g position?

I have a page with a svg loaded via object.
Then, I call a function that loads a div, using width, height, left and top of an internal g element
var cartina = document.getElementById(whatMap);
var cartinaContext;
cartina.addEventListener("load",function(){
cartinaContext = cartina.contentDocument;
var el = $("#mappaBase", cartinaContext)[0];
var rect = el.getBoundingClientRect();
var whatContainer = "#containerIcone"+whatMap;
$(whatContainer).css("position", "absolute");
$(whatContainer).width(rect.width);
$(whatContainer).height(rect.height);
$(whatContainer).css("left", rect.left);
$(whatContainer).css("top", rect.top);
}
I'm using getBoundingClientRect(). I'm applying the div #containerIcone over the svg.
In Chrome it works smoothly well. The problem is in Firefox: when I load the page, width and height are properly loaded but left and top are not. If I inspect the svg with Firefox, it appears that the g element is placed in a fixed position, while the rendered g element has another one (responsive to window dimensions and other elements position). Still, the g fixed element reacts well to window various sizes. The div is placed over the g element fixed inspect-position.
Inspecting the same element with Chrome reveals that the g element inspect box is drawed everytime where the g rendered element is.
How can I make this work in Firefox?
I found a solution, it's working cross-browser.
Instead of positioning with .top and .left of the nested g element, I get width and height of nested element
var el = $(nestedElement);
var rect = el.getBoundingClientRect();
Then I get width and height of the parent svg element
var rectSvg = mysvg.getBoundingClientRect();
Then I subtract the el width and height from the svg ones, and divide results by 2. The final result is the white space the svg has inside it, top and left, used to center the rendered element el inside the svg element (used by browser to mantain aspect ratio). Then I apply those results as css top and left of my div containing icons - it will be positioned exactly over the g el element.
var leftSpace = (rectSvg.width - rect.width)/2;
var topSpace = (rectSvg.height - rect.height)/2;
$(myPositionedDiv).css("left", leftSpace);
$(myPositionedDiv).css("top", topSpace);
This manner, however Firefox positions the element despite of rendering, left and top are correctly calculated.

Position a div relavtive to another div: SVG issues

I have a div with an id="div_Diagram" that contains two other divs, div_CanvasHeader and div_Canvas, as shown. div_Canvas also contans an SVG, which in turn contains several rects. Each rect has is constructed in a way that its has a javascript script attached to its mouseover event with the x & y position values passed into the script.
Do to the nature of svgs, I'm not able to correctly position the tooltip division relative to the rect. I'd like to be able to use the rect coordinates (x&y) to position the tooltip relative to div_CanvasHeader or div_Diagram. Other then x & y, all other dimensions are fixed.
Here is the javascript. (Note that the tooltip is a telerik control. The Show() method does show the tooltip with all of the correct content but at the bottom left of page).
function showSVGTtip(elt, x, y) {
if (elt.hasAttribute("name")) {
var ttipText = elt.getAttribute("ttipText ");
var ttip = $find("<%=myToolTipDiv.ClientID %>");
document.getElementById("ttipLabel").innerHTML = ttipText ;
ttip.show();
// Need to set position of ttip relative to other element such as pnlCanvasHeader
}
}
How do I position the tooltip div relative to one of the other divs? For example, if I have the id of the tooltip div, can I move it on the client relative to div_CanvasHeader? Does the tooltip need to be contained within the other div?

Categories