drag and drop soccer score incrementor Javascript - javascript

I haven't been able to correctly build logic. After dropping soccer ball into the goal, the score does not increment. As stated in my JS script code, I attempted to add score++ to scoreDisplay function (in bold).
Thank you for looking at this issue.
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<h3>Score:<span id="score">0</span></h3>
<button id="start-button">Start/Pause</button>
<p>Drag the ball.</p>
<img src="https://en.js.cx/clipart/soccer-gate.svg" id="gate" class="droppable">
<img src="https://picsum.photos/150/150" id="ball">
<script>
const scoreDisplay = document.querySelector('#score')
let score = 0
let currentDroppable = null;
ball.onmousedown = function(event) {
let shiftX = event.clientX - ball.getBoundingClientRect().left;
let shiftY = event.clientY - ball.getBoundingClientRect().top;
ball.style.position = 'absolute';
ball.style.zIndex = 1000;
document.body.append(ball);
moveAt(event.pageX, event.pageY);
function moveAt(pageX, pageY) {
ball.style.left = pageX - shiftX + 'px';
ball.style.top = pageY - shiftY + 'px';
}
function onMouseMove(event) {
moveAt(event.pageX, event.pageY);
ball.hidden = true;
let elemBelow = document.elementFromPoint(event.clientX, event.clientY);
ball.hidden = false;
if (!elemBelow) return;
let droppableBelow = elemBelow.closest('.droppable');
if (currentDroppable != droppableBelow) {
if (currentDroppable) { // null when we were not over a droppable before this event
leaveDroppable(currentDroppable);
}
currentDroppable = droppableBelow;
if (currentDroppable) { // null if we're not coming over a droppable now
// (maybe just left the droppable)
enterDroppable(currentDroppable);
}
//add score
**function scoreIncrement() {
score++;
document.getElementById("score").innerText="Score: " + score;**
}​
}
}
document.addEventListener('mousemove', onMouseMove);
ball.onmouseup = function() {
document.removeEventListener('mousemove', onMouseMove);
ball.onmouseup = null;
};
};
function enterDroppable(elem) {
elem.style.background = 'pink';
}
function leaveDroppable(elem) {
elem.style.background = '';
}
ball.ondragstart = function() {
return false;
};
</script>
</body>
</html>
Thanks again for for taking the time to look this over

you were almost there!. You were missing what is called a "flag". That is a variable (usually true/false) that holds some information that allows you to make decisions in the right event (which you had).
In this case a flag could tell me if I am over or not the goal, so that when I drop the ball I can add a point to the score.
As you can see in the code below, when you enterDroppable the flag is set to true and when you leaveDroppable its set back to false; then when the event mouseUp is triggered, the flag is checked. If the flag was true, then the score is incremented (and its value is updated on the screen)
Note that I changed the style of the ball so it looks more like a ball. Also note that its not a good practice to subscribe and remove events inside other events. Its better to have the events subscribed once and have more flags: for example, set a flag in the mouseDown to know that the ball was "grabed", then the mouseMove event would check that flag to see if it had to move the ball or not. I leave it as is, so not to change your code much but keep it in mind.
See the working code below (scroll all the way down and click on "Run the snipped code" to see it in action). Also if this solved your question dont forget to mark it as such using the green check left to the answer.
const scoreDisplay = document.querySelector('#score')
let score = 0
let currentDroppable = null;
let ballIsOverDroppable = false;
ball.onmousedown = function(event) {
let shiftX = event.clientX - ball.getBoundingClientRect().left;
let shiftY = event.clientY - ball.getBoundingClientRect().top;
ball.style.position = 'absolute';
ball.style.zIndex = 1000;
document.body.append(ball);
moveAt(event.pageX, event.pageY);
function moveAt(pageX, pageY) {
ball.style.left = pageX - shiftX + 'px';
ball.style.top = pageY - shiftY + 'px';
}
function onMouseMove(event) {
moveAt(event.pageX, event.pageY);
ball.hidden = true;
let elemBelow = document.elementFromPoint(event.clientX, event.clientY);
ball.hidden = false;
if (!elemBelow) return;
let droppableBelow = elemBelow.closest('.droppable');
if (currentDroppable != droppableBelow) {
if (currentDroppable) { // null when we were not over a droppable before this event
leaveDroppable(currentDroppable);
}
currentDroppable = droppableBelow;
if (currentDroppable) { // null if we're not coming over a droppable now
// (maybe just left the droppable)
enterDroppable(currentDroppable);
}
}
}
document.addEventListener('mousemove', onMouseMove);
ball.onmouseup = function() {
document.removeEventListener('mousemove', onMouseMove);
ball.onmouseup = null;
if (ballIsOverDroppable) {
score++;
scoreDisplay.textContent = `${score}`;
}
};
};
function enterDroppable(elem) {
elem.style.background = 'pink';
ballIsOverDroppable = true;
}
function leaveDroppable(elem) {
elem.style.background = '';
ballIsOverDroppable = false;
}
ball.ondragstart = function() {
return false;
};
<h3>Score:<span id="score">0</span></h3>
<button id="start-button">Start/Pause</button>
<p>Drag the ball.</p>
<img src="https://en.js.cx/clipart/soccer-gate.svg" id="gate" class="droppable">
<img src="https://picsum.photos/20/20" id="ball" style="border-radius: 20px; border: 2px solid black;">

