How to rotate a box div while dragging an element using jquery - javascript

I understand that we need to use transform: rotate(ndeg); in order to rotate a specific element in CSS. In this case, I want to do it dynamically. Using jQuery, I want to rotate the box/container div when the user drags the handle (the red background) on n degrees as the user wishes. Is it possible in jQuery?
body {
padding: 50px;
}
.box_element {
border: 1px solid black;
width: 200px;
height: 200px;
position: relative;
z-index: -1;
}
.handle {
position: absolute;
bottom: -10px;
right: -10px;
width: 10px;
height: 10px;
border: 1px solid;
background: red;
z-index: 10;
}
<body>
<div class="box_element">
THIS IS TEST
<div class="handle"></div>
</div>
</body>

Here you need to write few code to make it possible, try live code https://codepen.io/libin-prasanth/pen/xxxzbLg
var stop,
active = false,
angle = 0,
rotation = 0,
startAngle = 0,
center = {
x: 0,
y: 0
},
R2D = 180 / Math.PI;
function start(e) {
e.preventDefault();
var bb = this.getBoundingClientRect(),
t = bb.top,
l = bb.left,
h = bb.height,
w = bb.width,
x,
y;
center = {
x: l + w / 2,
y: t + h / 2
};
x = e.clientX - center.x;
y = e.clientY - center.y;
startAngle = R2D * Math.atan2(y, x);
return (active = true);
}
function rotate(e) {
e.preventDefault();
var x = e.clientX - center.x,
y = e.clientY - center.y,
d = R2D * Math.atan2(y, x);
rotation = d - startAngle;
return (rot.style.webkitTransform = "rotate(" + (angle + rotation) + "deg)");
}
function stop() {
angle += rotation;
return (active = false);
}
rot = document.getElementById("draggable");
rot.addEventListener("mousedown", start, false);
window.addEventListener("mousemove", function(event) {
if (active === true) {
event.preventDefault();
rotate(event);
}
});
window.addEventListener("mouseup", function(event) {
event.preventDefault();
stop(event);
});
#draggable {
left: 50px;
top: 50px;
width: 100px;
height: 100px;
position: relative;
border: 1px solid #000;
}
#draggable:before{
content: "";
position: absolute;
bottom: -5px;
right: -5px;
width: 10px;
height: 10px;
background: #f00;
}
<div id="draggable">
</div>

You can make use of a css-variable and then change the value of the variable when clicked.
const box_element = document.getElementById('box_element');
const handle = document.getElementById('handle');
handle.addEventListener('click', function() {
let currentVal = getComputedStyle(box_element).getPropertyValue('--rotate_deg');
box_element.style.setProperty(
'--rotate_deg', ((parseInt(currentVal.replace('deg', '')) + 90) % 360) + 'deg');
});
:root {
--rotate_deg: 0deg;
}
.box_element {
margin: 1em;
border: 1px solid black;
width: 100px;
height: 100px;
position: relative;
z-index: -1;
transform: rotate(var(--rotate_deg))
}
.handle {
position: absolute;
bottom: -10px;
right: -10px;
width: 10px;
height: 10px;
border: 1px solid;
background: red;
z-index: 10;
cursor: pointer;
}
<div class="box_element" id="box_element">
THIS IS TEST
<div class="handle" id="handle"></div>
</div>

Related

document.addEventListener blocking highlight in textarea

