How to find the absolute the coordinates of an html element? - javascript

I need to find the absolute coordinates of the html element as per the screen. I know i can use getBoundingClientRect().top and getBoundingClientRect().left method to compute the coordinates as per the view port. How do i find the absolute coordinates? Another question is does window.screenX takes into account url and tab bar into account? Help is appreciated.

UPDATE
Added a special measurement:
var offset = window.outerHeight - window.innerHeight
This is the top of the browser to the bottom of the browser bar (or top of viewport). The new coords called UselessXY takes the height of the browser's bar and adds it to the Y coord. If the browser is resized, then it needs to be refreshed in order to get the new offset. This works best if the browser is maximized.
I made a function that'll display clientX, clientY, screenX, and screenY. And offset and uselessXY
Just click anywhere to get coordinates.
SNIPPET
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>COORDS</title>
<style>
*, *:before, *:after { margin: 0; padding: 0; }
body { width: 100vw; height: 100vh; position: relative; }
#display { width: 40ex; height: 50px; border: 1px solid grey; padding: 3px; position: absolute; }
</style>
</head>
<body onmousedown="coords(event)">
<figure id="display" onmouseover="this.style.left = '50%'" onclick="this.style.left = '0'">
<figcaption><u>Coordinates(X,Y)</u></figcaption>
<output id="xy"></output>
</figure>
<script>
function coords(evt) {
document.getElementById('xy').textContent = "screenXY: " + evt.screenX + ", " + evt.screenY +" | clientXY: " + evt.clientX + ", " + evt.clientY+" | Offset: "+offset+" | UselessXY: "+evt.screenX+", "+(evt.screenY + offset);
}
var offset = window.outerHeight - window.innerHeight;
</script>
</body>
</html>

How do i find the absolute coordinates?
use offsetTop
Suppose element's id is
var d = document.getElementById("socialChange");
var topPos = d.offsetTop;
Another question is does window.screenX takes into account url and tab
bar into account?
No, check the documentation here. Area covered by browser's controls are excluded out of the window.screenX and window.screenY.

x_axis = window.screenX + (window.outerWidth - window.innerWidth) + element.getBoundingClientRect().left
The above will get the absolute length from the left of the screen.
Similar case can be done for the y axis.
For the conceptual point of view, this picture can be used.

Related

jQuery - Draggable Div with width and height counter (Demo code included)

All.
I've been messing with this project for a few days, trying different codes, making some progress, then getting stuck.
The below code is the closest I've come to a working example.
This one counts the WIDTH from the LEFT panel.
I need it to count the WIDTH from the RIGHT panel.
--UPDATED--
I've made it drag from the RIGHT, and it calculates its width from the RIGHT. Unfortunately, the HEIGHT is still not working when the div grows in height, but the width counts.
As you will see when you run the demo below, when you drag the bar, the left panel does not stay attached, along with other issues.
Almost as if it was designed to run one way only.
I know I am missing something here, just not sure what?
Best Viewed In Full Screen.
Thank you.
Wayne
Here is the code
var info = document.getElementById('Info');
var left = document.getElementById('drag-left');
var right = document.getElementById('drag-right');
$(function() {
$(right).resizable({
minHeight: 200,
minWidth: 320
});
$(left).resizable({
minHeight: 200,
minWidth: 320
});
});
// Left Panel
$(right).resizable({
handles: 'w',
resize: function(event, ui) {
// var width = $("body").width() - ui.size.width;
// var height = $("body").height() - ui.size.height;
var width = ui.size.width;
var height = ui.size.height;
$(left).width(left);
$(info).text("Width: " + width + "px; & Height: " + height + "px;");
}
});
/*This is to create the BAR in the middle to grab.
To change which one gets it, change the (e) to (w)
E = Left panel
W = Right Panel*/
.ui-resizable-w {
background-color: black;
}
.ui-resizable-w:hover {
cursor: col-resize;
}
* {
box-sizing: border-box;
}
p {
color: darkslategray;
}
.drag-container {
display: flex;
width:1000px;
padding:5px;
}
[class^=panel] {
padding: 60px 24px;
background-color: whitesmoke;
}
.panel-one {
width: 100%;
flex: 1 1 auto;
}
.panel-two {
width: 60%;
}
#drag-right, #drag-left {
min-height:200px;
min-width:320px;
border:1px double green;
}
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CodePen - Simple JS Dragbar</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<link href = "https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css" rel = "stylesheet">
<script src = "https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
</head>
<body translate="no" >
<div class="drag-container">
<div class="panel-one" id="drag-left">
<h2>Panel 1</h2>
<p>Look, everyone wants to be like Germany, but do we really have the pure strength of 'will'? But I know you in the future. I cleaned your poop. Large bet on myself in round one. Take me to your leader! My fellow Earthicans, as I have explained in my book 'Earth in the Balance'', and the much more popular ''Harry Potter and the Balance of Earth', we need to defend our planet against pollution. Also dark wizards.</p>
</div>
<div class="panel-two" id="drag-right">
<h2>Panel 2</h2>
<p>So, how 'bout them Knicks? You guys go on without me! I'm going to go… look for more stuff to steal! Guards! Bring me the forms I need to fill out to have her taken away! Do a flip! Calculon is gonna kill us and it's all everybody else's fault!</p>
</div>
</div>
<div style="float:right; height:30px; width:320px; border:1px double green; padding:40px 4px;">Width: 320px;<br />
<span id="Info">Information Goes Here</span>
</div>