Related

I give two div the same style on click of a button and they don't behave the same

I have canvas where I can upload pdf file.On click of a button I can create div with image inside that is called divMark and I can drag that div on canvas.I made zoom functionality where on click of a button I increase width and height on all four sides for 25px and also I change style left and top of divMark. Original coordinates I store in array I have xList for top coordinates and yList for left coordinates and each value in xList I increase for 12 and yList I decrease for 5 then first value form each array I gave to first div second value to second div and so on.
This is code for creating divMark and for zoom functionality:
const myImg = document.getElementById("the-canvas");
const divBtn = document.querySelector(".btn-mark");
const zoomOutBtn = document.querySelector(".zoom-out-btn");
const zoomInBtn = document.querySelector(".zoom-in-btn");
let counter = 0;
let showCounter = 1;
divBtn.addEventListener("click", createContent);
zoomInBtn.addEventListener("click", zoomIn);
zoomOutBtn.addEventListener("click", zoomOut);
function createContent() {
var divMark = document.createElement("div");
divMark.classList = `markers mark`;
divMark.id = `${counter}`;
var img = document.createElement("img");
img.classList = "comment";
img.src = "indeksiraj-1.png";
img.alt = "myimage";
var pCounter = document.createElement("p");
pCounter.classList = "p-counter";
pCounter.innerHTML = showCounter;
divMark.appendChild(pCounter);
divMark.appendChild(img);
$(marksCanvas).append(divMark);
divMarks.push(divMark);
counter++;
showCounter++;
window.onload = addListeners();
function addListeners() {
divMark.addEventListener("mousedown", mouseDown, false);
window.addEventListener("mouseup", mouseUp, false);
}
function mouseUp() {
window.removeEventListener("mousemove", divMove, true);
}
function mouseDown(e) {
window.addEventListener("mousemove", divMove, true);
}
function divMove(e) {
var xCord = e.pageX;
var yCord = e.pageY;
divMark.style.top = yCord + "px";
divMark.style.left = xCord + "px";
divMark.onclick = function () {
divContent.setAttribute("style", "visibility:visible;");
console.log(parseInt(divMark.id));
let index = parseInt(divMark.id);
xList = removeXListItem(index, xList);
xList.splice(parseInt(divMark.id), 0, xCord);
yList.splice(parseInt(divMark.id), 0, yCord);
};
}
}
function xCordPlus(num) {
return num + 22;
}
function yCordPlus(num) {
return num + -8;
}
function xCordMinus(num) {
return num - 22;
}
function yCordMinus(num) {
return num + 8;
}
function removeXListItem(index, xList) {
xList.splice(index, 1);
return xList;
}
function zoomIn() {
var currWidth = myImg.clientWidth;
if (currWidth == 1000) return false;
else {
var currWidth = myImg.clientWidth;
myImg.style.width = currWidth + 100 + "px";
}
xList = xList.map(xCordPlus);
console.log("xList is: " + xList);
yList = yList.map(yCordPlus);
$(".markers").each(function (index) {
$(this).css({ top: yList[index] + "px", left: xList[index] + "px" });
});
}
function zoomOut() {
var currWidth = myImg.clientWidth;
var currHeight = myImg.clientHeight;
if (currWidth == 800) return false;
else {
var currWidth = myImg.clientWidth;
myImg.style.width = currWidth - 100 + "px";
}
xList = xList.map(xCordMinus);
yList = yList.map(yCordMinus);
$(".markers").each(function (index) {
$(this).css({ top: yList[index] + "px", left: xList[index] + "px" });
});
}
My problem is that when I put two divMarks one on the left side of canvas other one on the right side divMark on the right side works great it moves when I click zoomInBtn how is suppose to but divMark on the right side it does not work well it moves to much on the right side it not works like divMark on the right side.
Here is all code: https://jsfiddle.net/SutonJ/thernqmv/13/
You are making the zoom-out-btn class, when hovered, not disabled and active, go down the screen by the length of 12.5% of the size of the html element's font size on line 200 of the CSS in that jsfiddle you posted.
.zoom-out-btn:not(:disabled):hover:active {
transform: scale(1.05) translateY(0.125rem);
}
You are never doing the same for zoom-in-btn. Additionally, the css is quite different for the zoom-in-btn, so you need to add a transition property to that class if you want the on-hover effect to look smooth.

