How to Detect the Mouse Pointer Come From When Hover Elements - javascript

I just want to ask how to detect the mouse pointer come from using jquery when the pointer hover an element like div.
When run the function I want to know mouse pointer come from top, left, bottom and right
Thank you!

Try this code:
var getDirection = function (ev, obj) {
var w = obj.offsetWidth,
h = obj.offsetHeight,
x = (ev.pageX - obj.offsetLeft - (w / 2) * (w > h ? (h / w) : 1)),
y = (ev.pageY - obj.offsetTop - (h / 2) * (h > w ? (w / h) : 1)),
d = Math.round( Math.atan2(y, x) / 1.57079633 + 5 ) % 4;
return d;
};
$('#yourDiv').mouseover(function (event) {
var direction = getDirection(event, this);
if (direction == 0) {
$(this).html('Top side');
} else if (direction == 1) {
$(this).html('Right side');
} else if (direction == 2) {
$(this).html('Bottom side');
} else if (direction == 3) {
$(this).html('Left side');
}
});
#yourDiv {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top: 50px;
left: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="yourDiv"></div>
getDirection copied from this page by CSS-Tricks which seems to do a similar thing to what you want in a number of different ways.

Related

How do I make an image move on keys up down left right?

I have watched at least 30 tutorials on how to make an image move up, down, left or right on the keys pressed, but not a single one was helpful to me.
I want to put in an image, and if you press the left or right key and it would move in that direction.
What is the shortest way to do this?
I know it's something with subtracting or adding the X axis, but how do I add the X and Y on a page so it can move?
is it something with keycode?
NOTE: Take care of -ve in left and top.
const image = document.querySelector(".image-continer");
document.addEventListener("keydown", (e) => {
const key = e.keyCode;
const cs = getComputedStyle(image);
const change = 10;
const regex = /[\d\.]*/;
const left = cs.left;
const top = cs.top;
const leftNumber = left.match(regex);
const topNumber = top.match(regex);
// LEFT key pressed
if (key === 37) {
image.style.left = `${parseFloat(leftNumber[0]) - change}px`;
}
// TOP key pressed
if (key === 38) {
image.style.top = `${parseFloat(topNumber[0]) - change}px`;
}
// RIGHT key pressed
if (key === 39) {
image.style.left = `${parseFloat(leftNumber[0]) + change}px`;
}
// DOWN key pressed
if (key === 40) {
image.style.top = `${parseFloat(topNumber[0]) + change}px`;
}
});
html,
body {
height: 100%;
margin: 0;
}
.image-continer {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="image-continer">🙂</div>
This method allows move image diagonally.
let img = document.getElementById("myimage"),
w = img.offsetWidth/2,
h = img.offsetHeight/2,
x = img.offsetLeft,
y = img.offsetTop,
step = 10, //number of pixels to move
keys = [];
document.addEventListener("keydown", function(e)
{
let l=null, u=null;
if (keys.indexOf(e.key) == -1)
keys[keys.length] = e.key;
for(let i = 0; i < keys.length; i++)
{
let key = keys[i];
if (key == "ArrowLeft")
{
l += -step;
}
if (key == "ArrowRight")
{
l += step;
}
if (key == "ArrowUp")
{
u += -step;
}
if (key == "ArrowDown")
{
u += step;
}
}
if (l === null && u === null)
return;
e.preventDefault();
e.stopPropagation();
if (l !== null)
x += l;
if (u !== null)
y += u;
if (x < w)
x = w;
if (y < h)
y = h;
if (x > img.parentNode.offsetWidth - w)
x = img.parentNode.offsetWidth - w;
if (y > img.parentNode.offsetHeight - h)
y = img.parentNode.offsetHeight - h;
img.style.left = x + "px";
img.style.top = y + "px";
}, false);
document.addEventListener("keyup", function(e)
{
keys.splice(keys.indexOf(e.key), 1);
}, false);
body,
html
{
height: 100%;
}
img
{
top: 50%;
left: 50%;
position: absolute;
transform: translate(-50%,-50%);
transition: left 0.3s ease, top 0.3s ease;
box-shadow: 0 0 10px 2px lightblue;
}
<img id="myimage" src="https://lh3.googleusercontent.com/s1j_z7YCGft2EBNfnpXel8v02F8QkQKvp-_UjkR8SFaE5ciwPX9IugLMYvo_cCBzzuThRD7dVwwLO3H7XnvbD0JNnyVDmw_mPd8T5NH7yzQSSirZcA=w100">
Example with JQuery:
$(document).on('keydown', function(event) { // if a key is pressed...
if (event.which === 39) { // then if the key the right arrow key...
$('.image').animate({ // then animate it with JQuery...
left: `+=${$('.image').width() * 3}`
}, 'slow'); // and do it slowly
} else if (event.which === 37) { // otherwise if the key is the left arrow key...
$('.image').animate({ // then animate it with JQuery...
left: `-=${$('.image').width() * 3}`
}, 'slow'); // and do it slowly
} else if (event.which === 38) { // otherwise if it is the up arrow key...
$('.image').animate({ // then animate it with JQuery...
top: `-=${$('.image').width() * 3}`
}, 'slow'); // and do it slowly
} else if (event.which === 40) { // otherwise if it is the down arrow key...
$('.image').animate({ // then animate it with JQuery
top: `+=${$('.image').width() * 3}`
}, 'slow'); // and do it slowly
}
event.preventDefault();
});
I got the solution:
var x = 0;
var y = 0;
var keys = {};
image.style.left = (x) + "px";
image.style.top = (y) + "px";
document.addEventListener("keyup", (e) => {
keys[e.keyCode] = false;
});
document.addEventListener("keydown", (e) => {
keys[e.keyCode] = true;
if(keys[37] {
x += 5;
image.style.left = (x) + "px";
}
if(keys[39] {
x -= 5;
image.style.left = (x) + "px";
}
});

Why JS animation is stuck?

I want the box to traverse the inside of the container from left to right, then down, then right to left and finally back up to the original position. The examples I found all include extra array pos = [180,180]. I don't understand why do I need it when my IF conditions seem to cover all positions.
window.onload = function() {
var t = setInterval(slide, 5);
pos1 = [0, 0];
var box = document.getElementById('sqr');
function slide() {
if (pos1[0] < 180 && pos1[1] < 180) {
pos1[0]++;
box.style.left = pos1[0] + "px";
} else if (pos1[0] >= 180 && pos1[1] < 180) {
pos1[1]++;
box.style.top = pos1[1] + "px";
} else if (pos1[0] >= 180 && pos1[1] >= 180) {
pos1[0]--;
box.style.left = pos1[0] + "px";
} else if (pos1[0] <= 0 && pos1[1] >= 180) {
pos1[1]--;
box.style.top = pos1[1] + "px";
}
}
}
#contain {
position: relative;
width: 200px;
height: 200px;
background-color: pink;
}
#sqr {
position: absolute;
width: 20px;
height: 20px;
background-color: blue;
}
<div id="contain">
<div id="sqr"></div>
</div>
Once the box gets to the maximum X and Y positions, the program is still checking to make sure the box hasn't reached the maximum yet, which causes the all IF conditions to fail. You could do it by checking for Y=0 for the first "leg", X=MAX for the next, Y=MAX for the next, and then X=0 for the last, but instead of that, you can set a "state" which has 4 values to determine which "leg" of the animation is being run, and then just run it for 180 iterations each.
window.onload = function() {
var t = setInterval(slide, 5);
pos1 = [0, 0];
var box = document.getElementById('sqr');
state = 0;
iterations = 0;
function slide() {
if (iterations >= 180) {state = (state + 1) % 4; iterations = 0;}
if (state === 0) pos1[0]++;
else if (state == 1) pos1[1]++;
else if (state == 2) pos1[0]--;
else if (state == 3) pos1[1]--;
iterations++;
box.style.left = pos1[0] + "px";
box.style.top = pos1[1] + "px";
}
}
#contain {
position: relative;
width: 200px;
height: 200px;
background-color: pink;
}
#sqr {
position: absolute;
width: 20px;
height: 20px;
background-color: blue;
}
<div id="contain">
<div id="sqr"></div>
</div>
window.onload = function() {
var t = setInterval(slide, 5);
var box = document.getElementById('sqr');
var left = 0,
top = 0;
function slide() {
var pos1 = [parseInt(box.style.left || 0), parseInt(box.style.top || 0)]
console.log(pos1);
if (pos1[0] == 0 && pos1[1] == 0) { //Top left, go right
left = 1;
top = 0;
} else if (pos1[0] == 180 && pos1[1] == 0) { //Top right, go down
left = 0;
top = 1;
} else if (pos1[0] == 180 && pos1[1] == 180) { //Bottom right, go left
left = -1;
top = 0;
} else if (pos1[0] == 0 && pos1[1] == 180) { //Bottom left, go up
left = 0;
top = -1;
}
box.style.left = (parseInt(box.style.left || 0) + left) + "px";
box.style.top = (parseInt(box.style.top || 0) + top) + "px";
}
}
#contain {
position: relative;
width: 200px;
height: 200px;
background-color: pink;
}
#sqr {
position: absolute;
width: 20px;
height: 20px;
background-color: blue;
}
<div id="contain">
<div id="sqr"></div>
</div>
Here's my take on it. React according to the position of the element, when it reaches a corner, change directions. This makes things easier, since we do not rely on actual positions to know where to go next step...
It is because, when animation gets to pos1 = [180, 180], it executes:
else if (pos1[0] >= 180 && pos1[1] >= 180) {
pos1[0]--;
box.style.left = pos1[0] + "px";
}
And then pos1 = [179, 180], which is not covered by the code.
I suggest using something like that:
var direction = 0; //0 - right, 1 - down, 2 - left, 3 - up
function slide() {
if (pos1[0] < 180 && pos1[1] = 0) {
direction = 0;
} else if (pos1[0] = 180 && pos1[1] < 180) {
direction = 1;
} else if (pos1[0] > 0 && pos1[1] = 180) {
direction = 2;
} else if (pos1[0] = 0 && pos1[1] > 0) {
direction = 3;
}
switch(direction){
case 0:
pos1[0]++;
break;
case 1:
pos1[1]++;
break;
case 2:
pos1[0]--;
break;
case 3:
pos1[1]--;
break;
}
box.style.left = pos1[0] + "px";
box.style.top = pos1[1] + "px";
}
I'm not usually a fan of doing someone's homework for them, but I got intrigued as to what would make it work and couldn't help myself. shrugs
The if statements have been tailored to be more explicit with what they need. This of course was achieved by following the methods suggested to you by #j08691, by just adding a console.log(pos1); at the top of each if section.
This is just for reference, in fact, #Salketer has managed to post before me and it looks a lot cleaner than this. The real answer is in the comments by #j08691
window.onload = function() {
var t = setInterval(slide, 5),
pos1 = [0, 0],
box = document.getElementById('sqr');
function slide() {
if (pos1[0] < 180 && pos1[1] === 0) {
console.log(pos1);
pos1[0]++;
box.style.left = pos1[0] + "px";
} else if (pos1[0] === 180 && pos1[1] < 180) {
console.log(pos1);
pos1[1]++;
box.style.top = pos1[1] + "px";
} else if ((pos1[0] <= 180 && pos1[0] >= 1) && pos1[1] === 180) {
console.log(pos1);
pos1[0]--;
box.style.left = pos1[0] + "px";
} else if (pos1[0] === 0 && pos1[1] <= 180) {
console.log(pos1);
pos1[1]--;
box.style.top = pos1[1] + "px";
}
}
}
#contain {
position: relative;
width: 200px;
height: 200px;
background-color: pink;
}
#sqr {
position: absolute;
width: 20px;
height: 20px;
background-color: blue;
}
<div id="contain">
<div id="sqr"></div>
</div>