I did a div that is moveable but unfortunetaly the function that let user move the div also block the highlight of the text in the text area behind.
I would like to keep the possibility to move the div and to highlight the text in textarea like I want.
Ps: I already tried to put the addEventListener on varMoveButtonNotesWindow but it's really ncomfortable to use it like that (we need to keep the cursor in the little box, and I dont want the box to be bigger it wouldn't look good).
Here's the code:
var mousePosition;
var offset = [0,0];
var isDown = false;
var varMoveButtonNotesWindow = document.getElementById('moveButtonNotesWindow');
var varNotesWindow = document.getElementById('notesWindow');
varMoveButtonNotesWindow.addEventListener('mousedown', function(e) {
isDown = true;
offset = [
varNotesWindow.offsetLeft - e.clientX,
varNotesWindow.offsetTop - e.clientY
];
}, true);
document.addEventListener('mouseup', function() {
isDown = false;
}, true);
//The bug occurs here
document.addEventListener('mousemove', function(event) {
event.preventDefault();
if (isDown) {
mousePosition = {
x : event.clientX,
y : event.clientY
};
varNotesWindow.style.left = (mousePosition.x + offset[0]) + 'px';
varNotesWindow.style.top = (mousePosition.y + offset[1]) + 'px';
}
}, true);
//so far
function closeNotesWindow() {
varNotesWindow.classList.remove('show');
}
function openNotesWindow() {
windowsModalContainer.classList.remove('show');
varNotesWindow.classList.add('show');
};
.firstTextarea {
height: 300px;
width: 300px;
}
#notesWindow {
display: block;
position: absolute;
width: 300px;
height: 275px;
top: 0px;
left: 0px;
border: 2px solid #313131;
z-index: 2;
resize: both;
overflow: auto;
}
#headerNotesWindow {
height: 35px;
background-color: black;
}
#moveButtonNotesWindow {
position: absolute;
background-color: blue;
color: white;
width: 20px;
height: 20px;
right: 5px;
z-index: 1;
top: 7.5px;
}
#closeButtonNotesWindow {
position: absolute;
background-color: red;
color: white;
width: 20px;
height: 20px;
right: 30px;
z-index: 1;
top: 7.5px;
}
#divTextareaNotesWindow {
text-align: center;
height: calc(100% - 6px - 35px);
}
#textareaNotesWindow {
resize: none;
width: calc(100% - 6px);
height: 100%;
outline: none;
}
<textarea class="firstTextarea">Pokemon is the best game of my childhood.</textarea>
<div class="divWindow" id="notesWindow">
<div id="headerNotesWindow">
<div id="moveButtonNotesWindow"></div>
<div id="closeButtonNotesWindow" onclick="closeNotesWindow()"></div>
</div>
<div id="divTextareaNotesWindow">
<textarea id="textareaNotesWindow"></textarea>
</div>
</div>
This can do like but not perfact:
RollBack selection when focus back it.
var mousePosition;
var offset = [0,0];
var isDown = false;
var varMoveButtonNotesWindow = document.getElementById('moveButtonNotesWindow');
var varNotesWindow = document.getElementById('notesWindow');
varMoveButtonNotesWindow.addEventListener('mousedown', function(e) {
isDown = true;
offset = [
varNotesWindow.offsetLeft - e.clientX,
varNotesWindow.offsetTop - e.clientY
];
}, true);
document.addEventListener('mouseup', function() {
isDown = false;
}, true);
//The bug occurs here
document.addEventListener('mousemove', function(event) {
event.preventDefault();
if (isDown) {
mousePosition = {
x : event.clientX,
y : event.clientY
};
varNotesWindow.style.left = (mousePosition.x + offset[0]) + 'px';
varNotesWindow.style.top = (mousePosition.y + offset[1]) + 'px';
}
}, true);
//so far
window.addEventListener('load',function(){
var logTextSelection = function(event) {
var tgItem = event.target;
tgItem.setAttribute("lastSelectionStart",tgItem.selectionStart);
tgItem.setAttribute("lastSelectionEnd",tgItem.selectionEnd);
}
var rollBackSelection = function(event){
var tgItem = event.target;
var lastSelectionStart = tgItem.getAttribute("lastSelectionStart");
var lastSelectionEnd = tgItem.getAttribute("lastSelectionEnd");
if((lastSelectionStart !== lastSelectionEnd)){
tgItem.focus();
tgItem.setSelectionRange(lastSelectionStart,lastSelectionEnd);
}
}
var docTextareas = document.getElementsByTagName('textarea');
for (var i = 0; i < docTextareas.length; i++) {
docTextareas[i].addEventListener('select', logTextSelection, true);
docTextareas[i].addEventListener('keyup', logTextSelection, true);
docTextareas[i].addEventListener('focus', rollBackSelection, true);
}
});
function closeNotesWindow() {
varNotesWindow.classList.remove('show');
}
function openNotesWindow() {
windowsModalContainer.classList.remove('show');
varNotesWindow.classList.add('show');
};
.firstTextarea {
height: 300px;
width: 300px;
}
#notesWindow {
display: block;
position: absolute;
width: 300px;
height: 275px;
top: 0px;
left: 0px;
border: 2px solid #313131;
z-index: 2;
resize: both;
overflow: auto;
}
#headerNotesWindow {
height: 35px;
background-color: black;
}
#moveButtonNotesWindow {
position: absolute;
background-color: blue;
color: white;
width: 20px;
height: 20px;
right: 5px;
z-index: 1;
top: 7.5px;
}
#closeButtonNotesWindow {
position: absolute;
background-color: red;
color: white;
width: 20px;
height: 20px;
right: 30px;
z-index: 1;
top: 7.5px;
}
#divTextareaNotesWindow {
text-align: center;
height: calc(100% - 6px - 35px);
}
#textareaNotesWindow {
resize: none;
width: calc(100% - 6px);
height: 100%;
outline: none;
}
<textarea class="firstTextarea">Pokemon is the best game of my childhood.</textarea>
<div class="divWindow" id="notesWindow">
<div id="headerNotesWindow">
<div id="moveButtonNotesWindow"></div>
<div id="closeButtonNotesWindow" onclick="closeNotesWindow()"></div>
</div>
<div id="divTextareaNotesWindow">
<textarea id="textareaNotesWindow"></textarea>
</div>
</div>
OK I found it, i just created a div that replace document for the addeventListener.
Ps I set the color to rgba(0, 175, 0, 0.3) just for you to see how it react and work you can obviously change it to 0.
function start() {
varNotesWindow.classList.add('show');
}
var mousePosition;
var offset = [0,0];
var isDown = false;
var varMoveButtonNotesWindow = document.getElementById('moveButtonNotesWindow');
var varNotesWindow = document.getElementById('notesWindow');
const constAlternativeDocumentForMoveButtonsWindow = document.getElementById('alternativeDocumentForMoveButtonsWindowId');
//Start Move Notes Window
varMoveButtonNotesWindow.addEventListener('mousedown', function(e) {
isDown = true;
offset = [
varNotesWindow.offsetLeft - e.clientX,
varNotesWindow.offsetTop - e.clientY
];
constAlternativeDocumentForMoveButtonsWindow.classList.add('use');
}, true);
constAlternativeDocumentForMoveButtonsWindow.addEventListener('mousemove', function(event) {
event.preventDefault();
if (isDown) {
mousePosition = {
x : event.clientX,
y : event.clientY
};
varNotesWindow.style.left = (mousePosition.x + offset[0]) + 'px';
varNotesWindow.style.top = (mousePosition.y + offset[1]) + 'px';
}
}, true);
constAlternativeDocumentForMoveButtonsWindow.addEventListener('mouseup', function() {
constAlternativeDocumentForMoveButtonsWindow.classList.remove('use');
});
document.addEventListener('mouseup', function() {
isDown = false;
}, true);
//End Move Notes Window
function closeNotesWindow() {
varNotesWindow.classList.remove('show');
}
function openNotesWindow() {
windowsModalContainer.classList.remove('show');
varNotesWindow.classList.add('show');
};
.alternativeDocumentForMoveButtonsWindowClass {
display: none;
}
.alternativeDocumentForMoveButtonsWindowClass.use {
display: block;
position: absolute;
z-index: 3;
width: 100%;
height: 100%;
left: 0;
top: 0;
background-color: rgba(0, 175, 0, 0.3);
}
#notesWindow {
display: none;
}
#notesWindow.show {
display: block;
position: absolute;
width: 300px;
height: 275px;
top: 0px;
left: 0px;
border: 2px solid #313131;
z-index: 2;
resize: both;
overflow: auto;
}
#headerNotesWindow {
height: 35px;
background-color: black;
}
#moveButtonNotesWindow {
position: absolute;
background-color: blue;
color: white;
width: 20px;
height: 20px;
right: 5px;
z-index: 1;
top: 7.5px;
}
#closeButtonNotesWindow {
position: absolute;
background-color: red;
color: white;
width: 20px;
height: 20px;
right: 30px;
z-index: 1;
top: 7.5px;
}
#divTextareaNotesWindow {
text-align: center;
height: calc(100% - 6px - 35px);
}
#textareaNotesWindow {
resize: none;
width: calc(100% - 6px);
height: 100%;
outline: none;
}
<button onclick='start()'>Let's Go</div>
<div class="alternativeDocumentForMoveButtonsWindowClass" id="alternativeDocumentForMoveButtonsWindowId"></div>
<div class="divWindow" id="notesWindow">
<div id="headerNotesWindow">
<div id="moveButtonNotesWindow"></div>
<div id="closeButtonNotesWindow" onclick="closeNotesWindow()"></div>
</div>
<div id="divTextareaNotesWindow">
<textarea id="textareaNotesWindow"></textarea>
</div>
</div>

