I want to get real X and Y position of my styled elements in javascript ( or jquery short code).
var offset = obj.offset();
ox=offset['left'];
oy=offset['top'];
px=parseInt(obj.css('padding-left')); // padding left
py=parseInt(obj.css('padding-top')); // padding top
bx=parseInt(obj.css('border-width') ); // stroke value
ox=ox+px+bx;
oy=oy+py+bx;
But this codes sometimes not work..
when scrool top or scroll left change im not get real position :(
please help me..
You don't have to use offsets. Use the modern getBoundingClientRect function:
function getPosition( element ) {
var rect = element.getBoundingClientRect();
return {
x: rect.left,
y: rect.top
};
}
You could then use the above function like this:
var element = document.getElementById( 'myElement' );
var pos = getPosition( el );
// Alert position in X axis
alert( pos.x );
// Alert position in Y axis
alert( pos.y );
Works in all browsers 🙂
EDIT: If you want the position of the element with respect to page scroll, just add document.body.scrollTop to Y position and document.body.scrollLeft to X position.
You'll want the offset from the element relative to the document. You have to keep in mind that styles like padding, margin and border can greatly affect the result of the offset. You might want to calculate those on or off the offset.
Finally you need to check if you are using box-sizing, which pushing padding and borders to the inside (with the most common version box-sizing: border-box;);
document.getElementById('cloud').offsetLeft; //offsetTop
Just debug with the other styles (adding/subtracting) until you get the real offset. I mostly test if the offset is correct by making a screenshot (or using the OS X selective-screenshot function) to see if the offset is correctly calculated (counting pixels) with the other styles.
Here's a little example:
CSS
#cloud {
height: 500px;
width: 500px;
margin: 20px auto;
border: 1px dotted #CCC;
}
HTML
<body>
<div id="cloud">
<div id="centerBox"></div>
</div>
</body>
JavaScript
'use strict';
console.log(document.getElementById('cloud').offsetLeft);
console.log(document.getElementById('cloud').offsetTop);
Ouput
main.js: 1 >>> 372
main.js: 2 >>> 20
Funny thing here, you can easily test if the offsetLeft works because of the margin: 20px auto;. If you resize the window it will also have a different offsetLeft.
This function gives you the exact position of an element without padding or margin or border:
function getElementRec(element) {
let rec = { x: 0, y: 0, width: 0, height: 0 };
let computedStyle = getComputedStyle(element);
rec.width = element.clientWidth;
rec.width -= parseFloat(computedStyle.paddingLeft);
rec.width -= parseFloat(computedStyle.paddingRight);
rec.height = element.clientHeight;
rec.height -= parseFloat(computedStyle.paddingTop);
rec.height -= parseFloat(computedStyle.paddingBottom);
let boundingRect = element.getBoundingClientRect();
rec.x = boundingRect.left;
rec.x += parseFloat(computedStyle.paddingLeft);
rec.x += parseFloat(computedStyle.borderLeft);
rec.y = boundingRect.top;
rec.y += parseFloat(computedStyle.paddingTop);
rec.y += parseFloat(computedStyle.borderTop);
return rec;
}
var offset = obj.offset();
ox=offset['left']; = document.getElementById('Mypicture').offsetLeft;
oy=offset['top']; = document.getElementById('Mypicture').offsetTop;
px=parseInt(obj.css('padding-left')); // padding left
py=parseInt(obj.css('padding-top')); // padding top
bx=parseInt(obj.css('border-width') ); // stroke value
ox=ox+px+bx;
oy=oy+py+bx;
//Two codes get equal value; But Not Real clientX ClientY positions..
// My html:
<div id="container">
<img id="Mypicture" src="myimage.jpg" alt="The source image for paint"/>
</div>
//My css :
#Mypicture{
margin:100px;
padding:20px;
border: 20px solid #cacaca;
}
#container {
display:block;
background:#ffaaff;
width: 550px;
padding:50px;
margin-left:300px;
}
// I want to get realx and realY value of Mypicture,on Document.
// All codes work Realx ( ox ) return true value But RealY (oy) nearly 10px false;
Related
Without using jQuery, is there a way to get an element's current position and add/subtract from it? Let's say an element has this CSS
position: relative;
top: 400px;
/*400px away from the top*/
Can JavaScript get the amount of pixels from "top" and subtract from it? I know that I can directly edit the top property with document.getElementById("element").style.top , but I want to get the value itself first, then subtract a number of pixels from that value, and then put the new value as the position. Is this possible?
Yes you need to get the computedStyle of the element let rect = getComputedStyle('el'), assign this to a variable then you can use the top position to get amount set in your class => rect.top will give you the top position.
const cont = document.querySelector('.cont')
function getTopPos(el){
// get the computed style of element
// get the top position using .top
// split at px and get the first index which will be the number
// subtract it by desired amount and concatenate px measurement back to the value
let was = getComputedStyle(el).top;
el.style.top = `${getComputedStyle(el).top.split('px')[0] - 300}px`
console.log(`top position is now: ${getComputedStyle(el).top.split('px')[0]}px, was: ${was}`)
}
getTopPos(cont)
* {
margin: 0;
padding: 0;
}
.cont {
width: 100px;
height: 100px;
background: red;
position: relative;
top: 400px;
}
<div class="cont">Was 400 pixels from top, now 100 pixels from top</div>
Something like this? Get the position from the top of the viewport, then subtract a value and return the new "offset from top value":
const offsetValue = 49
const findNewPosition = (offset) => {
const element = document.querySelector('#elementId').getBoundingClientRect().top
return element - offset
}
findNewPosition(offsetValue)
I think this works (it did for my case):
var eee = document.getElementById('elementId').style.top.replace("px", "");
var aaa = parseInt(eee, 10);
aaa = aaa - 300;
document.getElementById('elementId').style.top = aaa + `px`;
(excuse my bad english, I am 13 years old)
alright, even though i just joined stackoverflow today, I have been coding for a while. I'm trying to make a simple game (and may make it something bigger later) and I want the hammer (the player sprite) not be able to go through the box toward the middle of the screen, but I don't know how. here is what I have:
var sq = document.getElementById("box");
var posX = 0;
var posY = 0;
var rot = "rotate(0deg)";
var id = null;
function move(object, pixels, xa){
if(xa == true) {
posX+=pixels;
object.style.left = posX + 'px';
}else{
posY+=pixels;
object.style.top = posY + 'px';
}
}
OBJect.style.left = "200px";
OBJect.style.top = "200px";
document.addEventListener('keydown', logKey);
function logKey(e) {
if (`${e.code}` == "ArrowRight") {
rot = "rotate(90deg)";
sq.style.transform = rot;
move(sq, 5, true);
if(posX > 470){
posX = 5;
}
}
if (`${e.code}` == "ArrowLeft") {
rot = "rotate(270deg)";
sq.style.transform = rot;
move(sq, -5, true);
if(posX < 0){
posX = 465;
}
}
if (`${e.code}` == "ArrowDown") {
rot = "rotate(180deg)";
sq.style.transform = rot;
move(sq, 5, false);
if(posY > 465){
posY = 5;
}
}
if (`${e.code}` == "ArrowUp") {
rot = "rotate(0deg)";
sq.style.transform = rot;
move(sq, -5, false);
if(posY < 0){
posY = 470;
}
}
}
setInterval(function(){
xaxis.innerHTML = "x: " + posX;
yaxis.innerHTML = "y: " + posY;
rotate.innerHTML = rot;
},1);
#myContainer {
width: 500px;
height: 500px;
position: relative;
background: black;
outline: red solid 10px;
}
#box {
width: 30px;
height: 30px;
position: absolute;
background-color: gray;
}
#OBJect {
width: 30px;
height: 30px;
position: absolute;
background-color: gray;
}
<!DOCTYPE html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<style>
/*style would go here/*
</style>
<body>
<div id="myContainer">
<img src="https://cdn.glitch.com/7f9c2ae2-9b45-42a1-a387-380de7f5d3bd%2Fhammer.png?v=1615308683807" alt="hammer" id="box">
<div id="OBJect"></div>
</div>
<br><br>
<div id="xaxis"></div>
<div id="yaxis"></div>
<div id="rotate"></div>
<script>
//script would go here
</script>
</body>
</html>
yeah, yeah, I know. I could definetly improve, but I only know basic things,and some of these from either Stackoverflow or w3schools, and yes, I know there is a lot of solved answers with this problem, but I get confused by them because they are too complicated for me. I just request easy, simple code to understand (if it isn't, please label things so I know).
sorry if this is too much, I just need help :/
so to do this you need to know the 4 corners of each element then you need to check if the other object is within the players bounds
they're both rectangles and to be touching 1 of these statements have to be true
the top left corner of the square is to the right of the top left corner of the player and the top left corner of the square is to the left of the top right corner of the player while the top left corner of the square is less than the y of the top side and higher than the y of the bottom side
the top right corner of the square is to the left of the top right corner of the player and the top right corner of the square is to the right of the top left corner of the player while the top right corner of the square is less than the y of the top side and higher than the y of the bottom side
same as 1 & 2 but with the bottom left and right corners
if one of the corners has the same x and y as a corner on the other object or if the position of one object is the same as the other
a second way to do this is using Pythagoras theorem to get the distance between two points
a^2 + b^2 = c^2
how that would look in code
let c = Math.sqrt(Math.pow(Math.abs(x1 - x2), 2) + Math.pow(Math.abs(x2, y2), 2))
this is a little tricky but the distance between two points is a triangle in a sense so the distance on x and y form the two legs then to get the actual distance we need the hypotenuse which is what Pythagoras theorem gets us. So to get a and b we need to get the absolute value of the first minus second x and y to get the distance on x and y then we square them with Math.pow() and add them but that gives us c^2 and we just want c so we get the square root with Math.sqrt() which gives us the distance then the one other thing we have to do is get the center of the objects to use as a and b. Since you're working with javascript on a webpage the X and Y values are for the top left corner so you need to add half the width and height to x and y appropriately to get the center of the object, then you can use the distance formula. the only problem with this approach is that it works best for circles because every point around the edge is equally distant from the center which isn't true for a square.
So personally I would use the first method, you can get the other corners by using width and height to add to the position of the top left corner to get the other positions. it's more code but more precise than distance because you're checking the bounds of each object rather than checking distance from center
I also joined today and I am 12. since the hammer is an img, you can use css:
I think your question was that you want to move the hammer, if yes:
var left = 0; /*left and top can be edited in your code but*/
var top = 0;/*you have to reset them using the code below*/
var hammer = document.querySelector('#hammer');
hammer.style.left = left + 'px';
hammer.style.top = top + 'px';
#hammer {
position: absolute;
left: 0px;
right: 0px;
}/*set left and right via js*/
<!--just add an id like #hammer to the hammer-->
i have a div of static width and height and i want to know its bottom right corner so that i can use it for top and left of another div
so basically the coordinates of the marked point in the image below,
i have tried to bottom = rect.top + rect.height;
right = rect.top + rect.height;
i dont think above is correct. could someone help me get the bottom right corner of the div.thanks.
You should use getBoundingClientRect. This function returns the size of an element and its position relative to the viewport.
document.getElementById('foo').getBoundingClientRect();
// => {
// top: Number,
// left: Number,
// right: Number,
// bottom: Number,
// x: Number,
// y: Number,
// width: Number,
// height: Number,
// }
From there I think you can do some simple math to get the bottom right corner.
Link: https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect
botRightX = rect.left + rect.width
botRightY = rect.top + rect.height
You could use the .offsetHeight and .offsetWidth properties to get the height and the width of you first div. Like this:
var height = document.getElementById('yourDivId').offsetHeight;
and
var width = document.getElementById('yourDivId').offsetWidth;
const boundingRect = div.getBoundingClientRect();
const bottom = div.bottom - div.top;
const right = div.right - div.left;
Assuming that div is the element you want to target.
Hi I am using a hashmap that allows me to efficiently detect objects in the given coordinates. However it is working perfectly , the problem lies with using the mouse to gather the position of the mouse within the canvas down to the pixel. I have been using the offsetX and offsetY methods for the event to gather some offset but it seems there is an offset I am unaware of and may have something to do with either:
1.using scaling on the canvas , Note: ive tried to fix this by division of the renderscale, this works with everything else so should be fine here.
mouseoffset is not accounting for parts of the page or is missing pixels at a low level (maybe 20) but divided by the render scale thats massive.
3.I am using a cartesian coordinate system to simplify things for the future , so the game map is in cartesian and may have to do with the problem.
I will not be supplying all the code because it is allot of work to go through it all so i will supply the following :
the html/css canvas code
<html lang="en">
<head>
<meta charset="UTF-8">
<title> Game</title>
</head>
<body onload="jsEngine = new JsEngine(24, 24, .1); " >
<div class ="wrapper">
<canvas id="canvas" width="1920" height="1080"></canvas>
</div>
<style>
.wrapper {
position: relative;
width: auto;
height: 900px;
}
.wrapper canvas {
position: absolute;
left: 90px;
top: 50px;
padding-left: 0;
padding-right: 0;
margin-left: auto;
margin-right: auto;
display: block;
width: 90%;
height: 90%;}
.GUI{
top: -315px;
left: -302px;
position: absolute;
width: 300px;
height: 300px;
background-color: cadetblue;
opacity: .5;
word-wrap: break-word;}
img{
image-rendering: optimize-contrast;
}
</style>
<div id = GUI class = "GUI"></div>
<!-- Libraries -->
<script src="../myapi/JSONE.js"></script>
<script src="../myapi/engine/SpacialHash.js"></script>
</body>
</html>
2.the javascript click function
//Click on objects
let onClick = function(event){
let canvas_ctx = document.getElementById("canvas").getContext("2d");
let canvasOffsetX = canvas_ctx.canvas.width/2;
let canvasOffsetY = canvas_ctx.canvas.height/2;
let mousePosX = event.clientX;
let mousePosY = event.clientY;
let mouseX =jsEngine.cameraFocus.x-canvasOffsetX/jsEngine.renderScale+(mousePosX)/jsEngine.renderScale;
let mouseY = jsEngine.cameraFocus.y+(canvasOffsetY)/jsEngine.renderScale+((-mousePosY)/jsEngine.renderScale);
console.log("sum to",mouseX,mouseY);
//My hashMap to place the mouse coordinates on the game map
let clickPosition = hm.find({x:mouseX,y:mouseY,width:1,height:1});
if(clickPosition.length===1){
let gameObject = jsEngine.gameObjects[clickPosition[0].range.id];
//console.log(gameObject.transform.x,gameObject.transform.y,mouseX,mouseY);
let clickBox = {};
let picture = gameObject.texture;
guiCreateClickBox(clickBox,gameObject.id,1200,500,picture);
}else if(clickPosition.length>1) {
for (let i = 0; i < clickPosition.length; i++) {
let gameObject = jsEngine.gameObjects[clickPosition[i].range.id];
if (gameObject instanceof PlayerShip|| gameObject instanceof Bullet)
continue;
let clickBox = {};
let picture = gameObject.texture;
guiCreateClickBox(clickBox,gameObject.id,1200,500,picture);
//console.log(gameObject.transform.x,gameObject.transform.y,mouseX,mouseY)
}
}
};
// Listeners
//Click on objects
document.getElementById("canvas").addEventListener("click", onClick);
the making of the map and scale :Note: this is done via onPreRender
function drawBackground(canvas_ctx, renderScale, imageResource) {
let img = imageResource.mapBackground;
let mapWidth = 1000000;
let mapHeight= 1000000;
let zoom = 1;
mapWidth *= renderScale / zoom;
mapHeight *= renderScale / zoom;
// Render the Background
canvas_ctx.fillStyle = canvas_ctx.createPattern(img, 'repeat');
canvas_ctx.scale(zoom, zoom);
canvas_ctx.fillRect(-mapWidth / 2, - mapHeight / 2, mapWidth, mapHeight);
//if (jsEngine.cameraFocus.x > 1000000) {}
canvas_ctx.scale(1/zoom, 1/zoom);
}
The rendering method used for playership
renderGameObject(gameObject) {
let x = gameObject.transform.x * this.renderScale;
let y = -(gameObject.transform.y * this.renderScale);
let rotation = Math.radians(gameObject.transform.rotation);
let width = gameObject.transform.width;
width *= this.renderScale;
let height = gameObject.texture.height;
height *= this.renderScale;
// Render the gameObject
this.canvas_ctx.translate(x, y);
this.canvas_ctx.rotate(rotation);
this.canvas_ctx.drawImage(gameObject.texture, 0, 0, width / this.renderScale, height / this.renderScale, // Make sure the image is not cropped
-width/2 , // X
-height/2 , // Y
width, height); // width and height
this.canvas_ctx.rotate(-rotation);
this.canvas_ctx.translate(-x, -y);
}
the issue to solve is to make it so that when you click on any given quadrant of the canvas it will return -+ for top left, -- bottom left , -+ topright, +- bottomright, as well as being applied to the render scale which at the moment is .1 so just divide your mouse and canvas coords like shown above and you should be able to get the same results.
Things to keep in mind :
the jsEngine.cameraFocus is set to the playerships x and y coordinates(which are set to the 0,0 posiiton on the map) (which are also in the middle of the ship)
the top left of the canvas is still 0,0 and ++ is still toward the bottom right so theoretically minusing half the canvas width/height then adding the offsets X and Y. this should be working but at my map coordinate -4000,-4000 i get ~-3620,-3295 and at +4000,+4000 I get 3500,3500. (The reason why the canvas 0,0 is not where the ship is , is to make the ship in the middle of the screen)
If you have questions about anything based on code that needs to be supplied please ask via comment . Please note if you have problems with the format of the code supplied I have nothing to say about it . all I need is the click function working on the canvas model i set up in cartesian format.
ps: jQuery is not a solution its a problem please use vanilla js.
I found out why it was off , my canvas has a offset of 90 px and 50 px as well as the main problem that the canvas is only 90% of its origonal size (also in css). If anyone can give me help for how to adjust to these issues please reply in comment . until then I beleieve I have solved my own issue .
How to position an element for e.g. a div tag by using values for x & y co-ordinates from Javascript variables ?
If you're trying to position the object in absolute x,y coordinates on the page, just set the object to position: absolute and then set the values of top and left to your x and y.
HTML:
<div id="square" style="background-color: #777; height: 100px; width: 100px;"></div>
Code:
var s = document.getElementById("square");
s.style.position = "absolute";
var x = 100, y = 200;
s.style.left = x + "px";
s.style.top = y + "px";
You can see a working code example here: http://jsfiddle.net/jfriend00/hhpDQ/.
I'm not sure you can set the coordinates, but you could set the margin. Something like
$("#divid").css("margin-left" : "200px" , "margin-up" : "200px");