Getting the wrong element in click handler with overlapping "circle" divs - javascript

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.

Related

OnClick function to rotate a div element

I am new to Javascript. I am writing a code where I am trying to rotate a square with every click. I was able to do it by clicking the square div element itself. But I wanna rotate the element using the button only. I am stuck with this. Where am I going wrong?
var count=0;
function rot(e){
count++;
var deg = count * 30;
e.style.transform = "rotate("+deg+"deg)";}
function rotat(){
count++;
var deg = count * 30;
this.style.transform = "rotate("+deg+"deg)";
}
.rectangle{
position: relative;
margin: 60mm;
width:90mm;
height:90mm;
border:5px solid #24ddff;
}
<div class = "rectangle" onclick="rot(this)"></div>
<button onclick="rotat()">Rotate</button>
<p id="demo"></p>
select div element . and use it in rotate function
var count=0;
const div = document.querySelector('div')
function rotat(){
count++;
var deg = count * 30;
div.style.transform = "rotate("+deg+"deg)";
}
.rectangle{
position: relative;
margin: 60px;
width:90px;
height:90px;
border:5px solid #24ddff;
}
<button onclick="rotat()">Rotate</button>
<div class = "rectangle"></div>
You should add id attribute to rectangle element that help you to recognize it within Javascript by getElementById
var count = 0;
function rot(e) {
count++;
var deg = count * 30;
e.style.transform = "rotate(" + deg + "deg)";
}
function rotat() {
const rectangle = document.getElementById("rectangle") //find rectangle element by id
count++;
var deg = count * 30;
rectangle.style.transform = "rotate(" + deg + "deg)";
}
.rectangle {
position: relative;
margin: 60mm;
width: 90mm;
height: 90mm;
border: 5px solid #24ddff;
}
<div class="rectangle" id="rectangle" onclick="rot(this)"></div>
<button onclick="rotat()">Rotate</button>
Or you can use class="rectangle" and find it by querySelector, but this way is not 100% safe because you may have multiple elements having rectangle class
var count = 0;
function rot(e) {
count++;
var deg = count * 30;
e.style.transform = "rotate(" + deg + "deg)";
}
function rotat() {
const rectangle = document.querySelector(".rectangle") //find rectangle element by id
count++;
var deg = count * 30;
rectangle.style.transform = "rotate(" + deg + "deg)";
}
.rectangle {
position: relative;
margin: 60mm;
width: 90mm;
height: 90mm;
border: 5px solid #24ddff;
}
<div class="rectangle" id="rectangle" onclick="rot(this)"></div>
<button onclick="rotat()">Rotate</button>
For some reasons "transform" did not work properly.
Try to use ".webkitTransform" instead ".transform".
Tip 2: Also try to bind the element by ID, not with Event.
Here some example:
<script type="text/javascript">
var rotatingDiv = document.getElementById("rotatingDiv");
rotatingDiv.style.webkitTransform = "rotate(-1.6deg)";
function transform()
{
var x=document.getElementById("element1");
rotatingDiv.style.webkitTransform = "rotate("+x.value+"deg)";
}
</script>

more chaotic upward movement