Rotate 2 circles with each other in circular motion by mouse drag

I want to rotate 2 circles around each other in a circular motion by mouse drag like in this code using jQuery
When I drag the white ball it rotates correctly and makes red ball rotate also and that what I need.
My problem is that when I click on red ball it doesn't rotate and doesn't make as the white ball.
I want to make a red ball like a white ball exactly that when drag red ball the red ball and white ball rotate with mouse like in white-ball case.
https://jsfiddle.net/Sarah_Lotfy/h1ye8Ld3/4/
If there is a code that does the same thing please share it with me
var circle = document.getElementById('circle'),
picker = document.getElementById('picker'),
pickerCircle = picker.firstElementChild,
rect = circle.getBoundingClientRect(),
center = {
x: rect.left + rect.width / 2,
y: rect.top + rect.height / 2
},
transform = (function(){
var prefs = ['t', 'WebkitT', 'MozT', 'msT', 'OT'],
style = document.documentElement.style,
p;
for (var i = 0, len = prefs.length; i < len; i++){
if ( (p = prefs[i] + 'ransform') in style ) return p
}
alert('your browser doesnt support css transforms!')
})(),
rotate = function(x, y){
var deltaX = x - center.x,
deltaY = y - center.y,
angle = Math.atan2(deltaY, deltaX) * 180 / Math.PI
return angle
},
// DRAGSTART
mousedown = function(event){
event.preventDefault()
document.body.style.cursor = 'move'
mousemove(event)
document.addEventListener('mousemove', mousemove)
document.addEventListener('mouseup', mouseup)
},
// DRAG
mousemove = function(event){
picker.style[transform] = 'rotate(' + rotate(event.x, event.y) + 'deg)'
},
// DRAGEND
mouseup = function(){
document.body.style.cursor = null;
document.removeEventListener('mouseup', mouseup)
document.removeEventListener('mousemove', mousemove)
}
// DRAG START
pickerCircle.addEventListener('mousedown', mousedown)
// ENABLE STARTING THE DRAG IN THE BLACK CIRCLE
circle.addEventListener('mousedown', function(event){
if(event.target == this) mousedown(event)
})
#circle{
position: relative;
width: 300px;
height: 300px;
border-radius: 50%;
background: #000;
}
#circle-in{
position: absolute;
top: 35px;
left: 35px;
width: 230px;
height: 230px;
border-radius: 50%;
background: #fff;
}
#picker{
position: absolute;
top: 50%;
left: 50%;
height: 30px;
margin-top: -15px;
width: 50%;
transform-origin: center left;
}
#picker-circle{
width: 30px;
height: 30px;
border-radius: 50%;
background: #fff;
margin: 0 3px 0 auto;
cursor: move;
}
#picker2{
position: absolute;
top: -200%;
left: -100%;
height: 30px;
margin-top: -10px;
width: 50%;
transform-origin: center right ;
}
#picker-circle2{
width: 30px;
height: 30px;
border-radius: 50%;
background: red;
margin: 0 3px 0 auto;
cursor: move;
}
<div id="circle">
<div id="circle-in"></div>
<div id="picker">
<div id="picker-circle"></div>
</div>
<div id="picker2">
<div id="picker-circle2"></div>
</div>
</div>