How to generate a new image from overlaid text and images over one large background image using Javascript?

I've got an image on the page (I'll call it the background image) and I've allowed the user to enter some text that is positioned via css over the background image. As well, there are a few other small images that will be automatically position over the background image using css based on the text.
I want to turn what the user setup/created into an actual downloadable image now, essentially "flattening the layers" in photo editing terms.
I'd also ideally like to do this at a very high resolution as the original background image exists in a much larger and higher resolution format than the one the people see when editing.
I'm not sure the best way to do this. I'd be using NodeJS and Lambdas.
One solution I think would be to perhaps have another page exist with the full size background image and have the css reposition and resize everything perfectly and take a screenshot with puppeteer or something, although I don't know if that'll lose the quality of the original image somehow?
Or do I size the overlayed text and images correctly for the background and take screenshots of each of them, somehow add transparency, and then somehow merge the pictures?
Is there a way easier thing I'm missing or some package that can help?
If you create an element which has the full-size image, overlay the users' text and any other required image - both suitably scaled up in size and position, you can save that element on a canvas and then convert that to an image.
Here is some code to give the idea. It's using html2canvas but actually you could just create the canvas and draw the images and write the text to it without needing a library if preferred. (The code runs from my server and on my laptop and on https://codepen.io/rgspaces/pen/RwoNxVQ but does not run in a SO snippet - ??a CORS problem with iframe inside snippet system??).
<head>
<script src="https://ahweb.org.uk/html2canvas.js"></script>
<style>
body {
overflow: hidden;
margin: 0;
padding: 0;
box-sizing: border-box;
--t: 20px; /* distance from top of the user's text in the workspace */
--l: 20px; /* distance from left of the user's text */
--f: 30px; /* fontsize of the user's text in the workspace */
}
#big {
position: absolute;
left: 100vw;
display: none;
width: auto;
height: auto;
}
#workspace {
width: 50vw;
height: auto;
}
#workspace .mainimg {
width: 100%;
height: auto;
}
#workspace .text, #big .text {
position: absolute;
color: white;
}
#workspace .text {
top: var(--t);
left: var(--l);
font-size: var(--f);
}
</style>
</head>
<body>
<div id="big">
<img id="bigimg" src="https://picsum.photos/id/1016/3844/2563.jpg" class="mainimg" crossOrigin = "anonymous">
<div class="text"></div>
</div>
<div id="workspace">
<img src="https://picsum.photos/id/1016/3844/2563.jpg" class="mainimg">
<div class="text">User's text</div>
<!-- other imgs -->
</div>
<p>YOUR IMAGE WILL APPEAR BELOW - RIGHT CLICK TO SAVE IT TO FILE (WINDOWS); PRESS TO SAVE TO PHOTOS (IOS)</p>
<img id="resultimg" style="clear:both;" src=""/>
<script>
function start() {
let big = document.getElementById('big');
let bigImg = document.getElementById('bigimg');
let bigText = document.querySelector('#big .text');
let width = bigimg.width;
let height = bigimg.height;
let workspace = document.getElementById('workspace');
let workspaceText = document.querySelector('#workspace .text');
let props = window.getComputedStyle(workspace, null);
let scaling = width/props.getPropertyValue("width").replace('px','');
bigText.innerHTML = workspaceText.innerHTML;
// just some simple scaling to give an idea for now
bigText.style.fontSize = 'calc(var(--f) * ' + scaling + ')';
bigText.style.top = 'calc(var(--t) * ' + scaling + ')';
bigText.style.left = 'calc(var(--l) * ' + scaling + ')';
big.style.display = 'inline-block';
window.scrollTo(0, 0);
html2canvas(big, {allowTaint: true, useCORS: true, logging: true, width: width, height: height})
.then((canvas) => {
big.style.display = 'none';
document.body.style.overflow = 'visible';
const imgData = canvas.toDataURL('image/png', 1);
const resultImg = document.getElementById('resultimg')
resultImg.src = imgData;
resultImg.style.width = width + 'px';
resultImg.style.height = 'auto';
});
}
window.onload = start;
</script>
</body>
</html>