I have a heart movement on my page starting from the bottom of the page. Each randomly generates the size and speed of movement.
How can I make them, instead of appearing at the bottom of the page, appear when you click on the specified place, and move not evenly, but more chaotically and disappear before reaching the end?
var love = setInterval(function() {
var r_num = Math.floor(Math.random() * 40) + 1;
var r_size = Math.floor(Math.random() * 30) + 10;
var r_left = Math.floor(Math.random() * 100) + 1;
var r_time = Math.floor(Math.random() * 5) + 5;
$('.bg_heart').append("<div class='heart' style='width:" + r_size + "px;height:" + r_size + "px;left:" + r_left + "%;background:#ff94a7;-webkit-animation:love " + r_time + "s ease;-moz-animation:love " + r_time + "s ease;-ms-animation:love " + r_time + "s ease;animation:love " + r_time + "s ease'></div>");
$('.bg_heart').append("<div class='heart' style='width:" + (r_size - 10) + "px;height:" + (r_size - 10) + "px;left:" + (r_left + r_num) + "%;background:#ff94a7;-webkit-animation:love " + (r_time + 5) + "s ease;-moz-animation:love " + (r_time + 5) + "s ease;-ms-animation:love " + (r_time + 5) + "s ease;animation:love " + (r_time + 5) + "s ease'></div>");
$('.heart').each(function() {
var top = $(this).css("top").replace(/[^-\d\.]/g, '');
var width = $(this).css("width").replace(/[^-\d\.]/g, '');
if (top <= -100 || width >= 150) {
$(this).detach();
}
});
}, 500);
html,body{
height:100%
}
.bg_heart {
position: relative;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden
}
.heart {
position: absolute;
top: -50%;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-m-transform: rotate(-45deg);
transform: rotate(-45deg)
}
.heart:before {
position: absolute;
top: -50%;
left: 0;
display: block;
content: "";
width: 100%;
height: 100%;
background: inherit;
border-radius: 100%;
}
.heart:after {
position: absolute;
top: 0;
right: -50%;
display: block;
content: "";
width: 100%;
height: 100%;
background: inherit;
border-radius: 100%;
}
#-webkit-keyframes love {
0%{top:110%}
}
#-moz-keyframes love {
0%{top:110%}
}
#-ms-keyframes love {
0%{top:110%}
}
#keyframes love {
0%{top:110%}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header-plugin"></div>
<div class="bg_heart"></div>
To fly more chaotically use setInterval. You can also change the speed to whatever you need.
var brd = document.createElement("DIV");
document.body.insertBefore(brd, document.getElementById("board"));
const duration = 3000;
const speed = 0.5;
const cursorXOffset = 0;
const cursorYOffset = -5;
var hearts = [];
function generateHeart(x, y, xBound, xStart, scale)
{
var heart = document.createElement("DIV");
heart.setAttribute('class', 'heart');
brd.appendChild(heart);
heart.time = duration;
heart.x = x;
heart.y = y;
heart.bound = xBound;
heart.direction = xStart;
heart.style.left = heart.x + "px";
heart.style.top = heart.y + "px";
heart.scale = scale;
heart.style.transform = "scale(" + scale + "," + scale + ")";
if(hearts == null)
hearts = [];
hearts.push(heart);
return heart;
}
var down = false;
var event = null;
document.onmousedown = function(e) {
down = true;
event = e;
}
document.onmouseup = function(e) {
down = false;
}
document.onmousemove = function(e) {
event = e;
}
document.ontouchstart = function(e) {
down = true;
event = e.touches[0];
}
document.ontouchend = function(e) {
down = false;
}
document.ontouchmove = function(e) {
event = e.touches[0];
}
var before = Date.now();
var id = setInterval(frame, 5);
var gr = setInterval(check, 100);
function frame()
{
var current = Date.now();
var deltaTime = current - before;
before = current;
for(i in hearts)
{
var heart = hearts[i];
heart.time -= deltaTime;
if(heart.time > 0)
{
heart.y -= speed;
heart.style.top = heart.y + "px";
heart.style.left = heart.x + heart.direction * heart.bound * Math.sin(heart.y * heart.scale / 30) / heart.y * 100 + "px";
}
else
{
heart.parentNode.removeChild(heart);
hearts.splice(i, 1);
}
}
}
function check()
{
if(down)
{
var start = 1 - Math.round(Math.random()) * 2;
var scale = Math.random() * Math.random() * 0.8 + 0.2;
var bound = 30 + Math.random() * 20;
generateHeart(event.pageX - brd.offsetLeft + cursorXOffset, event.pageY - brd.offsetTop + cursorYOffset, bound, start, scale);
}
}
html,body{
height:100%
}
#keyframes heartfade {
0% {
opacity : 1;
}
50% {
opacity : 0;
}
}
.heart {
z-index : 999;
animation : heartfade 6s linear;
position : absolute;
}
.heart:before,
.heart:after {
content : "";
background-color : #ff94a7;
position : absolute;
height : 30px;
width : 45px;
border-radius : 15px 0px 0px 15px;
}
.heart:before {
transform : rotate(45deg);
}
.heart:after {
left : 10.5px;
transform : rotate(135deg);
}

How to drag images in JS