How do I make second div move down and up with the w and s keys on the keyboard?

The Problem I'm having is that the everytime i trigger the event key for w and s characters, it logs on the console showing the w event key being triggered, but nothing happens to the div as i want it to move up and down. I tried to use the code structure as the first div but could only get a console.log(e). How do i make it move up or down?
I'm building pong on basically div elements, and some js. I got the first paddle to work. When i tried to the run the same code but using keydown funtion and use e.key to equal w. It for some reason is shown console logging the w key being press down, but it never moves the second div.
var playerOne = document.getElementById("playerOnePaddle");
var playerTwo = document.getElementById("playerTwoPaddle");
console.log(playerOne);
console.log(playerTwo);
window.addEventListener('keydown', function (e) {
var y = parseInt(getComputedStyle(playerOne).top);
e.preventDefault();
if (e.key === "ArrowUp") {
y -= 1;
playerOne.style.top = y + "px";
console.log(e);
} else if (e.key === "ArrowDown") {
y += 1;
playerOne.style.top = y + "px";
console.log(e);
}
});
window.addEventListener('keydown', function (e){
var x = parseInt(getComputedStyle(playerTwo).top);
e.preventDefault();
if (e.key === 'w') {
x -= 1;
playerOne.style.top = x + "px";
console.log(e);
} else if (e.key === 's') {
x = x + 1;
playerOne.style.top = x + "px";
console.log(e);
}
});
#backBoard {
border: 1px solid black;
height: 200px;
position: relative;
width: 400px;
}
#playerOnePaddle {
background: black;
border: 1px solid black;
height: 50px;
position: absolute;
top: 0;
left: 4px;
width: 4px;
}
#playerTwoPaddle {
background: red;
border: 1px solid red;
height: 50px;
position: absolute;
top: 0;
left: 390px;
width: 4px;
}
#ball {
background-color: green;
border: 1px solid black;
border-radius: 50%;
height: 15px;
position: absolute;
top: 0;
left: 50px;
width: 15px;
}
<div id="backBoard">
<div id="playerOnePaddle"></div>
<div id="playerTwoPaddle"></div>
<div id="ball"></div>
</div>
in the second keydown callback you're changing the style of playerOne where you would need to add it to playerTwo.
This should be what you are expecting (run the snippet) :
you don't have to make two exact event listeners just add all your code into one and use conditions.
your x and y were being reset each time the event function is executed so i moved them out of the callback function .
you were using on both events the same player playerOne.
var playerOne = document.getElementById("playerOnePaddle");
var playerTwo = document.getElementById("playerTwoPaddle");
var y = parseInt(getComputedStyle(playerOne).top);
var x = parseInt(getComputedStyle(playerTwo).top)
window.addEventListener('keydown', function (e) {
e.preventDefault();
if (e.key === "ArrowUp") {
y -= 1;
playerOne.style.top = y+"px";
} else if (e.key === "ArrowDown") {
y += 1;
playerOne.style.top = y+"px";
} else if (e.key === 'w') {
x -= 1;
playerTwo.style.top = x+"px";
} else if (e.key === 's') {
x = x + 1;
playerTwo.style.top = x+"px";
}
});
#backBoard {
border: 1px solid black;
height: 200px;
position: relative;
width: 400px;
}
#playerOnePaddle {
background: black;
border: 1px solid black;
height: 50px;
position: absolute;
top: 0;
left: 4px;
width: 4px;
}
#playerTwoPaddle {
background: red;
border: 1px solid red;
height: 50px;
position: absolute;
top: 0;
left: 390px;
width: 4px;
}
#ball {
background-color: green;
border: 1px solid black;
border-radius: 50%;
height: 15px;
position: absolute;
top: 0;
left: 50px;
width: 15px;
}
<div id="backBoard">
<div id="playerOnePaddle"></div>
<div id="playerTwoPaddle"></div>
<div id="ball"></div>
</div>

