I want to get the exact positions of the div using its class name. Here is the screenshot.. My script which is finding a div position is highlighted in yellow and the div i am looking for is at the bottom highlighted red. Since my script is placed above the div so i am finding the parent div of the document and then comparing the div class with the div class i am looking for and thats how i am getting the positions. The positions are not exact. For example if the Top and Left position of the div is 50,150 then i am getting like 55,155.
function getPosition(element) {
var xPosition = 0;
var yPosition = 0;
var left = 0;
var top = 0;
var i = 0;
while (element) {
xPosition = (element.offsetLeft);
yPosition = (element.offsetTop);
console.log("TOP Pos: "+yPosition+"Left Pos: "+xPosition);
if (i == 1) {
left = xPosition;
top = yPosition;
}
element = element.offsetParent;
i++;
}
return {
x: left,
y: top
};
}
And this is how i am using this method.
function ReadDivPos(selector) {
var _divPos = "";
var parentDoc = window;
while (parentDoc !== parentDoc.parent) {
parentDoc = parentDoc.parent;
}
parentDoc = parentDoc.document;
var parentDiv = parentDoc.getElementsByTagName('div');
var divs = [];
for (var i = 0; i < parentDiv.length; i++) {
if (parentDiv[i].className == "content") {
var pos = getPosition(parentDiv[i]);
var x = pos["x"];
var y = pos["y"];
console.log("Values+ Top: " + y + " Left: " + x);
var w = parentDiv[i].offsetWidth;
_divPos += x + "," + w + "," + y + "," + (x + w) + ","+window.screen.availWidth+"\\n";
}
}
console.log("Values+ x: " + _divPos);
return _divPos;
}
This is working fine but i am just wondering is there any other better way to make it done using jquery or any other method. Thanks in advance!.
See :
$(function() {
var x = $(".target").offset().left,
y = $(".target").offset().top;
$(".target").html("x: " + x + " y: " + y);
});
body
{
padding: 0;
}
.target
{
background-color: lightgreen;
width: 7em;
height: 7em;
line-height: 7em;
text-align: center;
left: 100px;
top: 20px;
font-family: Calibri;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="target"></div>
Related
I have Layout with a machine, i intend to have this machine (purple animation) move from point A to point B based on input cordinate x and cordinate Y. I followed some online tutorials but still not been able to get it. The animation currently moves manually with arrow keys but i intend to have it move automatically. The aim is to have the animation move at a slow frame pace to the inserted coordinates. Any help will be appreciated.
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title> Farm Harvest </title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="grid"></div>
<input type="number" id = 'cords1' placeholder="X-Cordinates">
<input type="number" id = 'cords2' placeholder="Y-Cordinates">
<button id = "mybtn" onclick="myCords();">Get Value</button>
<script src="app.js"></script>
</body>
</html>
CSS:
.grid {
position: absolute;
width: 560px;
height: 300px;
border: solid 1px black;
margin-top: 100px;
}
.user {
position: absolute;
width: 30px;
height: 20px;
background-color: blueviolet;
}
.block {
position: absolute;
width: 100px;
height: 20px;
background-color: blue;
}
JS:
const grid = document.querySelector('.grid')
const value1 = document.getElementById('cord1')
const value2 = document.getElementById('cord2')
const blockWidth = 100
const blockHeight = 20
const boardWidth = 560
const boardHeight = 300
var mouseX, mouseY;
var stepWidthFactor = 200;
const userStart = [10, 270]
let currentPosition = userStarnst userStart1 = [10, 270]
let currentPosition1 = userStart1
const user1 = [10, 270]
let currentPosition2 = user1
//my block
class Block {
constructor(xAxis, yAxis) {
this.bottomLeft = [xAxis, yAxis]
this.bottomRight = [xAxis + blockWidth, yAxis]
this.topRight = [xAxis + blockWidth, yAxis + blockHeight]
this.topLeft = [xAxis, yAxis + blockHeight]
}
}
class moveblock{
constructor(xAxis,yAxis){
this.xAxis = inputval0;
this.yAxis = inputval1;
let currentPosition3 = user2;
}
}
//all my blocks
const blocks = [
new Block(120, 210),
new Block(230, 210),
new Block(340, 210),
new Block(120, 140),
new Block(230, 140),
new Block(340, 140),
new Block(120, 70),
new Block(230, 70),
new Block(340, 70),
]
//draw my blocks
function addBlocks() {
for (let i = 0; i < blocks.length; i++) {
const block = document.createElement('div')
block.classList.add('block')
block.style.left = blocks[i].bottomLeft[0] + 'px'
block.style.bottom = blocks[i].bottomLeft[1] + 'px'
grid.appendChild(block)
console.log(blocks[i].bottomLeft)
}
}
addBlocks()
//add user
const user = document.createElement('div')
user.classList.add('user')
grid.appendChild(user)
drawUser()
//move user
function moveUser(e) {
switch (e.key) {
case 'ArrowLeft':
if (currentPosition[0] > 0) {
currentPosition[0] -= 10
console.log(currentPosition[0] > 0)
drawUser()
}
break
case 'ArrowRight':
if (currentPosition[0] < (boardWidth - blockWidth)) {
currentPosition[0] += 10
console.log(currentPosition[0])
drawUser()
}
break
case 'ArrowDown':
if (currentPosition1[0] < (boardHeight - blockHeight)) {
currentPosition1[0] += 10
console.log(currentPosition1[0]>0)
drawUser()
}
break
case 'ArrowUp':
if (currentPosition1[0] > 0) {
currentPosition1[0] -= 10
console.log(currentPosition1[0])
drawUser()
}
break
}
}
document.addEventListener('keydown', moveUser)
//draw User
function drawUser() {
user.style.top = currentPosition1 [0] + 'px'
user.style.left = currentPosition[0] + 'px'
user.style.bottom = currentPosition[0] + 'px'
user.style.right = currentPosition[0] + 'px'
}
function myCords(){
const user2 = [inputval0,inputval1]
let currentPosition3 = user2;
var inputval0 = document.getElementById('cords1').value;
var inputval1 = document.getElementById('cords2').value;
if(inputval0 < boardHeight && inputval1 < boardWidth && inputval0 != 0 && inputval1 != 0){
alert("good cords " + "X: "+ inputval0 + " " +"Y: " +inputval1)
}
else{
alert("wrong cordinates")
}
}document.addEventListener('onclick',myCords)
function drawnewUser(){
user.style.left = currentPosition + 'px';
user.style.top = currentPosition + 'px'
user.style.bottom = currentPosition + 'px'
user.style.right = currentPosition + 'px'
}
I am trying dynamically add HTML elements with click handlers. When the click handler is activated it targets wrong element(it always target the outer circle). Where could be the problem?
(function() {
//selector, jQuery style
var $ = function(selector) {
return document.querySelector(selector);
}
//getting quantity of circles
var quantity = $('.circles').getAttribute('quantity');
//setting outer width/height for circles
$('.circles').style.width = (quantity * 50) + 4 + 'px';
$('.circles').style.height = (quantity * 50) + 4 + 'px';
//creating element for children
var childCircle = document.createElement('div');
childCircle.className = 'subCircle';
//click function for children
function onClick() {
this.attributes.style.value += 'border-color: red;'
alert(this.clientHeight);
}
//append sub circles
for (var i = 0; i < quantity; i++) {
$('.circles').appendChild(childCircle.cloneNode());
}
//iterate over .circles .subCircle and add onClick function for each subCircle and css aswell
var subCircle = $('.circles').getElementsByClassName('subCircle');
for (var i = 0; i < subCircle.length; i++) {
subCircle[i].onclick = onClick;
subCircle[i].style.width = ((i + 1) * 50) + 'px';
subCircle[i].style.height = ((i + 1) * 50) + 'px';
}
})();
.circles {
position: absolute;
}
.subCircle {
position: absolute;
border-radius: 50%;
transform: translateX(-50%) translateY(-50%);
border: 2px solid black;
top: 50%;
left: 50%;
}
<body>
<div class="circles" quantity=10></div>
</body>
Also on jsFiddle: https://jsfiddle.net/martin_borman/1srkL5bf/
The problem isn't this, which is actually getting set by the event callback mechanism just fine. It's that your largest circle is on top.
Changing the loop that sets the size lets you put the smaller circles on top:
for (var i = 0; i < subCircle.length; i++) {
subCircle[i].onclick = onClick;
subCircle[i].style.width = ((subCircle.length - i) * 50) + 'px';
subCircle[i].style.height = ((subCircle.length - i) * 50) + 'px';
}
The key bit there is (subCircle.length - i) * 50 rather than (i + 1) * 50.
I'd also use
this.style.borderColor = 'red';
rather than
this.attributes.style.value += 'border-color: red;'
Example:
(function() {
//selector, jQuery style
var $ = function(selector) {
return document.querySelector(selector);
}
//getting quantity of circles
var quantity = $('.circles').getAttribute('quantity');
//setting outer width/height for circles
$('.circles').style.width = (quantity * 50) + 4 + 'px';
$('.circles').style.height = (quantity * 50) + 4 + 'px';
//creating element for children
var childCircle = document.createElement('div');
childCircle.className = 'subCircle';
//click function for children
function onClick() {
this.style.borderColor = 'red';
alert(this.clientHeight);
}
//append sub circles
for (var i = 0; i < quantity; i++) {
$('.circles').appendChild(childCircle.cloneNode());
}
//iterate over .circles .subCircle and add onClick function for each subCircle and css aswell
var subCircle = $('.circles').getElementsByClassName('subCircle');
for (var i = 0; i < subCircle.length; i++) {
subCircle[i].onclick = onClick;
subCircle[i].style.width = ((subCircle.length - i) * 50) + 'px';
subCircle[i].style.height = ((subCircle.length - i) * 50) + 'px';
}
})();
.circles {
position: absolute;
}
.subCircle {
position: absolute;
border-radius: 50%;
transform: translateX(-50%) translateY(-50%);
border: 2px solid black;
top: 50%;
left: 50%;
}
<body>
<div class="circles" quantity=10></div>
</body>
Just add the z-index property for each circle
subCircle[i].style['z-index'] = subCircle.length-i;
Actually the larger circle is overlapping all the inner circle.
I am just starting to learn about Javascript for animation. I have created this super simple example, which when clicked moves 3 blocks from a central position, to top, top-left and top-right position (I am building up to a sort of Context Action button type thing). But I would now like to be able to click again and if the animation is "out", then it will execute in reverse. I tried adding an if else, using the elem1.style.bottom == 350 parameter to define whether pos would increment or decrement, but it didn't work. Similarly, I was unable to get a clicked boolean to persist between clicks.
JSFiddle
html:
<body>
<p>
<button onclick="myMove()">Click Me</button>
</p>
<div id ="container">
<div id ="animate1"></div>
<div id ="animate2"></div>
<div id ="animate3"></div>
</div>
</body>
css:
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate1 {
width: 50px;
height: 50px;
left: 175px;
bottom: 175px;
position: absolute;
background-color: red;
z-index:3;
}
#animate2 {
width: 50px;
height: 50px;
left: 175px;
bottom: 175px;
position: absolute;
background-color: blue;
}
#animate3 {
width: 50px;
height: 50px;
left: 175px;
bottom: 175px;
position: absolute;
background-color: green;
}
Javascript:
function myMove() {
var elem1 = document.getElementById("animate1");
var elem2 = document.getElementById("animate2");
var elem3 = document.getElementById("animate3");
var start = 350;
var pos = 175;
var id = setInterval(frame, 5);
var clicked = false;
function frame() {
if (pos == 350) {
clearInterval(id);
clicked = !clicked;
} else {
if (clicked == false){ pos++; } else { pos--;}
elem1.style.bottom = pos + 'px';
elem1.style.left = start - pos + 'px';
elem2.style.bottom = pos + 'px';
elem2.style.left = pos + 'px';
elem3.style.bottom = pos + 'px';
}
}
}
How would I achieve this?
I think this is what you want: http://jsfiddle.net/3pvwaa19/20/
It creates a variable to keep track of whether the animation has happened and it moves your pos variable to the same location - - outside of the main function, so that the values won't get lost after each click:
var moved = false;
var pos = 175;
Yes, you can do it with if(elem1.style.bottom =="350px") {...}else{...:
function myMove() {
var elem1 = document.getElementById("animate1");
var elem2 = document.getElementById("animate2");
var elem3 = document.getElementById("animate3");
if (elem1.style.bottom == "350px"){
var start = 175;
var pos = 350;
var id = setInterval(frame, 5);
function frame() {
if (pos == 175) {
clearInterval(id);
} else {
pos--;
elem1.style.bottom = pos + 'px';
elem1.style.left = 2*start - pos + 'px';
elem2.style.bottom = pos + 'px';
elem2.style.left = pos + 'px';
elem3.style.bottom = pos + 'px';
}
}
} else {
var start = 350;
var pos = 175;
var id = setInterval(frame, 5);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
pos++;
elem1.style.bottom = pos + 'px';
elem1.style.left = start - pos + 'px';
elem2.style.bottom = pos + 'px';
elem2.style.left = pos + 'px';
elem3.style.bottom = pos + 'px';
}
}
}
}
I have part of a game where the cursor is supposed to "slow down" when it passes over certain divs. I'm using a function that can detect a collision with the div. This works fine when the cursor meets the first div, but it doesn't work at all on the second div.
Check out this jsFiddle for a better idea of what I'm talking about. Pass the cursor over the first white block (class='thing') on the left and it slows down. Pass the cursor over the other block (also class='thing'), and nothing happens. I need this collision function to work on all divs where class='thing'.
HTML
<div id='cursor'>
</div>
<div class='thing' style='width:70px; height:70px; background: #fff; position: absolute; bottom: 350px; right: 800px; z-index: -1;'>
</div>
<div class='thing' style='width:70px; height:70px; background: #fff; position: absolute; bottom: 200px; right: 400px; z-index: -1;'>
</div>
JS
(function collide(){
var newInt = setInterval(function() {
function collision($cursor, $thing) {
var x1 = $cursor.offset().left;
var y1 = $cursor.offset().top;
var h1 = $cursor.outerHeight(true);
var w1 = $cursor.outerWidth(true);
var b1 = y1 + h1;
var r1 = x1 + w1;
var x2 = $thing.offset().left;
var y2 = $thing.offset().top;
var h2 = $thing.outerHeight(true);
var w2 = $thing.outerWidth(true);
var b2 = y2 + h2;
var r2 = x2 + w2;
// change 12 to alter damping higher is slower
var varies = 12;
if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2){
} else {
varies = 200;
console.log(varies);
}
$xp += (($mouseX - $xp)/varies);
$yp += (($mouseY - $yp)/varies);
$("#cursor").css({left:$xp +'px', top:$yp +'px'});
}
$(collision($('#cursor'), $('.thing')));
//$('.result').text(collision($('#cursor'), $('.thing')));
}, 20);
})();
$thing is a collection of elements, like you want, but the problem here is that you ask specific attributes from $thing like offset().left;, which can not return more than one number, therefor it just takes the first. What you should do instead is use an .each() function to loop over all the elements in $thing.
$thing.each( function( index, element ){
//your code for each thing here
});
When you are selecting element by class name(in your case using .thing) in jQuery you will get an array of elements and collision() function will take first element in an array. so to overcome this you need to uniquely select both the elements this can be done using id as a selector,You can change your code like below to work it as expected
<div id='track'>
<div class = 'container'>
<div id='cursor' class='cursor'>
</div>
<div class='thing' id="a1" style='width:70px; height:70px; background: #fff; position: absolute; bottom: 175px; right: 400px; z-index: -1;'>
</div>
<div class='thing' id="a2" style='width:70px; height:70px; background: #fff; position: absolute; bottom: 100px; right: 200px; z-index: -1;'>
</div>
</div>
</div>
(function cursorMapping(){
var $mouseX = 0, $mouseY = 0;
var $xp = 0, $yp =0;
$(document).mousemove(function(e){
$mouseX = e.pageX;
$mouseY = e.pageY;
});
function showCoords(event) {
var x = event.clientX;
var y = event.clientY;
var coor = "X: " + x + ", Y: " + y;
}
var timestamp = null;
var lastMouseX = null;
var lastMouseY = null;
var mrefreshinterval = 500; // update display every 500ms
var lastmousex=-1;
var lastmousey=-1;
var lastmousetime;
var mousetravel = 0;
var lastmousetravel = 0;
var speed;
var marker1 = 1;
var marker2 = 1;
var timer = setInterval(function(){
marker1;
marker2;
}, 20);
$(function() {
var $speedometer = $('#speed'),
_speed = 0;
$('#track').cursometer({
onUpdateSpeed: function thisSpeed(speed) {
_speed = speed;
$speedometer.text(Math.ceil(speed * 100)/100);
},
updateSpeedRate: 20
});
});
var thisInterval = setInterval(function FXInterval(){
speed = $('#speed').text();
$('#cursor').css({'background-color': '#CE7A7A'});
}, 20);
$('html').mousemove(function(e) {
var mousex = e.pageX;
var mousey = e.pageY;
if (lastmousex > -1)
mousetravel += Math.max( Math.abs(mousex-lastmousex), Math.abs(mousey-lastmousey) );
lastmousex = mousex;
lastmousey = mousey;
var speed = lastmousex + lastmousey;
setTimeout(function(){
lastmousetravel = mousetravel;
}, 20);
});
(function collide(){
var newInt = setInterval(function() {
function collision($cursor, $thing) {
var x1 = $cursor.offset().left;
var y1 = $cursor.offset().top;
var h1 = $cursor.outerHeight(true);
var w1 = $cursor.outerWidth(true);
var b1 = y1 + h1;
var r1 = x1 + w1;
var x2 = $thing.offset().left;
var y2 = $thing.offset().top;
var h2 = $thing.outerHeight(true);
var w2 = $thing.outerWidth(true);
var b2 = y2 + h2;
var r2 = x2 + w2;
// change 12 to alter damping higher is slower
var varies = 12;
if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2){
} else {
varies = 200;
console.log(varies);
}
$xp += (($mouseX - $xp)/varies);
$yp += (($mouseY - $yp)/varies);
$("#cursor").css({left:$xp +'px', top:$yp +'px'});
}
$(collision($('#cursor'), $('#a1')));
$(collision($('#cursor'), $('#a2')));
}, 20);
})();
})();
I have a URL like http://weburl/mine/dot.html?gid=4&x=266y=647&x=191y=355&x=100y=893
From the above URL. i need to draw dots on the screen by taking the x and y values.
According to the above example there are 3 such values.
x=266 y=647
x=191 y=355
x=100 y=893
There are 2 parts to this question:
1.) How can I break the values from the URL and put it to an array in order to construct the image? (Since there are multiple values for x in the above URL)
2.) How can I draw the dot on the image? fiddle added.
Note: Following is the CSS of the dot.
position: 'absolute',
top: ev.pageY + 'px',
left: ev.pageX + 'px',
width: '10px',
height: '10px',
background: '#000000'
1)
// for str use window.location.search.replace("?", "");
var str = 'gid=4&x=266y=647&x=191y=355&x=100y=893';
var data = str.match(/(x|y)=(\d+)/g), pointsX = [], pointsY = [];
for(var i = 0; i < data.length; i++)
{
var tmp = data[i].split('=');
if (tmp[0] == 'x')
pointsX.push(tmp[1]);
else
pointsY.push(tmp[1]);
}
2) place a div with background or border above the image or use html5 + canvas http://jsfiddle.net/dh0swt43/
var str = 'gid=4&x=20y=30&x=40y=50&x=100y=100';
var data = str.match(/(x|y)=(\d+)/g), pointsX = [], pointsY = [];
for(var i = 0; i < data.length; i++)
{
var tmp = data[i].split('=');
if (tmp[0] == 'x')
pointsX.push(tmp[1]);
else
pointsY.push(tmp[1]);
}
for(var i = 0; i < pointsX.length; i++)
{
var div = document.createElement('div');
div.className = 'dot';
div.style.left = pointsX[i] + 'px';
div.style.top = pointsY[i] + 'px';
document.getElementById('wrapper').appendChild(div);
}
.dot {
height: 2px;
width: 2px;
position: absolute;
border: 2px solid red;
z-index: 10;
}
<div style='position:relative' id='wrapper'>
<img src='http://bestclipartblog.com/clipart-pics/earth-clip-art-3.jpg'>
</div>