Adding and Removing Event Listeners that Point to Function Declarations inside Constructor Function Expression

I have a problem figuring out how to organize these sets of expressions in a way that works. My constructor is a component of a game editor. Inside of this constructor I have a method that handles when the player clicks on an SVG on the document calling the moveObject expression. The move object correctly moves the object and it seems like inner onMouseMove function declaration is working as intended, but I cannot figure out how to remove these listeners.
I tried bind(this) on the removes too, but those didn't work. Before I try to mess with the function expressions and declarations I wanted to see if any of you had any thoughts on how I could write this code more efficiently. I feel like it is a little clunky right now.
function Editor(game){
this.active = null;
this.moveObject = function(event) {
var x = event.clientX;
var y = event.clientY;
let element = document.elementFromPoint(x, y);
if (element.classList.contains('editorMoveable')) {
do {
element = element.parentElement;
if (element.classList.contains('gameObject'))
break;
} while(element.tagName != "body");
}
this.activeElement = element;
var key = splitElementID(this.activeElement.id);
this.active = this.game.objects[key.object][key.subObject];
let shiftX = event.clientX - this.activeElement.getBoundingClientRect().left;
let shiftY = event.clientY - this.activeElement.getBoundingClientRect().top;
var globalTransform = this.game.calculateGlobals(this.active);
var newPos = moveAt(event.pageX, event.pageY);
this.active.Transform.position.x = newPos.newPosX;
this.active.Transform.position.y = newPos.newPosY;
this.activeElement.style.transform = 'translate(' + newPos.newPosX + 'rem, ' + newPos.newPosY + 'rem)';
function moveAt(pageX, pageY) {
var newPosX = ((pageX - shiftX)/remSize - globalTransform.position.x);
var newPosY = ((pageY - shiftY)/remSize - globalTransform.position.y);
var newRotX = (0);
var newRotY = (0);
var newSclX = (1);
var newSclY = (1);
return {"newPosX": newPosX, "newPosY": newPosY}
}
function onMouseMove(event) {
var newPos = moveAt(event.pageX, event.pageY);
this.active.Transform.position.x = newPos.newPosX;
this.active.Transform.position.y = newPos.newPosY;
this.activeElement.style.transform = 'translate(' + newPos.newPosX + 'rem, ' + newPos.newPosY + 'rem)';
}
function onMouseUp() {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
this.activeElement = null;
this.active = null;
}
// Move the elem on mousemove
document.addEventListener('mousemove', onMouseMove.bind(this));
document.addEventListener('mouseup', onMouseUp.bind(this));
};
};
Results are as explained in the upper problem. Since the event is not being removed (they stack on each click) I get "cannot read property of null".
Thanks for all the help in advance!
The problem is that onMouseMove is not the same function as onMouseMove.bind(this).
What you can do is assign that to a variable, and then use that variable in both the addEventListener and removeEventListener calls.
let thisOnMouseMove = onMouseMove.bind(this);
let thisOnMouseUp = onMouseUp.bind(this);
function onMouseMove(event) {
var newPos = moveAt(event.pageX, event.pageY);
this.active.Transform.position.x = newPos.newPosX;
this.active.Transform.position.y = newPos.newPosY;
this.activeElement.style.transform = 'translate(' + newPos.newPosX + 'rem, ' + newPos.newPosY + 'rem)';
}
function onMouseUp() {
document.removeEventListener('mousemove', thisOnMouseMove);
document.removeEventListener('mouseup', thisOnMouseUp);
this.activeElement = null;
this.active = null;
}
// Move the elem on mousemove
document.addEventListener('mousemove', thisOnMouseMove);
document.addEventListener('mouseup', thisOnMouseUp);