How can I avoid the automatic left alignment in rotation?

I am trying to move and rotate the object in the direction of the mouse click. Unfortunately during the first click object automatically align itself to left. It works perfectly after the first click but it doesn't work during the first click. I couldn't find out why it goes automatically to upper left corner. How can I fix that? Here is the code:
var theThing = document.querySelector("#thing");
var container = document.querySelector("#contentContainer");
var triangle = document.querySelector("#triangle");
container.addEventListener("click", getClickPosition, false);
function getClickPosition(e) {
var xPosition = e.clientX;
var yPosition = e.clientY;
var translate3dValue = "translate3d(" + xPosition + "px," + yPosition + "px,0)";
var box = $("#thing");
var boxCenter = [box.offset().left + box.width() / 2, box.offset().top + box.height() / 2];
var angle = Math.atan2(xPosition - boxCenter[0], -(yPosition - boxCenter[1])) * (180 / Math.PI);
theThing.style.transform += "rotate(" + angle + "deg)";
setTimeout(function() {
theThing.style.transform = translate3dValue;
}, 500);
}
body {
background-color: #FFF;
padding: 0;
margin: 0;
}
#contentContainer {
width: 550px;
height: 350px;
border: 15px #EDEDED;
overflow: hidden;
background-color: #F2F2F2;
cursor: pointer;
}
#thing {
width: 75px;
height: 75px;
background-color: rgb(255, 207, 0);
border-radius: 0%;
transform: translate3d(200px, 100px, 0);
transition: transform.2s ease-in;
}
#triangle {
width: 0;
height: 0;
border-left: 30px solid transparent;
border-right: 45px solid transparent;
border-bottom: 75px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="contentContainer">
<div id="thing">
<div id="triangle">
</div>
</div>
</div>
Because initially the transform is set in the CSS thus you cannot append the rotation to it and you will simply override it. Make it inline using JS and it will work fine. It will behave like the next ones since later you will be adding all the transform inline:
var theThing = document.querySelector("#thing");
var container = document.querySelector("#contentContainer");
var triangle = document.querySelector("#triangle");
container.addEventListener("click", getClickPosition, false);
theThing.style.transform="translate3d(200px, 100px, 0)";
function getClickPosition(e) {
var xPosition = e.clientX;
var yPosition = e.clientY;
var translate3dValue = "translate3d(" + xPosition + "px," + yPosition + "px,0)";
var box = $("#thing");
var boxCenter = [box.offset().left + box.width() / 2, box.offset().top + box.height() / 2];
var angle = Math.atan2(xPosition - boxCenter[0], -(yPosition - boxCenter[1])) * (180 / Math.PI);
theThing.style.transform += "rotate(" + angle + "deg)";
setTimeout(function() {
theThing.style.transform = translate3dValue;
}, 500);
}
body {
background-color: #FFF;
padding: 0;
margin: 0;
}
#contentContainer {
width: 550px;
height: 350px;
border: 15px #EDEDED;
overflow: hidden;
background-color: #F2F2F2;
cursor: pointer;
}
#thing {
width: 75px;
height: 75px;
background-color: rgb(255, 207, 0);
border-radius: 0%;
/*transform: translate3d(200px, 100px, 0);*/
transition: transform.2s ease-in;
}
#triangle {
width: 0;
height: 0;
border-left: 30px solid transparent;
border-right: 45px solid transparent;
border-bottom: 75px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="contentContainer">
<div id="thing">
<div id="triangle">
</div>
</div>
</div>

