var circle = document.getElementById("circle");
function moveUp() {
var top = circle.offsetTop;
newTop = top - 10;
circle.style.top = newTop "px";
console.log("moveUP Called")
}
function moveDown() {
var top = circle.offsetTop;
newTop = top 10;
circle.style.top = newTop "px";
console.log("moveDown Called")
}
function moveLeft() {
var left = circle.offsetLeft;
newLeft = left - 10;
circle.style.left = newLeft "px";
console.log("moveLeft Called")
}
function moveRight() {
var left = circle.offsetLeft;
newLeft = left 10;
circle.style.left = newLeft "px";
console.log("moveRight Called")
}
window.addEventListener("keypress", (event) => {
if (event.key == 'w') {
moveUp();
} else if (event.key == 's') {
moveDown();
} else if (event.key == 'a') {
moveLeft();
} else if (event.key == 'd') {
moveRight();
}
})
body {
margin: 2px;
background-color: aquamarine;
}
#circle {
height: 100px;
width: 100px;
background-color: blue;
border-radius: 50%;
position: absolute;
}
In the above code where on key press circle moves, for example on 'w'
it moves up, for 's'
it moves down and so on.
But the problem is that the circle even moves out of the window, how do I fix it and what is the problem??
CodePudding user response:
var circle = document.getElementById("circle");
console.log(window.innerWidth, window.innerHeight)
function moveUp() {
var top = circle.offsetTop;
console.log(top)
newTop = top - 10;
if(newTop < 0) {
newTop = 0;
}
circle.style.top = newTop "px";
}
function moveDown() {
var top = circle.offsetTop;
var height = circle.offsetHeight top;
if((height 10) >= window.innerHeight) {
return;
}
newTop = top 10;
circle.style.top = newTop "px";
/* console.log("moveDown Called") */
}
function moveLeft() {
var left = circle.offsetLeft;
newLeft = left - 10;
if(newLeft<0) {
newLeft = 0;
}
circle.style.left = newLeft "px";
}
function moveRight() {
var left = circle.offsetLeft;
newLeft = left 10;
if(newLeft > window.innerWidth - 100 ) {
newLeft = window.innerWidth - 100 ;
}
circle.style.left = newLeft "px";
}
window.addEventListener("keypress", (event) => {
if (event.key == 'w') {
moveUp();
} else if (event.key == 's') {
moveDown();
} else if (event.key == 'a') {
moveLeft();
} else if (event.key == 'd') {
moveRight();
}
})
body{
margin:2px;
background-color: aquamarine;
}
#circle{
height: 100px;
width: 100px;
background-color: blue;
border-radius: 50%;
position: absolute;
overflow: hidden;
}
<div id="circle">
</div>
Explaination
for moveup()
if the position is a negative number that means the div is going out of the viewport. So with the if condition new position will be always set to 0
preventing the div to go negative position.
for moveDown()
first you get the offsetTop
which means how far is the box from top position along with the offsetHeight
which represents the height of the box. So add these two to get the total height. Now simply check if this height is going over the innerHeight the distance(10)
you are going with each move. If it is more than the innerHeight
simply return. otherwise move the box.
moveLeft()
is same as moveUp()
.
moveRight()
is also same as moveDown()
but here we're calculating the innerWidth
. Subtract it with the box width so it doesn't go outside the viewport. Now simple condition check and set the new right position.
hope it helped
CodePudding user response:
What is the problem?
There is no problem. CSS does exactly what you told it to do.
For example, you can click on 'w'
couple of times, which will set left
property for your absolutely positioned circle to, let's say, -160px
. This will instruct the browser to move your element to the left, away from the viewport, i.e. to position it -160px
of the left edge of the initial containing block or nearest positioned ancestor. More about left
property: https://developer.mozilla.org/en-US/docs/Web/CSS/left
I would not say that it is a problem, because it is exactly what left
is used for - move elements to whatever position you like. Sometimes you can hide elements by setting their position: absolute; left: -10000px;
How do I fix it?
If you don't want your circle to move away from the viewport, you need to check if your circle is 'touching' the viewport. I will use example with the left, but the same logic can be applied to top
, right
and bottom
.
So for the left, this will consist of two parts:
- Check what is the initial distance from your circle to the left edge of the viewport.
- Check if absolute value of your new left value is not greater than this distance.
For example, for the left method:
var elDistanceToLeft = window.pageXOffset circle.getBoundingClientRect().left;
function moveLeft() {
let left = circle.offsetLeft;
newLeft = Math.abs(left - 10) <= elDistanceToLeft ? left - 10 : -elDistanceToLeft;
circle.style.left = newLeft "px";
}
In this case your circle will move all way to the left (on pressing 'a') until it 'touches' the viewport (screen). Then it will stop.
Here is a code snippet
var elDistanceToLeft = window.pageXOffset circle.getBoundingClientRect().left
function moveLeft() {
let left = circle.offsetLeft;
newLeft = Math.abs(left - 10) <= elDistanceToLeft ? left - 10 : -elDistanceToLeft;
circle.style.left = newLeft "px";
}
window.addEventListener("keypress", (ev) => { if (ev.key == 'a') { moveLeft();} })
#circle {
height: 100px;
width: 100px;
background-color: blue;
border-radius: 50%;
position: absolute;
}
#parent {
position: relative;
padding: 200px;
}
<div id="parent">
<div id="circle"></div>
</div>