how to drag and drop a <div> across the page

I am developing an web application where I am trying simulate a popup window using tags , for style purpose. I done this with this javascript code:
<script>
function handleClick(url){
document.getElementById("results").style.display = 'block';
document.getElementById("about").innerHTML='<object type="text/html" data="'+url+'" ></object>';
}
function cleanDiv() {
document.getElementById("results").style.display = 'none';
document.getElementById("about").innerHTML=' ';
}
</script>
associated to this html code:
<section class="about" id="results">
<div align="right">Fechar</div>
<div id="about" algin="center"></div>
</section>
and the style is on my css file.
I have almost all what I want, but I wish this "popup window" don't stay fixed in a unique position on the page, and the user could move it around with the mouse.
Someone knows how to make this with javascript/html/css only?
You are looking for the HTML5 draggable attribute and events. Make the element draggable by setting draggable="true" and ondragstart="dragElem(event)". Then write your code in function dragElem(ev) { }. See W3Schools
After more search, I ended with this code, from site http://waseemblog.com/42/movable-div-using-javascript.html
html:
<section class="about" id="results" style="left: 183px; top: 111px;" onMouseDown="dragStart(event, 'results');">
<div align="right">X</div>
<div id="content" align="center"></div>
</section>
javascript:
function getID(id)
{
return document.getElementById(id);
}
// Global object to hold drag information.
var dragObj = new Object();
function dragStart(event, id) {
var x, y;
dragObj.elNode = getID(id);
// Get cursor position with respect to the page.
try {
x = window.event.clientX + document.documentElement.scrollLeft
+ document.body.scrollLeft;
y = window.event.clientY + document.documentElement.scrollTop
+ document.body.scrollTop;
}
catch (e) {
x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;
}
// Save starting positions of cursor and element.
dragObj.cursorStartX = x;
dragObj.cursorStartY = y;
dragObj.elStartLeft = parseInt(dragObj.elNode.style.left, 10);
dragObj.elStartTop = parseInt(dragObj.elNode.style.top, 10);
if (isNaN(dragObj.elStartLeft)) dragObj.elStartLeft = 0;
if (isNaN(dragObj.elStartTop)) dragObj.elStartTop = 0;
// Capture mousemove and mouseup events on the page.
try {
document.attachEvent("onmousemove", dragGo);
document.attachEvent("onmouseup", dragStop);
window.event.cancelBubble = true;
window.event.returnValue = false;
}
catch (e) {
document.addEventListener("mousemove", dragGo, true);
document.addEventListener("mouseup", dragStop, true);
event.preventDefault();
}
}
function dragGo(event) {
var x, y;
// Get cursor position with respect to the page.
try {
x = window.event.clientX + document.documentElement.scrollLeft
+ document.body.scrollLeft;
y = window.event.clientY + document.documentElement.scrollTop
+ document.body.scrollTop;
}
catch (e) {
x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;
}
// Move drag element by the same amount the cursor has moved.
var drLeft = (dragObj.elStartLeft + x - dragObj.cursorStartX);
var drTop = (dragObj.elStartTop + y - dragObj.cursorStartY);
if (drLeft > 0)
{
dragObj.elNode.style.left = drLeft + "px";
}
else
{
dragObj.elNode.style.left = "1px";
}
if (drTop > 0)
{
dragObj.elNode.style.top = drTop + "px";
}
else
{
dragObj.elNode.style.top = "1px";
}
try {
window.event.cancelBubble = true;
window.event.returnValue = false;
}
catch(e){
event.preventDefault();
}
}
function dragStop(event) {
// Stop capturing mousemove and mouseup events.
try {
document.detachEvent("onmousemove", dragGo);
document.detachEvent("onmouseup", dragStop);
}
catch (e) {
document.removeEventListener("mousemove", dragGo, true);
document.removeEventListener("mouseup", dragStop, true);
}
}
It can be bigger than your counterpart using jquery, but I guess it works fine in most browsers available today.