Getting distance to be 0

I want this div to go from point A to point B and vice-versa. Problem is the dist variable (distance) never gets to 0, it is usually either 1 or -1 (or some other range of values), which results in the div getting stuck and not going anywhere. In my complete code, point A and B positions are randomized every time I open the page.
The example below is reproducing the problem. To see it working as intended set #pointA { top: 5px; left: 5px; } | #pointB { top: 5px; left: 105px; }
var score = 0, points = 0, boxMode = 0, speed, speedX, speedY, angleRadians,
distX, distY, dist;
var destinationX = $("#pointB").position().left;
var destinationY = $("#pointB").position().top;
var pointAPos = $("#pointA").position();
var pointAx = pointAPos.left;
var pointAy = pointAPos.top;
var pointBPos = $("#pointB").position();
var pointBx = pointBPos.left;
var pointBy = pointBPos.top;
var boxPos = $('#box').position();
var boxX = pointAx;
var boxY = pointAy;
function calculateDistance(x, y) {
distX = boxX - x;
distY = boxY - y;
dist = Math.sqrt((distX*distX)+(distY*distY));
}
function boxMove() {
angleRadians = Math.atan2(-distX, -distY);
speed = 2;
speedX = speed * Math.sin(angleRadians);
speedY = speed * Math.cos(angleRadians);
document.getElementById("box").style.left = boxX + "px";
document.getElementById("box").style.top = boxY + "px";
boxX += speedX;
boxY += speedY;
}
function boxAI() {
calculateDistance(destinationX, destinationY);
if (!dist == 0) {
boxMove();
} else {
if (boxMode == 0) {
points += 1;
if (points == 50) {
// change destination to point A
destinationX = pointAx;
destinationY = pointAy;
boxMode = 1;
}
} else {
// change destination to point B
destinationX = pointBx;
destinationY = pointBy;
score += points;
points = 0;
boxMode = 0;
}
}
}
function mainLoop() {
boxAI();
$("#debug").html(points + " " + score + " " + boxMode);
requestAnimationFrame(mainLoop);
}
requestAnimationFrame(mainLoop);
#levelWrapper {
position: relative;
width: 400px;
height: 150px;
top: 2px;
margin: auto;
border: 1px solid red;
}
#pointA {
position: absolute;
background: beige;
width: 45px;
height: 45px;
top: 3px;
left: 50px;
margin: auto;
}
#pointB {
position: absolute;
background: beige;
width: 45px;
height: 45px;
top: 45px;
left: 195px;
margin: auto;
}
#box {
position: absolute;
background: black;
height: 5px;
width: 5px;
}
#debug {
position: relative;
background: white;
width: 250px;
height: 120px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="debug"></div>
<div id="levelWrapper">
<div id="pointA">A</div>
<div id="pointB">B</div>
<div id="box"></div>
</div>
<script src="jquery-3.2.1.js"></script>
<script type="text/javascript" src="woods_2.js"></script>
</body>
In JavaScript the ! operator has precedence over the ==, so if (dist != 0) would already be an improvement.
But as you use a speed variable which determines the difference between two consecutive measurements of the distance, you should make your test accordingly, and see if the distance is one step removed from zero:
if (dist >= speed)
Here is your code with some changes:
var score = 0, points = 0, boxMode = 0, speed, speedX, speedY, angleRadians,
distX, distY, dist;
var destinationX = $("#pointB").position().left;
var destinationY = $("#pointB").position().top;
var pointAPos = $("#pointA").position();
var pointAx = pointAPos.left;
var pointAy = pointAPos.top;
var pointBPos = $("#pointB").position();
var pointBx = pointBPos.left;
var pointBy = pointBPos.top;
var boxPos = $('#box').position();
var boxX = pointAx;
var boxY = pointAy;
var speed = 2; // make speed visible to other functions
function calculateDistance(x, y) {
distX = boxX - x;
distY = boxY - y;
dist = Math.sqrt((distX*distX)+(distY*distY));
}
function boxMove() {
angleRadians = Math.atan2(-distX, -distY);
speedX = speed * Math.sin(angleRadians);
speedY = speed * Math.cos(angleRadians);
document.getElementById("box").style.left = boxX + "px";
document.getElementById("box").style.top = boxY + "px";
boxX += speedX;
boxY += speedY;
}
function boxAI() {
calculateDistance(destinationX, destinationY);
// As the distance makes jumps of <speed> units,
// check whether it is within one step of the target
if (dist >= speed) {
boxMove();
} else {
score++; // Not sure what score should be measuring
if (boxMode == 0) {
// Change destination to point A
destinationX = pointAx;
destinationY = pointAy;
boxMode = 1;
} else {
// Change destination to point B
destinationX = pointBx;
destinationY = pointBy;
boxMode = 0;
}
}
}
function mainLoop() {
boxAI();
$("#debug").html(points + " " + score + " " + boxMode);
requestAnimationFrame(mainLoop);
}
requestAnimationFrame(mainLoop);
#levelWrapper {
position: relative;
width: 400px;
height: 150px;
top: 2px;
margin: auto;
border: 1px solid red;
}
#pointA {
position: absolute;
background: beige;
width: 45px;
height: 45px;
top: 3px;
left: 50px;
margin: auto;
}
#pointB {
position: absolute;
background: beige;
width: 45px;
height: 45px;
top: 45px;
left: 195px;
margin: auto;
}
#box {
position: absolute;
background: black;
height: 5px;
width: 5px;
}
#debug {
position: relative;
background: white;
width: 250px;
height: 120px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="debug"></div>
<div id="levelWrapper">
<div id="pointA">A</div>
<div id="pointB">B</div>
<div id="box"></div>
</div>
I did not understand what you wanted to do with score and points, so you will need to modify the code in that respect. For now I removed the changes to the points variable, and only increased score with every bounce.

Categories