sliderCursor not staying in slider

I'm trying to create a custom range slider. I'm having trouble keeping the slidersCursor in the slider.
Here's the relevant code:
var cursorPosition = 1 - clamp01((sliderDimention - (e.clientX - startPoint.left)) / sliderDimention);
sliderCursor.style.transform = 'translateX(' + (cursorPosition * sliderDimention - cursorRadius) + 'px)';
With the code above, when you drag the slider to the far right or left, the cursor goes halfway out of the slider on either side.
When I remove - cursorRadius, it goes too much to the right side. It stays in the slider when you drag to the left, but when you drag it to the right, it goes out of the slider.
When cursorRadius is equal to cursor.offsetWidth, it goes too much to the left side.
How can I make the sliderCursor stay in the slider when you drag to the far sides?
(Please don't post any JQuery or other "you can use 'this' plugin" answers. I'm doing this for learning purposes, and I want to create my own. Thanks!)
JSFiddle
function RangeSlider( /** DOM Elem */ parentElem) {
var wrapperElem = document.getElementsByClassName('wrapperElem')[0],
slider = document.getElementsByClassName('slider')[0],
sliderCursor = document.getElementsByClassName('sliderCursor')[0];
var sliderDimention = slider.offsetWidth,
cursorRadius = sliderCursor.offsetHeight / 2,
startPoint,
currentTarget;
function sliderDown(e) {
e.preventDefault();
currentTarget = null;
var sliderWithDescendents = wrapperElem.querySelectorAll('*');
for (var i = 0; i < sliderWithDescendents.length; i++) {
sliderWithDescendents[i]
if (sliderWithDescendents[i] === e.target || wrapperElem === e.target) {
currentTarget = wrapperElem.children[0];
break;
}
}
if (currentTarget === null) return;
startPoint = getOrigin(currentTarget);
sliderDimention = slider.offsetWidth;
window.addEventListener('mousemove', sliderMove);
sliderMove(e);
}
function sliderMove(e) {
var cursorPosition = 1 - clamp01((sliderDimention - (e.clientX - startPoint.left)) / sliderDimention);
sliderCursor.style.transform = 'translateX(' + (cursorPosition * sliderDimention - cursorRadius) + 'px)';
}
function mouseUpEvents() {
window.removeEventListener('mousemove', sliderMove);
}
wrapperElem.addEventListener('mousedown', sliderDown);
window.addEventListener('mouseup', mouseUpEvents);
}
var sliderTest = document.getElementById('sliderTest');
var test = new RangeSlider(sliderTest);
function clamp01(val) {
return Math.min(1, Math.max(0, val));
}
function getOrigin(elm) {
var box = (elm.getBoundingClientRect) ? elm.getBoundingClientRect() : {
top: 0,
left: 0
},
doc = elm && elm.ownerDocument,
body = doc.body,
win = doc.defaultView || doc.parentWindow || window,
docElem = doc.documentElement || body.parentNode,
clientTop = docElem.clientTop || body.clientTop || 0, // border on html or body or both
clientLeft = docElem.clientLeft || body.clientLeft || 0;
return {
left: box.left + (win.pageXOffset || docElem.scrollLeft) - clientLeft,
top: box.top + (win.pageYOffset || docElem.scrollTop) - clientTop
};
}
.wrapperElem {
height: 18px;
width: 100%;
cursor: pointer;
display: flex;
}
.slider {
height: 100%;
width: calc(100% - 62px);
border: 1px solid black;
}
.sliderCursor {
width: 14px;
height: 14px;
border-radius: 50%;
border: 2px solid black;
}
<div class="wrapperElem">
<div class="slider">
<div class="sliderCursor"></div>
</div>
</div>
It should be sliderCursor.style.transform = 'translateX(' + (cursorPosition * (sliderDimention - cursorRadius*2)) + 'px)';
You need the radius times x2 then the brackets are to perform the operations first then multiply by cursorPostions (which is from 0 to 1);
Although it works, I'd try clamp the final value (from [0 + radius] to [dimension - radius]). That way you won't get this weird drag where the mouse is in the left or right of the scroll_cursor. You want the mouse to be in the center of it at all times.
If you are doing it for learning, dissect rangeslider.js? It's very well coded.
function RangeSlider( /** DOM Elem */ parentElem) {
var wrapperElem = document.getElementsByClassName('wrapperElem')[0],
slider = document.getElementsByClassName('slider')[0],
sliderCursor = document.getElementsByClassName('sliderCursor')[0];
var sliderDimention = slider.offsetWidth,
cursorRadius = sliderCursor.offsetHeight / 2,
startPoint,
currentTarget;
function sliderDown(e) {
e.preventDefault();
currentTarget = null;
var sliderWithDescendents = wrapperElem.querySelectorAll('*');
for (var i = 0; i < sliderWithDescendents.length; i++) {
sliderWithDescendents[i]
if (sliderWithDescendents[i] === e.target || wrapperElem === e.target) {
currentTarget = wrapperElem.children[0];
break;
}
}
if (currentTarget === null) return;
startPoint = getOrigin(currentTarget);
sliderDimention = slider.offsetWidth;
window.addEventListener('mousemove', sliderMove);
sliderMove(e);
}
function sliderMove(e) {
var cursorPosition = 1 - clamp01((sliderDimention - (e.clientX - startPoint.left)) / sliderDimention);
sliderCursor.style.transform = 'translateX(' + (cursorPosition * (sliderDimention - cursorRadius*2)) + 'px)';;
}
function mouseUpEvents() {
window.removeEventListener('mousemove', sliderMove);
}
wrapperElem.addEventListener('mousedown', sliderDown);
window.addEventListener('mouseup', mouseUpEvents);
}
var sliderTest = document.getElementById('sliderTest');
var test = new RangeSlider(sliderTest);
function clamp01(val) {
return Math.min(1, Math.max(0, val));
}
function getOrigin(elm) {
var box = (elm.getBoundingClientRect) ? elm.getBoundingClientRect() : {
top: 0,
left: 0
},
doc = elm && elm.ownerDocument,
body = doc.body,
win = doc.defaultView || doc.parentWindow || window,
docElem = doc.documentElement || body.parentNode,
clientTop = docElem.clientTop || body.clientTop || 0, // border on html or body or both
clientLeft = docElem.clientLeft || body.clientLeft || 0;
return {
left: box.left + (win.pageXOffset || docElem.scrollLeft) - clientLeft,
top: box.top + (win.pageYOffset || docElem.scrollTop) - clientTop
};
}
.wrapperElem {
height: 18px;
width: 100%;
cursor: pointer;
display: flex;
}
.slider {
height: 100%;
width: calc(100% - 62px);
border: 1px solid black;
}
.sliderCursor {
width: 14px;
height: 14px;
border-radius: 50%;
border: 2px solid black;
}
<div class="wrapperElem">
<div class="slider">
<div class="sliderCursor"></div>
</div>
</div>