Javascript drag and drop code works on div but doesn't work on img

I'm fairly new to JavaScript, so any help would be awesome!
I created this small block of code that let's me grab a div and drag it around. I assign the "dragme" id to the div and all is fine and dandy. The problem is that if I replace that div from my html and put an img element instead (obviously assigning the "dragme" id to the img), things don't work as expected.
When I click to drag the img, it actually moves for about 3 or 4 pixels then it freezes until I lift the mouse button (mouseup).
Is there some property or characteristic that would prevent the img element from acting the same way as the div does?
var isClicked = false;
var startClientX = 0;
var startClientY = 0;
var startLeft = 0;
var startTop = 0;
window.addEventListener("load", addListeners, true);
function addListeners()
{
document.getElementById("dragme").addEventListener("mousedown", mouseIsDown, false);
document.getElementById("dragme").addEventListener("mouseup", mouseIsUp, false);
window.addEventListener("mousemove", moveImage, false);
function mouseIsDown(e)
{
if (isClicked == false)
{
isClicked = true;
startClientX = e.clientX;
startClientY = e.clientY;
startLeft = document.getElementById("dragme").offsetLeft;
startTop = document.getElementById("dragme").offsetTop;
}
}
function mouseIsUp()
{
if (isClicked == true)
{
isClicked = false;
}
}
function moveImage(e)
{
if (isClicked == true)
{
imageLeftDif = e.clientX - startClientX;
imageTopDif = e.clientY - startClientY;
var newLeftPos = (startLeft + imageLeftDif) + "px";
var newTopPos = (startTop + imageTopDif) + "px";
document.getElementById("dragme").style.left = newLeftPos;
document.getElementById("dragme").style.top = newTopPos;
}
}
}
This fixed the problem (answer provided as a comment by syazdani):
I'd venture to say that the built in browser drag and drop for images
is kicking in. Try e.preventDefault and return false in the mousedown
handler. – syazdani Dec 2 '12 at 17:26

Make img not to move in html

I have an image on my page, and I would like to listen to onmousemove events when the mouse is down. But I can't because in my browser (Firefox), when I drag an image, well actually I drag the image, which I don't want.
Here's my code:
JavaScript part:
document.onmousemove=getMouseCoordinates;
var x;
var y;
var clicked = false;
function getMouseCoordinates(event){
ev = event || window.event;
x = ev.pageX;
y = ev.pageY;
}
function onClickMap(){
var obj = document.getElementById("selectArea");
var tempX = x;
var tempY = y;
obj.style.left = tempX + "px";
obj.style.top = tempY + "px";
clicked = true;
}
function onMoveMap(){
if(clicked){
var obj = document.getElementById("selectArea");
var xToSize = Math.abs(parseInt(obj.style.left) - x);
var yToSize = Math.abs(parseInt(obj.style.top) - y);
obj.style.width = xToSize + "px";
obj.style.height = yToSize + "px";
}
}
HTML part:
<img src="pixels.png" id ="pixelDiv" usemap="#pixelMap" onClick="onClickMap()" onmousemove="onMoveMap()">
Here is a jQuery solution.
This will disable all drags:
$(document).bind("dragstart", function() {
return false;
});
If you want to disable drags only on img elements:
$(document).bind("dragstart", function(e) {
if (e.target.nodeName.toUpperCase() == "IMG") {
return false;
}
});
You can add a mousedown handler that just returns false. This seems to stop the dragging in FF.
ok it's nice, but I suppose it is something firefox specific, now I disabled the onlcick and onmove methods of my image, but I can stil drag the image
now I've found the solution, I was looking for this
http://www.develobert.info/2008/10/disable-firefox-image-drag.html

Categories

Resources