How to position rotated element to the right edge

I am trying to align an absolute element (image in this case) to the right edge of the container.
It works if the element is not rotated, but when a transformation is involved, the left property is not calculated correctly.
Maybe I am missing something, but the solution I am using right now is getBoundingClientRect() to get the width and then subtract it from the container width.
Here is a JSFiddle that demonstrate what I am doing.
getBoundingClientRect is a good approach, the problem is that when you set css left, it positions it without the rotation calculated. The order in which you set it doesn't change the fact the the rotation is applied in relation to the css, not in relation to the current position of the rotated div. So when you calculate dimensions using getBoundingClientRect you're taking into account the rotation, then you use it on a css that doesn't take it into account.
One easy way to get proper coordinates, would be to calculate the x difference between before rotation and after and adjust you left accordingly. You'll have prevDimension.x - dimension.x giving you the difference in x that the rotation is creating, which allows you to adjust newLeft.
Like this:
$('#rotate-align').click(function () {
var prevDimensions = $('.element')[0].getBoundingClientRect();
$('.element').css('transform', 'rotate(0.99923rad)');
var dimensions = $('.element')[0].getBoundingClientRect();
var newLeft = $('#bounds').width() - dimensions.width - dimensions.x + prevDimensions.x;
$('.element').css('left', newLeft);
});
http://jsfiddle.net/jgcynwmp/3/
Another approach would be to calculate the x difference based on the width difference between the non rotated element and the rotated element. This can be done using offsetWidth (which doesn't take the rotation into account) and the getBoundingClientRect. The difference between the 2 will tell you how much width is lost with the rotation. Note that for this calculation, the transform origin is important. For example, with a centered rotation, you'll need to divide by 2 the width difference to get the x difference, but with another origin it would be something else.
Like this:
$('#rotate-align').click(function () {
$('.element').css('transform', 'rotate(0.99923rad)');
var dimensions = $('.element')[0].getBoundingClientRect();
var newLeft = $('#bounds').width() - $('.element')[0].offsetWidth + (($('.element')[0].offsetWidth - dimensions.width) / 2);
$('.element').css('left', newLeft);
});
http://jsfiddle.net/jgcynwmp/4/
There is a JSFiddle here.
When the image is rotated, the bounding rectangle remains in the place of the rotation, instead of being to the transformed coordinates.
I added a 'bcr' <div> element which then is matched to the bounding client rectangle.
After the rotation we can move the image into place (477 is the absolute right of bounds).
There appears to be a small problem if you repeatedly click the button, but I guess that's the magic of CSS transforms!
$('#align').click(function () {
var newLeft = $('#bounds').width() - $('.element').outerWidth();
$('.element').css('left', newLeft);
});
$('#rotate-align').click(function () {
$('.element').css('transform', 'rotate(0.69923rad)');
var dimensions = $('.element')[0].getBoundingClientRect();
$('.element').css('left',477-dimensions.width-dimensions.left);
$('#bcr').css('left',dimensions.left);
$('#bcr').css('top',dimensions.top);
$('#bcr').css('width',dimensions.width);
$('#bcr').css('height',dimensions.height);
});
#bounds {
width:427px;
height:354px;
left:50px;
top:38px;
border: 1px solid red;
position: absolute;
}
#bcr {
width:327px;
height:254px;
left:150px;
top:138px;
border: 1px solid green;
position: absolute;
}
.element {
top: 100px;
z-index: 102;
line-height: 82px;
width: 312px;
height: 82px;
#transform: rotate(0.99923rad);
left: 0;
position:absolute;
border: 1px solid green;
}
.element-img {
width: 100%!important;
height: 100%!important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="bounds">
<div class="element">
<img class="element-img" src="https://www.google.com/logos/doodles/2014/2014-winter-olympics-5710368030588928-hp2x.jpg"> </div>
</div>
<input type="button" id="align" value="Align right" style="width:100%;" />
<input type="button" id="rotate-align" value="Rotate and align right" style="width:100%;" />
<div id="bcr"></div>

How to find a position somewhere in div tag using jquery

Also please view the attached image for clarification. I have a div container what I want to to find a position somewhere in that div container using jquery or javascript or both. The attached image shows everything. Please help.
Update
The reason I want to find this position is that I want to animate container towards that point and eventually disappear. Secondly I would like to find position on the opposite side too so that I could animate container from that position.
Second update
In other words how can we find the point of intersection of two lines?
Given you need to find the intersection between two lines inside a div, your markup could look like this:
<div id="container" style="position:absolute; width: 100%; height: 200px;">
<div style="width: 2px; height: 100%; left: 20%; position:absolute; background-color: red; top: 0;"></div>
<div style="height: 2px; width: 100%; left: 0; position:absolute; background-color: blue; top: 25%;"></div>
</div>​
Using jQuery, you can find the coordinates for the intersection like this:
var x = $('#container div:first').position().left;
var y = $('#container div:last').position().top;
console.log(x,y);
x and y would be the coordinates in pixels relative to the container element.
http://jsfiddle.net/sAsmj/
I dont see the image, however if you are looking at getting the position, which is ideally caret position, you can use the jquery plugin http://plugins.jquery.com/project/jCaret
You can find the poiter position by using this, try it
$(document).ready(function(){
$("div#container").on("mousemove", function(e){
var self = $(this);
var dx = e.pageX;
var dy = e.pageY;
var x = dx - self.offset().left ;
var y = dy - self.offset().top ;
console.log(x);
console.log(y);
});
});
If you want the X, Y of the mouse you can read this question:
getting the X/Y coordinates of a mouse click on an image with jQuery
Here is an excerpt from the question which is based upon an img but you can change it for your container:
$(document).ready(function() {
$('img').click(function(e) {
var offset = $(this).offset();
alert(e.clientX - offset.left);
alert(e.clientY - offset.top);
});
});

How to get the maximum possible width of a div?

I need to know how one can get the maximum possible width of a div. Generally, a <div>'s width is limited by it's parent, meaning that it can not be larger than a certain amount. How that certain amount can be calculated?
I need this to calculate if the text inside the current <div> has overflown, (since the only way to detect a text overflow is to compare it's current width to its current clientWidth).
Thanks!
A couple ways to do this, let's start with your div...
<div id='mr_cleaver'>
<div id='beaver'>Blah</div>
</div>
...and then someJavascript:
//Method One: Find the width of the div's parent
var max_beaver_width = $('mr_cleaver').offsetWidth
//Method Two: Max out the div, find length, return to original size.
var beaver_width = $('beaver').offsetWidth;
$('beaver').style.width = "100%";
var max_beaver_width = $('beaver').offsetWidth;
$('beaver').style.width = beaver_width + 'px';
//Method Three: Check for overflow
$('beaver').scrollWidth > $('beaver').offsetWidth ? alert("Over") : alert("Within")
Thanks Steve!
Your suggestions were very helpful. Although none of them worked for me(probably I didn't explain my situation very well), but using your hints, I could find a way to detect text overflow:
/* specifying the height of 'beaver'*/
var font_size= $('beaver').css("font-size");
font_size = parseInt(font_size.replace(/[a-z]*/gi,''));
var maxHeight = font_size + 4; // 4 is to make sure that the font fits in the maxHeight
/*now calculate current height*/
$('beaver').style.overflow-y:visible;
$('beaver').style.overflow-x:hidden;
var cuurentHeight = $('beaver').clientHeigth;
/* check whether overflow is occured*/
if(cuurentHeight > maxHeight){
//overflow has been occured
}
If you want the div to be 100 % in width with no space between the edges, you can try to add this simpel CSS style to the div:
<style type="text/css">
#FullWidthDiv { // EDIT
position: absolute; // If you use 'fixed' as position, then the div
display: block; // won't become smaller when the screen is at is smallest.
float: left; // The fixed position is good when you for example want the
width: 100%; // menu to stay in place.
background-color: #06F;
height: auto;
left: 0px;
top: 0px
}
</style>
<html>
<body>
<div id="FullWidthDiv"></div>
</body>
</html>
You can append a div into parent element to measure it.
var test = document.querySelector('#test');
var div = document.createElement('div');
div.style.width = '10000px';
test.appendChild(div);
var maxWidth = test.offsetWidth;
test.removeChild(div);
alert(maxWidth);
#test {
display: inline-block;
max-width: 100px;
}
<div id="test"></div>

Categories