JQuery UI set up my own tolerance

I´m working on game for my little baby. I want to change default tolerance in droppable object. I know, that there are default values like touch, fit, intersect and pointer. But in my app it doesn't work correctly, because I want something between fit and intersect. When I use fit, it is too difficult to insert into correct position, and when I use intersect, it is too light. Here is my HTML source:
<!DOCTYPE html>
<html lang="sk">
<head>
<title>
Puzzle Slovakia
</title>
<script src="jquery-2.1.3.min.js"></script>
<script src="jquery-ui.js"></script>
<script src="jquery.ui.touch-punch.js"></script>
<script type="text/JavaScript" src="javas.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<section>
<div id="game">
<div id="complete">
<img src="images/map.png">
</div>
</div>
</section>
</body>
</html>
And there is my JS code:
window.onload = function() {
var hra = document.getElementById("game");
hra.innerHTML+="<div class='place' id='BAp'></div><img class='puzzle' id='BA' src='images/puzzle/BA.png'>";
hra.innerHTML+="<div class='place' id='TTp'></div><img class='puzzle' id='TT' src='images/puzzle/TT.png'>";
hra.innerHTML+="<div class='place' id='TNp'></div><img class='puzzle' id='TN' src='images/puzzle/TN.png'>";
hra.innerHTML+="<div class='place' id='ZAp'></div><img class='puzzle' id='ZA' src='images/puzzle/ZA.png'>";
hra.innerHTML+="<div class='place' id='BBp'></div><img class='puzzle' id='BB' src='images/puzzle/BB.png'>";
hra.innerHTML+="<div class='place' id='KEp'></div><img class='puzzle' id='KE' src='images/puzzle/KE.png'>";
hra.innerHTML+="<div class='place' id='PPp'></div><img class='puzzle' id='PP' src='images/puzzle/PP.png'>";
hra.innerHTML+="<div class='place' id='NRp'></div><img class='puzzle' id='NR' src='images/puzzle/NR.png'>";
$('.puzzle').draggable( {
containment:'parent',
cursor:'move',
});
$('.place').droppable ( {
accept: '.puzzle',
drop: dropPicture,
tolerance: 'intersect'
});
}
function dropPicture( event, ui ) {
if ( $(this).attr('id') == ui.draggable.attr('id') + "p" ) {
ui.draggable.draggable( 'disable' );
ui.draggable.attr('class','done');
$(this).droppable( 'disable' );
ui.draggable.position( { of: $(this), my: 'left top', at: 'left top' } );
}
}
You could modify intersect function of jquery-ui to allow this. Most flexible way would be to be able to add a custom function returning true when droppable should be activated, and false when not. This would give complete control on the tolerance. Something like this:
$.ui.intersect = function(draggable, droppable, toleranceMode) {
if (!droppable.offset) {
return false;
}
var draggableLeft, draggableTop,
x1 = (draggable.positionAbs || draggable.position.absolute).left,
y1 = (draggable.positionAbs || draggable.position.absolute).top,
x2 = x1 + draggable.helperProportions.width,
y2 = y1 + draggable.helperProportions.height,
l = droppable.offset.left,
t = droppable.offset.top,
r = l + droppable.proportions.width,
b = t + droppable.proportions.height;
// With next line this allows to set a function as toleranceMode
if (typeof toleranceMode === "function") {
return toleranceMode(draggable, droppable);
} else {
// If it's not a function, then normal code applies
switch (toleranceMode) {
case "custom":
return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
x2 - (draggable.helperProportions.width / 2) < r && // Left Half
t < y1 && // Bottom Half
b > y1 + 15); // Top Half
case "fit":
return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
case "intersect":
return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
x2 - (draggable.helperProportions.width / 2) < r && // Left Half
t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
y2 - (draggable.helperProportions.height / 2) < b); // Top Half
case "pointer":
draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
return isOverAxis(draggableTop, t, droppable.proportions().height) && isOverAxis(draggableLeft, l, droppable.proportions().width);
case "touch":
return (
(y1 >= t && y1 <= b) || // Top edge touching
(y2 >= t && y2 <= b) || // Bottom edge touching
(y1 < t && y2 > b) // Surrounded vertically
) && (
(x1 >= l && x1 <= r) || // Left edge touching
(x2 >= l && x2 <= r) || // Right edge touching
(x1 < l && x2 > r) // Surrounded horizontally
);
default:
return false;
}
}
};
$("#draggable").draggable();
$("#droppable").droppable({
hoverClass: "hover",
tolerance: function(draggable, droppable) {
// Calculations will be made on the small div
// inside the draggable. This is the equivalent
// of touch tolerance, but applied not to the draggable
// itself, but to another div
var toleranceDiv = $('#toleranceDiv');
x1 = toleranceDiv.offset().left,
y1 = toleranceDiv.offset().top,
x2 = x1 + toleranceDiv.width(),
y2 = y1 + toleranceDiv.height(),
l = droppable.offset.left,
t = droppable.offset.top,
r = l + droppable.proportions.width,
b = t + droppable.proportions.height;
return (
(y1 >= t && y1 <= b) || // Top edge touching
(y2 >= t && y2 <= b) || // Bottom edge touching
(y1 < t && y2 > b) // Surrounded vertically
) && (
(x1 >= l && x1 <= r) || // Left edge touching
(x2 >= l && x2 <= r) || // Right edge touching
(x1 < l && x2 > r) // Surrounded horizontally
);
},
over: function(event, ui) {
$('#draggable').css('opacity', 0.8);
},
out: function(event, ui) {
$('#draggable').css('opacity', 0.5);
},
drop: function(event, ui) {
console.log('dropped');
}
});
#draggable {
width: 100px;
height: 100px;
background-color: blue;
opacity: 0.5;
position: absolute;
}
#toleranceDiv {
width: 20px;
height: 20px;
top: 30px;
left: 30px;
background-color: yellow;
position: absolute;
}
#droppable {
width: 200px;
height: 200px;
background-color: green;
opacity: 1;
top: 250px;
left: 250px;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script type="text/javascript" src="//code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<div id="droppable"></div>
<div id="draggable">
<div id="toleranceDiv">
</div>
</div>