I have a large background image and some much smaller images for the user to drag around on the background. I need this to be efficient in terms of performance, so i'm trying to avoid libraries. I'm fine with drag 'n' drop if it work's well, but im trying to get drag.
Im pretty much trying to do this. But after 8 years there must be a cleaner way to do this right?
I currently have a drag 'n' drop system that almost works, but when i drop the smaller images, they are just a little off and it's very annoying. Is there a way to fix my code, or do i need to take a whole different approach?
This is my code so far:
var draggedPoint;
function dragStart(event) {
draggedPoint = event.target; // my global var
}
function drop(event) {
event.preventDefault();
let xDiff = draggedPoint.x - event.pageX;
let yDiff = draggedPoint.y - event.pageY;
let left = draggedPoint.style.marginLeft; // get margins
let top = draggedPoint.style.marginTop;
let leftNum = Number(left.substring(0, left.length - 2)); // cut off px from the end
let topNum = Number(top.substring(0, top.length - 2));
let newLeft = leftNum - xDiff + "px" // count new margins and put px back to the end
let newTop = topNum - yDiff + "px"
draggedPoint.style.marginLeft = newLeft;
draggedPoint.style.marginTop = newTop;
}
function allowDrop(event) {
event.preventDefault();
}
let imgs = [
"https://upload.wikimedia.org/wikipedia/commons/6/67/Orange_juice_1_edit1.jpg",
"https://upload.wikimedia.org/wikipedia/commons/f/ff/Solid_blue.svg",
"https://upload.wikimedia.org/wikipedia/commons/b/b4/Litoria_infrafrenata_-_Julatten.jpg"
]
/* my smaller images: */
for (let i = 0; i < 6; i++) {
let sensor = document.createElement("img");
sensor.src = imgs[i % imgs.length];
sensor.alt = i;
sensor.draggable = true;
sensor.classList.add("sensor");
sensor.style.marginLeft = `${Math.floor(Math.random() * 900)}px`
sensor.style.marginTop = `${Math.floor(Math.random() * 500)}px`
sensor.onclick = function() {
sensorClick(logs[i].id)
};
sensor.addEventListener("dragstart", dragStart, null);
let parent = document.getElementsByClassName("map")[0];
parent.appendChild(sensor);
}
<!-- my html: -->
<style>
.map {
width: 900px;
height: 500px;
align-content: center;
margin: 150px auto 150px auto;
}
.map .base {
position: absolute;
width: inherit;
height: inherit;
}
.map .sensor {
position: absolute;
width: 50px;
height: 50px;
}
</style>
<div class="map" onDrop="drop(event)" ondragover="allowDrop(event)">
<img src='https://upload.wikimedia.org/wikipedia/commons/f/f7/Plan-Oum-el-Awamid.jpg' alt="pohja" class="base" draggable="false">
<div>
With the answers from here and some time i was able to get a smooth drag and click with pure js.
Here is a JSFiddle to see it in action.
let maxLeft;
let maxTop;
const minLeft = 0;
const minTop = 0;
let timeDelta;
let imgs = [
"https://upload.wikimedia.org/wikipedia/commons/6/67/Orange_juice_1_edit1.jpg",
"https://upload.wikimedia.org/wikipedia/commons/f/ff/Solid_blue.svg",
"https://upload.wikimedia.org/wikipedia/commons/b/b4/Litoria_infrafrenata_-_Julatten.jpg"
]
var originalX;
var originalY;
window.onload = function() {
document.onmousedown = startDrag;
document.onmouseup = stopDrag;
}
function sensorClick () {
if (Date.now() - timeDelta < 150) { // check that we didn't drag
createPopup(this);
}
}
// create a popup when we click
function createPopup(parent) {
let p = document.getElementById("popup");
if (p) {
p.parentNode.removeChild(p);
}
let popup = document.createElement("div");
popup.id = "popup";
popup.className = "popup";
popup.style.top = parent.y - 110 + "px";
popup.style.left = parent.x - 75 + "px";
let text = document.createElement("span");
text.textContent = parent.id;
popup.appendChild(text);
var map = document.getElementsByClassName("map")[0];
map.appendChild(popup);
}
// when our base is loaded
function baseOnLoad() {
var map = document.getElementsByClassName("map")[0];
let base = document.getElementsByClassName("base")[0];
maxLeft = base.width - 50;
maxTop = base.height - 50;
/* my smaller images: */
for (let i = 0; i < 6; i++) {
let sensor = document.createElement("img");
sensor.src = imgs[i % imgs.length];
sensor.alt = i;
sensor.id = i;
sensor.draggable = true;
sensor.classList.add("sensor");
sensor.classList.add("dragme");
sensor.style.left = `${Math.floor(Math.random() * 900)}px`
sensor.style.top = `${Math.floor(Math.random() * 500)}px`
sensor.onclick = sensorClick;
let parent = document.getElementsByClassName("map")[0];
parent.appendChild(sensor);
}
}
function startDrag(e) {
timeDelta = Date.now(); // get current millis
// determine event object
if (!e) var e = window.event;
// prevent default event
if(e.preventDefault) e.preventDefault();
// IE uses srcElement, others use target
targ = e.target ? e.target : e.srcElement;
originalX = targ.style.left;
originalY = targ.style.top;
// check that this is a draggable element
if (!targ.classList.contains('dragme')) return;
// calculate event X, Y coordinates
offsetX = e.clientX;
offsetY = e.clientY;
// calculate integer values for top and left properties
coordX = parseInt(targ.style.left);
coordY = parseInt(targ.style.top);
drag = true;
document.onmousemove = dragDiv; // move div element
return false; // prevent default event
}
function dragDiv(e) {
if (!drag) return;
if (!e) var e = window.event;
// move div element and check for borders
let newLeft = coordX + e.clientX - offsetX;
if (newLeft < maxLeft && newLeft > minLeft) targ.style.left = newLeft + 'px'
let newTop = coordY + e.clientY - offsetY;
if (newTop < maxTop && newTop > minTop) targ.style.top = newTop + 'px'
return false; // prevent default event
}
function stopDrag() {
if (typeof drag == "undefined") return;
if (drag) {
if (Date.now() - timeDelta > 150) { // we dragged
let p = document.getElementById("popup");
if (p) {
p.parentNode.removeChild(p);
}
} else {
targ.style.left = originalX;
targ.style.top = originalY;
}
}
drag = false;
}
.map {
width: 900px;
height: 500px;
margin: 50px
position: relative;
}
.map .base {
position: absolute;
width: inherit;
height: inherit;
}
.map .sensor {
display: inline-block;
position: absolute;
width: 50px;
height: 50px;
}
.dragme {
cursor: move;
left: 0px;
top: 0px;
}
.popup {
position: absolute;
display: inline-block;
width: 200px;
height: 100px;
background-color: #9FC990;
border-radius: 10%;
}
.popup::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -10px;
border-width: 10px;
border-style: solid;
border-color: #9FC990 transparent transparent transparent;
}
.popup span {
width: 90%;
margin: 10px;
display: inline-block;
text-align: center;
}
<div class="map" width="950px" height="500px">
<img src='https://upload.wikimedia.org/wikipedia/commons/f/f7/Plan-Oum-el-Awamid.jpg' alt="pohja" class="base" draggable="false" onload="baseOnLoad()">
<div>