using a global variable to store a number (JavaScript)

the statement if (xPos === xGold3 && yPos === yGold3) , the code somehow does not recognize the values for xGold3 and yGold3 and my code does not work, but if i assign some values manually like if (xPos === 400 && yPos === 0) , then the code works. Can anyone tell me what i'm doing wrong? thanks
<!DOCTYPE html>
<html>
<head>
<title>P</title>
<style>
div.box{ width: 600px; height: 400px; border: 5px solid black;
margin: auto; position: relative; }
</style>
<button type="button" onclick="position();setGoldPos();">New Game</button>
</head>
<body onLoad ="getGoldPos()" onKeyDown = "move(event)">
<script>
var dx = 20;
var dy = 20;
var xPos = 0;
var yPos = 0;
var xGold3 = 0;
var yGold3 = 0;
//generates random gold positions at the start of every game
function getGoldPos()
{
xGold3 = Math.floor((Math.random() * 545) + 1);
yGold3 = Math.floor((Math.random() * 350) + 1);
}
//assigns randomly generated position to image "gold3"
function setGoldPos()
{
document.getElementById("gold3").style.top= yGold3 + "px";
document.getElementById("gold3").style.left= xGold3 + "px";
}
function position()
{
kitty = document.getElementById("sprite");
kitty.style.left = xPos+"px";
kitty.style.top = yPos+"px";
if (xPos === xGold3 && yPos === yGold3)
{
document.getElementById("gold3").style.top= 420 + "px";
document.getElementById("gold3").style.left= 0 + "px";
}
setTimeout("position()",10);
}
function move(event)
{
var keyPressed = String.fromCharCode(event.keyCode);
if ((keyPressed == "W" || keyPressed == "I" || event.keyCode == '38' ) && yPos >= 2)
{
yPos -= dy;
}
else if ((keyPressed == "D" || keyPressed == "L" || event.keyCode == '39') && xPos <=545)
{
xPos += dx;
}
else if ((keyPressed == "S" || keyPressed == "K" || event.keyCode == '40') && yPos <= 350)
{
yPos += dy;
}
else if ((keyPressed == "A" || keyPressed == "J" || event.keyCode == '37') && xPos >= 3 )
{
xPos -= dx;
}
}
</script>
<div STYLE="text-align:center"> <h2> Use WASD or IJKL or arrow keys to move kitty </h2> </div>
<div class="box">
<img src="sprite.jpg" alt="kitty" id="sprite" width="40px"
style="position: absolute; left: 0px; top: 0px;">
<img id="gold3" src="gold.jpg" style="position:absolute;
left: 400; top: 100; width: 30px; height: 35px;"/>
</div>
</body>
</html>
Think about the issue. You are picking a random number and your step is by 20. So if the random number is not a factor of 20, it is impossible for them to be equal.
xGold3: 86 <-- actual value
xPos: 10, 30, 50, 70, 90, 110 <-- Possible values of X
With the possible values, it is not possible for xPos and xGold3 to ever be equal with this specific value. When you hard coded it to a value in the if statement, 400 was a possible value for xPos, hence why it worked.
So either you need to position the gold on a factor of the step, or you need to be a range.
So you either need to change the random number generator to round to the nearest factor of your step OR change your if statement to see if the gold is in the range of the step. The check should be something like this: (untested)
if (xGold3 >= xPos && xGold3 < xPos+dx && yGold3 >= yPos && yGold3 < yPos+dy)
Positions will never be equal with the current code, try something like this instead to see if both x and y of the cat are within 20pxs:
if (Math.abs(xPos - xGold3) <= 20 && Math.abs(yPos - yGold3) <= 20)
As I dove into it, variable type was not the issue.
This works below! Working JSFiddle https://jsfiddle.net/t7k0a395/
If you subtract the modulo of the random number to make it divisible by 20 so it will be eaqual to your step variable of 20 it works. When it gets to the gold, now the gold moves outside the box.
xGold3 = Math.floor((Math.random()* 545) + 1);
yGold3 = Math.floor((Math.random()* 350) + 1);
xGold3 = xGold3-(xGold3 % 20);
yGold3 = yGold3-(yGold3 % 20);
RGecy
REVISED: Maybe a better way would be to take the mod of xGold3 and dx and do the same for the y values. That way if you changed dx or dy, you would not need to change the mod value.
xGold3 = Math.floor((Math.random()* 545) + 1);
yGold3 = Math.floor((Math.random()* 350) + 1);
xGold3 = xGold3-(xGold3 % dx);
yGold3 = yGold3-(yGold3 % dy);

Categories

Resources