Javascript - moving multiple images inside a div, with border control

Little premise: I didn't want to make this question, because I thought it was a too personal and generic problem; but after 2 days without any improvement, I couldn't resist anymore.
So basically, my project is an aquarium with multiple fishes inside.
It all works fine, the only problem is that, in short words: the first fish image remains inside the div(it even stops too soon), the second one arrives a bit farther, the third even farther, and so on.
The opposite thing happens with the top margin: going forward, the last fish is always farther from the margin, and I can't find out the reason.
My scope is to keep all the fishes inside the "acquario" div (which has the black borders).
P.S. With sx and dx margins, they have no problem.
var BORDER_LEFT_RIGHT = 7;
var BORDER_TOP_DOWN = 28;
var fishes = new Array();
var nextId = 0;
var heightMax;
var widthMax;
var n; //initial direction, see createFish()
init();
/* light blue fish (dory, to clarify)*/
createFish("https://s18.postimg.org/n8sqmtjkp/pesce1_sx.png", "https://s30.postimg.org/6w8xyqwep/pesce1_dx.png");
/* white and yellow fish */
createFish("https://s28.postimg.org/6aalv0pst/pesce2_sx.png", "https://s29.postimg.org/dxbi0vypz/pesce2_dx.png");
/* dark blue fish */
createFish("https://s24.postimg.org/sbgt8zn6t/pesce3_sx.png", "https://s29.postimg.org/v65opob7r/pesce3_dx.png");
/* white-blue-yellow fish */
createFish("https://s30.postimg.org/62lb9bfwx/pesce4_sx.png", "https://s28.postimg.org/kt5m4ea65/pesce4_dx.png");
/* orange fish */
createFish("https://s18.postimg.org/q5sq0saex/pesce5_sx.png", "https://s18.postimg.org/uqnwe2vex/pesce5_dx.png");
showFishes();
function init() {
heightMax = document.getElementById("acquario").clientHeight - BORDER_TOP_DOWN;
widthMax = document.getElementById("acquario").clientWidth - BORDER_LEFT_RIGHT;
n = 1;
}
function createFish(src1, src2) {
imgFishSX = new Image();
imgFishDX = new Image();
imgFishSX.src = src1;
imgFishDX.src = src2;
n *= -1;
var fish = {
id: nextId,
/* default x position: random number between 1 and widthMax */
x: Math.floor((Math.random() * widthMax - imgFishSX.width) + 1),
/* default y position: random number between 1 and heightMax */
y: Math.floor((Math.random() * heightMax - imgFishSX.height) + 1),
xIncrease: n * getIncrease(),
yIncrease: n * getIncrease(),
imageSX: imgFishSX,
imageDX: imgFishDX
};
addFishToArray((fish));
nextId++;
}
function addFishToArray(fish) {
fishes.push(fish);
}
function showFishes() {
var node = document.getElementById("acquario");
var stringToInner = "";
var src;
/* first, we make the string with all the img filled in */
for (var i = 0; i < fishes.length; i++) {
/* we have to check if the default increase direction was <-- or --> */
fishes[i].xIncrease > 0 ? src = fishes[i].imageSX.src : src = fishes[i].imageDX.src;
/* z-index --> overlap priority */
stringToInner += "<img src =\"" + src +
"\" id=\"" + fishes[i].id + "\" style= \"margin-left: " +
fishes[i].x + "px;margin-top: " + fishes[i].y + "px;z-index: " +
fishes[i].id + ";position: absolute;\">";
stringToInner += "<br>";
}
/* then, we insert it */
node.innerHTML = stringToInner;
/* let's raise hell! */
moveFishes();
}
function getIncrease() {
return Math.floor((Math.random() * 5) + 1);
}
function moveFishes() {
/* scroll the array: we need to check each fish one by one */
for (var i = 0; i < fishes.length; i++) {
moveFish(fishes[i]);
}
/* infinite loop */
setTimeout(function() {
moveFishes()
}, 50);
}
function moveFish(fish) {
/* with this node, I'll apply changes to my html document */
node = document.getElementById(fish.id);
/* we are inside, just move */
if (fish.x > 0 && fish.x < widthMax - node.width && fish.y > 0 && fish.y < heightMax - node.height) {
node.style.marginLeft = fish.x + "px";
node.style.marginTop = fish.y + "px";
fish.x += fish.xIncrease;
fish.y += fish.yIncrease;
/* too --> , we need to get <-- */
} else if (fish.x >= widthMax - node.width) {
node.src = fish.imageDX.src;
fish.xIncrease = -getIncrease();
fish.x += fish.xIncrease;
/* too <-- , we need to get --> */
} else if (fish.x <= 0) {
node.src = fish.imageSX.src;
fish.xIncrease = 5;
fish.x += getIncrease();
/* too up, we need to get down */
} else if (fish.y >= heightMax - node.height) {
fish.yIncrease = -getIncrease();
fish.y += fish.yIncrease;
/* too down, we need to get up */
} else if (fish.y <= 0) {
fish.yIncrease = getIncrease();
fish.y += fish.yIncrease;
}
}
* {
box-sizing: border-box;
}
.row::after {
content: "";
clear: both;
display: block;
}
html {
background: url("https://s24.postimg.org/rakxoa7sl/sfondo.jpg") no-repeat center center fixed;
-webkibact-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
html,
body {
height: 100%;
margin: 0;
}
#main {
margin: 0;
height: 100%;
}
#acquario {
border-bottom: 28px solid black;
border-top: 28px solid black;
border-right: 7px solid black;
border-left: 7px solid black;
height: 100%;
}
<body>
<div id="main">
<div id="acquario">
</div>
</div>
</body>
do you want the fishes to bound off the walls or to hide under the wall? and why do you use margin-left and margin-top instead of top and left properties? it makes the aquarium scrolling. Is it ok now?
var BORDER_LEFT_RIGHT = 7;
var BORDER_TOP_DOWN = 28;
var fishes = new Array();
var nextId = 0;
var heightMax;
var widthMax;
var n; //initial direction, see createFish()
init();
/* light blue fish (dory, to clarify)*/
createFish("https://s18.postimg.org/n8sqmtjkp/pesce1_sx.png", "https://s30.postimg.org/6w8xyqwep/pesce1_dx.png");
/* white and yellow fish */
createFish("https://s28.postimg.org/6aalv0pst/pesce2_sx.png", "https://s29.postimg.org/dxbi0vypz/pesce2_dx.png");
/* dark blue fish */
createFish("https://s24.postimg.org/sbgt8zn6t/pesce3_sx.png", "https://s29.postimg.org/v65opob7r/pesce3_dx.png");
/* white-blue-yellow fish */
createFish("https://s30.postimg.org/62lb9bfwx/pesce4_sx.png", "https://s28.postimg.org/kt5m4ea65/pesce4_dx.png");
/* orange fish */
createFish("https://s18.postimg.org/q5sq0saex/pesce5_sx.png", "https://s18.postimg.org/uqnwe2vex/pesce5_dx.png");
showFishes();
function init() {
heightMax = document.getElementById("acquario").clientHeight + BORDER_TOP_DOWN;
widthMax = document.getElementById("acquario").clientWidth + BORDER_LEFT_RIGHT;
n = 1;
}
function createFish(src1, src2) {
imgFishSX = new Image();
imgFishDX = new Image();
imgFishSX.src = src1;
imgFishDX.src = src2;
n *= -1;
var fish = {
id: nextId,
/* default x position: random number between 1 and widthMax */
x: Math.floor((Math.random() * (widthMax - BORDER_LEFT_RIGHT - imgFishSX.width)) + BORDER_LEFT_RIGHT),
/* default y position: random number between 1 and heightMax */
y: Math.floor((Math.random() * (heightMax - BORDER_TOP_DOWN - imgFishSX.height)) + BORDER_TOP_DOWN),
xIncrease: n * getIncrease(),
yIncrease: n * getIncrease(),
imageSX: imgFishSX,
imageDX: imgFishDX
};
addFishToArray((fish));
nextId++;
}
function addFishToArray(fish) {
fishes.push(fish);
}
function showFishes() {
var node = document.getElementById("acquario");
var stringToInner = "";
var src;
/* first, we make the string with all the img filled in */
for (var i = 0; i < fishes.length; i++) {
/* we have to check if the default increase direction was <-- or --> */
fishes[i].xIncrease > 0 ? src = fishes[i].imageSX.src : src = fishes[i].imageDX.src;
/* z-index --> overlap priority */
stringToInner += "<img src =\"" + src +
"\" id=\"" + fishes[i].id + "\" style= \"left: " +
fishes[i].x + "px;top: " + fishes[i].y + "px;z-index: " +
fishes[i].id + ";position: absolute;\">";
stringToInner += "<br>";
}
/* then, we insert it */
node.innerHTML = stringToInner;
/* let's raise hell! */
moveFishes();
}
function getIncrease() {
return Math.floor((Math.random() * 5) + 1);
}
function moveFishes() {
/* scroll the array: we need to check each fish one by one */
for (var i = 0; i < fishes.length; i++) {
moveFish(fishes[i]);
}
/* infinite loop */
setTimeout(function() {
moveFishes()
}, 50);
}
function moveFish(fish) {
/* with this node, I'll apply changes to my html document */
node = document.getElementById(fish.id);
/* we are inside, just move */
if (fish.x > BORDER_LEFT_RIGHT && fish.x < widthMax - node.width && fish.y > BORDER_TOP_DOWN && fish.y < heightMax - node.height) {
node.style.left = fish.x + "px";
node.style.top = fish.y + "px";
fish.x += fish.xIncrease;
fish.y += fish.yIncrease;
/* too --> , we need to get <-- */
} else if (fish.x >= widthMax - node.width) {
node.src = fish.imageDX.src;
fish.xIncrease = -getIncrease();
fish.x += fish.xIncrease;
/* too <-- , we need to get --> */
} else if (fish.x <= BORDER_LEFT_RIGHT) {
node.src = fish.imageSX.src;
fish.xIncrease = 5;
fish.x += getIncrease();
/* too up, we need to get down */
} else if (fish.y >= heightMax - node.height) {
fish.yIncrease = -getIncrease();
fish.y += fish.yIncrease;
/* too down, we need to get up */
} else if (fish.y <= BORDER_TOP_DOWN) {
fish.yIncrease = getIncrease();
fish.y += fish.yIncrease;
}
}
* {
box-sizing: border-box;
}
.row::after {
content: "";
clear: both;
display: block;
}
html {
background: url("https://s24.postimg.org/rakxoa7sl/sfondo.jpg") no-repeat center center fixed;
-webkibact-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
html,
body {
height: 100%;
margin: 0;
}
#main {
margin: 0;
height: 100%;
}
#acquario {
border-bottom: 28px solid black;
border-top: 28px solid black;
border-right: 7px solid black;
border-left: 7px solid black;
height: 100%;
}
<body>
<div id="main">
<div id="acquario">
</div>
</div>
</body>
I know Pawel has fixed your issue, but I did state I would provide a canvas version so here it is
jsFiddle : https://jsfiddle.net/CanvasCode/zh0b7zrj/1/
HTML :
<canvas id="myCanvas"></canvas>
CSS :
html,
body {
width: 100%;
height: 100%;
margin: 0px;
overflow: hidden;
}
Javascript :
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext("2d");
var backgroundImage = new Image();
canvas.width = document.body.clientWidth; //document.width is obsolete
canvas.height = document.body.clientHeight; //document.height is obsolete
// Fish
function FishObject(xSet, ySet, xSpeed, ySpeed, spriteUrlRight, spriteUrlLeft) {
this.XPos = xSet;
this.YPos = ySet;
this.XDefaultSpeed = xSpeed;
this.YDefaultSpeed = ySpeed;
this.xSpeed = this.XDefaultSpeed;
this.ySpeed = this.YDefaultSpeed;
this.RightSprite = new Image();
this.RightSprite.src = spriteUrlRight;
this.LeftSprite = new Image();
this.LeftSprite.src = spriteUrlLeft;
}
FishObject.prototype.Draw = function(ctx) {
if (this.xSpeed > 0) {
ctx.drawImage(this.RightSprite, this.XPos, this.YPos);
} else {
ctx.drawImage(this.LeftSprite, this.XPos, this.YPos);
}
}
FishObject.prototype.Update = function(ctx) {
this.XPos += this.xSpeed;
this.YPos += this.ySpeed;
if (this.XPos <= 0) {
this.xSpeed = this.XDefaultSpeed;
} else if ((this.XPos + this.RightSprite.width) >= canvas.width) {
this.xSpeed = -this.XDefaultSpeed;
}
if (this.YPos <= 0) {
this.ySpeed = this.YDefaultSpeed;
} else if ((this.YPos + this.RightSprite.height) >= canvas.height) {
this.ySpeed = -this.YDefaultSpeed;
}
}
backgroundImage.src = 'https://s24.postimg.org/rakxoa7sl/sfondo.jpg';
var Fishs = [];
Fishs.push(new FishObject(0, 0, 1, 1, "https://s18.postimg.org/n8sqmtjkp/pesce1_sx.png",
"https://s30.postimg.org/6w8xyqwep/pesce1_dx.png"));
Fishs.push(new FishObject(0, 0, 2, 1.2, "https://s28.postimg.org/6aalv0pst/pesce2_sx.png",
"https://s29.postimg.org/dxbi0vypz/pesce2_dx.png"));
Fishs.push(new FishObject(0, 0, 1.7, 2.8, "https://s24.postimg.org/sbgt8zn6t/pesce3_sx.png",
"https://s29.postimg.org/v65opob7r/pesce3_dx.png"));
Fishs.push(new FishObject(0, 0, 0.2, 0.5, "https://s30.postimg.org/62lb9bfwx/pesce4_sx.png",
"https://s28.postimg.org/kt5m4ea65/pesce4_dx.png"));
Fishs.push(new FishObject(0, 0, 0.7, 0.1, "https://s18.postimg.org/q5sq0saex/pesce5_sx.png",
"https://s18.postimg.org/uqnwe2vex/pesce5_dx.png"));
setInterval(function() {
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(backgroundImage, 0, 0);
for (var i = 0; i < Fishs.length; i++) {
var fishObject = Fishs[i];
fishObject.Draw(ctx);
fishObject.Update(ctx);
}
}, (1000 / 60)); // 60 FPS (frames per second)

Getting the exact position of the div

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>

Categories