I need to resize notes in my little application, but I don't know how. They have to be resized by dragging their bottom right corner and it must be done in pure java script.
Div with "+" adds new note and empty div is something like counter of all notes.
Code:
document.addEventListener("onload", Load());
var index = 0;
var cnt = 0;
var x = 0;
var y = 0;
var xx = 0;
var yy = 0;
var clicked = false;
var dragged = false;
var counter = 0;
var numberOfPapers = 0;
var state = 0;
function Load(){
var adder = document.querySelector("#add");
adder.setAttribute("onclick", "addClick()");
}
function addClick(){
cnt++;
numberOfPapers++;
document.querySelector("#counter").innerHTML = "Przebieg = " + cnt + "<br>" + "Liczba kartek = " + numberOfPapers;
var paper = document.createElement("div");
var paperX = document.createElement("div");
var paperR = document.createElement("div");
var paperS = document.createElement("div");
//papierek xD
paper.setAttribute("class", "paper");
paper.setAttribute("onmousedown", "movePaper(this,event)");
paper.setAttribute("onmouseup", "stop(this)");
paper.setAttribute("onmouseleave", "stop(this)");
paper.setAttribute("id", "id_" + cnt);
paper.style.top = "100px";
paper.style.left = "100px";
paper.style.zIndex = cnt;
//niszczyciel papierków
paperX.setAttribute("class", "deleter");
paperX.setAttribute("onclick", "deletePaper(this)");
//zmieniacz rozmiarów
paperR.setAttribute("class", "resizer");
paperR.ondragstart = function(e){
e.preventDefault();
};
paperR.setAttribute("onmousedown", "resize(this,event)");
//edytor tekstu tini emce
paperS.setAttribute("class", "txtEditor");
paperS.setAttribute("onclick", "editTxt()");
paper.appendChild(paperX);
paper.appendChild(paperR);
paper.appendChild(paperS);
document.body.appendChild(paper);
}
function stop(e){
e.setAttribute("onmousemove", null);
state = 1;
}
function resize(e,event){
state = 2;
}
function deletePaper(e){
e.parentElement.id = "del";
var del = document.querySelector("#del");
del.parentNode.removeChild(del);
numberOfPapers--;
document.querySelector("#counter").innerHTML = "Przebieg = " + cnt + "<br>" + "Liczba kartek = " + numberOfPapers;
}
function movePaper(e, event){
index++;
e.style.zIndex = index;
x = event.clientX;
y = event.clientY;
xx = e.style.left;
yy = e.style.top;
xx = xx.slice(0,xx.search("px"));
yy = yy.slice(0,yy.search("px"));
x = x - xx;
y = y - yy;
e.setAttribute("onmousemove","moreMove(this,event)");
}
function moreMove(e,event){
e.style.top = event.clientY - y + "px";
e.style.left = event.clientX - x + "px";
}
body{
margin: 0;
padding: 0;
}
#add{
position: absolute;
width: 45px;
height: 35px;
top: 25px;
right: 25px;
background-color: #F5574E;
text-align:center;
padding-top:10px;
border: solid black 1px;
}
#counter{
position: absolute;
width: 200px;
height: 45px;
top: 25px;
right: 80px;
background-color: #F5574E;
text-align:center;
border: solid black 1px;
}
.paper{
position: absolute;
width: 100px;
height: 100px;
top: 25px;
left: 25px;
background-color: #E3D67F;
border: solid black 1px;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.deleter{
position: absolute;
width: 10px;
height: 10px;
top: 0px;
right: 0px;
background-color: red;
}
.resizer{
position: absolute;
width: 10px;
height: 10px;
bottom: 0px;
right: 0px;
background-color: green;
}
.txtEditor{
position: absolute;
width: 10px;
height: 10px;
top: 10px;
right: 0px;
background-color: yellow;
}
<body>
<div id="add">+
</div>
<div id="counter">
</div>
</body>
You can simply take replicate your move functions and instead of targeting top and left you target width and height of the parent node. Like this:
function resize(e, event) {
event.stopPropagation();//this to prevent move behavior to be triggered when clicking resize handle
state = 2;
index++;
e.style.zIndex = index;
x = event.clientX;
y = event.clientY;
xx = e.parentNode.style.width;
yy = e.parentNode.style.height;
xx = xx.slice(0, xx.search("px"));
yy = yy.slice(0, yy.search("px"));
x = x - xx;
y = y - yy;
e.setAttribute("onmousemove", "resizeMove(this,event)");
}
function resizeMove(e, event) {
console.log('resixe')
e.parentNode.style.height = event.clientY - y + "px";
e.parentNode.style.width = event.clientX - x + "px";
}
You'll have to declare width and height of your parentNode for it to work, you can add it to your paper section.
paper.style.width = "100px";
paper.style.height = "100px";
Related
I want to have a webpage whose entire viewable area is filled with divs. I am currently using the following code:
var wh= window.innerHeight;
var ww= window.innerWidth;
var area= wh * ww;
i= 1;
while(area > 0) {
document.getElementById("map").innerHTML+= "<div class='map-box' id='box" + i + "'></div>";
area-= 20 * 20;
i+=1;
}
.map-box {width: 20px; height: 20px; border-color: grey; border-width: 1px; border-style: solid; display: inline-block; margin: 0; padding: 0;}
<body>
<div id='map'></div>
</body>
If you try to use this code is your browser, you will see that there are two flaws in this:
First, it creates too many extra divs which go outside the viewable screen.
Second, this code is also somewhat slow.
Can someone here help me address both of these flaws and also optimize this code for faster performance?
1.) That <div> is not 20x20, because of the border:
let d = document.getElementById("test");
console.log(d.offsetWidth, d.offsetHeight);
.map-box {
width: 20px;
height: 20px;
border-color: grey;
border-width: 1px;
border-style: solid;
display: inline-block;
margin: 0;
padding: 0;
}
<div id="test" class="map-box"></div>
2.) There's still the default border around the entire thing, and also some spacing between the lines:
var wh = window.innerHeight;
var ww = window.innerWidth;
var area = wh * ww;
i = 1;
while (area > 0) {
document.getElementById("map").innerHTML += "<div class='map-box' id='box" + i + "'></div>";
area -= 22 * 22; // hardcoding is not that nice
i += 1;
}
.map-box {
width: 20px;
height: 20px;
border-color: grey;
border-width: 1px;
border-style: solid;
display: inline-block;
margin: 0;
padding: 0;
}
#map {
background: blue;
}
body {
background: red;
}
<div id='map'></div>
3.) Half cells are evil, so the width/height should be rounded downwards to a multiple of 22. Suddenly the grid is becoming an actual rectangle, at least in Chrome/Edge. The between-spacing is still a problem:
var wh = Math.floor(window.innerHeight / 22) * 22; // <--!!
var ww = Math.floor(window.innerWidth / 22) * 22; // <--!!
var area = wh * ww;
i = 1;
while (area > 0) {
document.getElementById("map").innerHTML += "<div class='map-box' id='box" + i + "'></div>";
area -= 22 * 22;
i += 1;
}
.map-box {
width: 20px;
height: 20px;
border-color: grey;
border-width: 1px;
border-style: solid;
display: inline-block;
margin: 0;
padding: 0;
}
#map {
background: blue;
}
body {
background: red;
margin: 0; // <--!!
padding: 0; // <--!!
}
<div id='map'></div>
I don't actually know how to use line-height properly, this one works on my machine with my scaling/DPI, in Chrome/Edge, but that's all I can say about it. The 22-s are cut back, area now simply stores the number of <div>s to generate.
var wh = Math.floor(window.innerHeight / 22);
var ww = Math.floor(window.innerWidth / 22);
var area = wh * ww;
i = 1;
while (area > 0) {
document.getElementById("map").innerHTML += "<div class='map-box' id='box" + i + "'></div>";
area--;
i += 1;
}
.map-box {
width: 20px;
height: 20px;
border-color: grey;
border-width: 1px;
border-style: solid;
display: inline-block;
margin: 0;
padding: 0;
}
#map {
line-height: 0.6;
}
body {
margin: 0;
padding: 0;
}
<div id='map'></div>
Instead of accessing dom element's inner html on each loop iteration - do it once after the loop with "prepared" data to set there
const wh = window.innerHeight;
const ww = window.innerWidth;
let area = wh * ww;
i = 1;
const ms = Date.now();
const divs = [];
while (area > 0) {
divs.push("<div class='map-box' id='box" + i + "'></div>");
area -= 20 * 20;
i += 1;
}
document.getElementById("map").innerHTML = divs.join("");
console.log("done fast", Date.now() - ms);
js fiddle with comparison https://jsfiddle.net/aL7zqwy9/
The final solution, not ideal but
<html>
<body>
<div id='map'></div>
</body>
<style>
body {
margin: 0;
padding: 0;
/* Overflow appears when last row is added and shrinks the "width" */
overflow-y: hidden;
}
#map {
/* To exclude space between rows */
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.map-box {
width: 20px;
height: 20px;
border: 1px solid grey;
display: block;
margin: 0;
padding: 0;
/* So border thickness will not affect element size */
box-sizing: border-box;
}
</style>
<script>
const cellSize = 20; // px
const wh = window.innerHeight;
const ww = window.innerWidth;
// not always divisible by cell size without a remainder
const columnsCount = Math.floor(ww / cellSize);
const rowsCount = Math.floor(wh / cellSize);
const cellsCount = columnsCount * rowsCount;
console.log(`wh: ${wh}, ww: ${ww}, cols: ${columnsCount}, rows: ${rowsCount}`);
const divs = [];
for (let i = 0; i < cellsCount; i++) {
divs.push(`<div class='map-box' id='box${i}'></div>`);
}
document.getElementById("map").innerHTML = divs.join("");
</script>
</html>
I want to find the position of a circle that's following the mouse in two boxes
and the position of the circle when it's out of them. In addition when it (the circle) goes to red box the circle color changes to black, when it goes to red box it's color changes to red and when it's over neither of them it's blue.
I have included the picture here.
window.addEventListener("mousemove", function(e) {
let x = e.clientX;
let y = e.clientY;
let mouse = "Mouse : " + x + " " + y;
document.getElementById("mouseText").innerText = mouse;
let circle = document.getElementById("circleText");
let newX = e.clientX + 5;
let newY = e.clientY + 5;
let newCircle = "circle : " + newX + " " + newY;
document.getElementById("circleText").innerText = newCircle;
let circle2 = document.getElementById("circle");
circle2.style.marginTop = `${newY}px`;
circle2.style.marginLeft = `${newX}px`;
});
function onMousemove(e) {
var m_posx = 0,
m_posy = 0,
e_posx = 0,
e_posy = 0,
obj = this;
//get mouse position on document crossbrowser
if (!e) {
e = window.event;
}
if (e.pageX || e.pageY) {
m_posx = e.pageX;
m_posy = e.pageY;
} else if (e.clientX || e.clientY) {
m_posx =
e.clientX +
document.body.scrollLeft +
document.documentElement.scrollLeft;
m_posy =
e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
//get parent element position in document
if (obj.offsetParent) {
do {
e_posx += obj.offsetLeft;
e_posy += obj.offsetTop;
} while ((obj = obj.offsetParent));
}
// mouse position minus elm position is mouseposition relative to element:
dbg.innerHTML =
" X Position: " + (m_posx - e_posx) + " Y Position: " + (m_posy - e_posy);
}
html {
position: relative;
}
#circle {
width: 15px;
height: 15px;
background-color: blue;
border-radius: 50px;
position: absolute;
}
#row {
display: flex;
margin: 0 200px;
}
#blackShape {
position: relative;
width: 250px;
height: 250px;
background-color: black;
margin-top: 125px;
margin-left: 300px;
right: 180px;
}
#redCircle {
position: absolute;
width: 25px;
height: 25px;
background-color: red;
border-radius: 50px;
top: 50%;
left: 45%;
}
#redShape {
position: relative;
width: 250px;
height: 250px;
background-color: red;
margin-top: 125px;
margin-right: 150px;
}
#blackCircle {
position: absolute;
width: 25px;
height: 25px;
background-color: black;
border-radius: 50px;
top: 50%;
left: 45%;
}
<div id="mouseText"></div>
<div id="circleText"></div>
<div id="circle"></div>
<div id="dbg"></div>
<div id="row">
<div id="blackShape">
<div id="redCircle"></div>
</div>
<div id="redShape">
<div id="blackCircle"></div>
</div>
</div>
This script adjusts the position and size of the elements and listens when the blue circle will fall in these areas. When it leaves the area, the color style returns to its original state.
Example when the blue dot is in the region:
After resizing the "Run code snippet" screen, it may not work correctly. Please copy the code and try it.
var pos = 5; //<-- Circle position
var csz = 15; //<-- Circle size
var c = document.getElementById('circle');
window.onload = window.onresize = elPositions;
function elPositions() {
blc = document.getElementById('blackShape');
blcH = blc.offsetHeight;
blcW = blc.offsetWidth;
blcT = blc.offsetTop;
blcL = blc.offsetLeft;
red = document.getElementById('redShape');
redH = red.offsetHeight;
redW = red.offsetWidth;
redT = red.offsetTop;
redL = red.offsetLeft;
}
function changeColor(y, x) {
if (redT - pos < y && redT + redH - pos - csz > y && redL - pos < x && redL + redW - pos - csz > x) {
c.style.backgroundColor = 'black';
}
else if (blcT - pos < y && blcT + blcH - pos - csz > y && blcL - pos < x && blcL + blcW - pos - csz > x) {
c.style.backgroundColor = 'red';
}
else {
c.style.backgroundColor = '';
}
}
////////////////////////////////////////////////
window.addEventListener("mousemove", function (e) {
let x = e.clientX;
let y = e.clientY;
let mouse = "Mouse : " + x + " " + y;
document.getElementById("mouseText").innerText = mouse;
let circle = document.getElementById("circleText");
let newX = e.clientX + pos;
let newY = e.clientY + pos;
let newCircle = "circle : " + newX + " " + newY;
document.getElementById("circleText").innerText = newCircle;
let circle2 = document.getElementById("circle");
circle2.style.marginTop = newY + 'px';
circle2.style.marginLeft = newX + 'px';
changeColor(newY, newX); //<-- New Line
});
function onMousemove(e) {
var m_posx = 0,
m_posy = 0,
e_posx = 0,
e_posy = 0,
obj = this;
//get mouse position on document crossbrowser
if (!e) {
e = window.event;
}
if (e.pageX || e.pageY) {
m_posx = e.pageX;
m_posy = e.pageY;
}
else if (e.clientX || e.clientY) {
m_posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
m_posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
//get parent element position in document
if (obj.offsetParent) {
do {
e_posx += obj.offsetLeft;
e_posy += obj.offsetTop;
}
while ((obj = obj.offsetParent));
}
// mouse position minus elm position is mouseposition relative to element:
dbg.innerHTML = " X Position: " + (m_posx - e_posx) + " Y Position: " + (m_posy - e_posy);
}
html {
position: relative;
}
#circle {
width: 15px;
height: 15px;
background-color: blue;
border-radius: 50px;
position: absolute;
z-index: 1; /*<-- New Line*/
}
#row {
display: flex;
margin: 0 200px;
}
#blackShape {
position: relative;
width: 250px;
height: 250px;
background-color: black;
margin-top: 125px;
margin-left: 300px;
right: 180px;
}
#redCircle {
position: absolute;
width: 25px;
height: 25px;
background-color: red;
border-radius: 50px;
top: 50%;
left: 45%;
}
#redShape {
position: relative;
width: 250px;
height: 250px;
background-color: red;
margin-top: 125px;
margin-right: 150px;
}
#blackCircle {
position: absolute;
width: 25px;
height: 25px;
background-color: black;
border-radius: 50px;
top: 50%;
left: 45%;
}
<div id="mouseText"></div>
<div id="circleText"></div>
<div id="circle"></div>
<div id="dbg"></div>
<div id="row">
<div id="blackShape">
<div id="redCircle"></div>
</div>
<div id="redShape">
<div id="blackCircle"></div>
</div>
</div>
Example when the mouse cursor is in the region:
document.getElementById('blackShape').addEventListener("mouseover", getColor);
document.getElementById('blackShape').addEventListener("mouseout", retColor);
document.getElementById('redShape').addEventListener("mouseover", getColor);
document.getElementById('redShape').addEventListener("mouseout", retColor);
function getColor() {
var x = this.id;
var c = document.getElementById('circle');
if(x === 'redShape') {
c.style.backgroundColor = 'black'
}
else if (x === 'blackShape') {
c.style.backgroundColor = 'red'
}
}
function retColor() {
var c = document.getElementById('circle');
c.style.backgroundColor = '';
}
////////////////////////////////////////////////
window.addEventListener("mousemove", function (e) {
let x = e.clientX;
let y = e.clientY;
let mouse = "Mouse : " + x + " " + y;
document.getElementById("mouseText").innerText = mouse;
let circle = document.getElementById("circleText");
let newX = e.clientX + 5;
let newY = e.clientY + 5;
let newCircle = "circle : " + newX + " " + newY;
document.getElementById("circleText").innerText = newCircle;
let circle2 = document.getElementById("circle");
circle2.style.marginTop = newY + 'px';
circle2.style.marginLeft = newX + 'px';
});
function onMousemove(e) {
var m_posx = 0,
m_posy = 0,
e_posx = 0,
e_posy = 0,
obj = this;
//get mouse position on document crossbrowser
if (!e) {
e = window.event;
}
if (e.pageX || e.pageY) {
m_posx = e.pageX;
m_posy = e.pageY;
}
else if (e.clientX || e.clientY) {
m_posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
m_posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
//get parent element position in document
if (obj.offsetParent) {
do {
e_posx += obj.offsetLeft;
e_posy += obj.offsetTop;
}
while ((obj = obj.offsetParent));
}
// mouse position minus elm position is mouseposition relative to element:
dbg.innerHTML = " X Position: " + (m_posx - e_posx) + " Y Position: " + (m_posy - e_posy);
}
html {
position: relative;
}
#circle {
width: 15px;
height: 15px;
background-color: blue;
border-radius: 50px;
position: absolute;
z-index: 1; /*<-- New Line*/
}
#row {
display: flex;
margin: 0 200px;
}
#blackShape {
position: relative;
width: 250px;
height: 250px;
background-color: black;
margin-top: 125px;
margin-left: 300px;
right: 180px;
}
#redCircle {
position: absolute;
width: 25px;
height: 25px;
background-color: red;
border-radius: 50px;
top: 50%;
left: 45%;
}
#redShape {
position: relative;
width: 250px;
height: 250px;
background-color: red;
margin-top: 125px;
margin-right: 150px;
}
#blackCircle {
position: absolute;
width: 25px;
height: 25px;
background-color: black;
border-radius: 50px;
top: 50%;
left: 45%;
}
<div id="mouseText"></div>
<div id="circleText"></div>
<div id="circle"></div>
<div id="dbg"></div>
<div id="row">
<div id="blackShape">
<div id="redCircle"></div>
</div>
<div id="redShape">
<div id="blackCircle"></div>
</div>
</div>
let screenLog = document.querySelector('#screen-log');
document.addEventListener('mousemove', logKey);
var imgHgt = document.getElementById('box');
function logKey(e) {
var d = document.getElementById('TextHidden');
d.style.position = "absolute";
d.style.left = e.clientX +'px';
d.style.top = e.clientY +'px';
screenLog.innerHTML = `${e.clientX}, ${e.clientY}` + "<br>Image Height = " + imgHgt.offsetHeight + "<br>Image Width = " + imgHgt.offsetWidth;
}
#box { width: 40%; display: block; position: absolute; overflow: hidden; }
.image { display: block; width: 100%; z-index: 1; }
#TextHidden { display: none; color: red; font-size; 20px; z-index: 10; } #box:hover #TextHidden { display: block; }
#screen-log { z-index: 11; }
<div id="box">
<img src="https://res.cloudinary.com/vaqar/image/upload/v1499826226/DSC_0361_y3mv4r.jpg" class="image"></p> </img>
<div id="TextHidden">Hovering<p id="screen-log"></p></div>
</div>
I am trying to move comments on top of the the mouse pointer, but having no success.
Change your left and top position pixels like,
d.style.left = (e.clientX - 50) +'px';
d.style.top = (e.clientY - 100) +'px';
And the snippet as follows,
let screenLog = document.querySelector('#screen-log');
document.addEventListener('mousemove', logKey);
var imgHgt = document.getElementById('box');
function logKey(e) {
var d = document.getElementById('TextHidden');
d.style.position = "absolute";
d.style.left = (e.clientX - 50) +'px';
d.style.top = (e.clientY - 100) +'px';
screenLog.innerHTML = `${e.clientX}, ${e.clientY}` + "<br>Image Height = " + imgHgt.offsetHeight + "<br>Image Width = " + imgHgt.offsetWidth;
}
#box { width: 40%; display: block; position: absolute; overflow: hidden; }
.image { display: block; width: 100%; z-index: 1; }
#TextHidden { display: none; color: red; font-size; 20px; z-index: 10; } #box:hover #TextHidden { display: block; }
#screen-log { z-index: 11; }
<div id="box">
<img src="https://res.cloudinary.com/vaqar/image/upload/v1499826226/DSC_0361_y3mv4r.jpg" class="image"></p> </img>
<div id="TextHidden">Hovering<p id="screen-log"></p></div>
</div>
Your approach is working in principle, but you don't see the moving text because it is currently hidden. Note that I commented out the overflow: hidden and display: none properties in your stylesheet.
let screenLog = document.querySelector('#screen-log');
document.addEventListener('mousemove', logKey);
var imgHgt = document.getElementById('box');
function logKey(e) {
var d = document.getElementById('TextHidden');
d.style.position = "absolute";
d.style.left = e.clientX + 'px';
d.style.top = e.clientY + 'px';
screenLog.innerHTML = `${e.clientX}, ${e.clientY}` + "<br>Image Height = " + imgHgt.offsetHeight + "<br>Image Width = " + imgHgt.offsetWidth;
}
#box {
width: 40%;
display: block;
position: absolute;
#overflow: hidden;
}
.image {
display: block;
width: 100%;
z-index: 1;
}
#TextHidden {
#display: none;
color: red;
font-size: 20px;
z-index: 10;
}
#box:hover #TextHidden {
display: block;
}
#screen-log {
z-index: 11;
}
<div id="box">
<div id="TextHidden">
<p id="screen-log"></p>
</div>
</div>
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.
I am using following link to show menus
http://codepen.io/anon/pen/dWdJbV
But I want to show them only in upper half circle. Even menu count changes it should use only upper half circle.
Js code
var items = document.querySelectorAll('.circle a');
for(var i = 0, l = items.length; i < l; i++) {
items[i].style.left = (50 - 35*Math.cos(-0.5 * Math.PI - 2*(2/l)*i*Math.PI)).toFixed(4) + "%";
items[i].style.top = (50 + 35*Math.sin(-0.5 * Math.PI - 2*(5/l)*i*Math.PI)).toFixed(4) + "%";
}
document.querySelector('.menu-button').onclick = function(e) {
e.preventDefault(); document.querySelector('.circle').classList.toggle('open');
}
I tried by changing values sin sin and cos but not getting required output
Here is the quick demo :
var isOn = false;
$('#menu-button').click(function() {
if(isOn) {
reset();
} else {
setPosition();
}
});
function setPosition() {
isOn = true;
var links = $('#menu-button a');
var radius = (links.length * links.width()) / 2;
var degree = Math.PI / links.length, angle = degree / 2;
links.each(function() {
var x = Math.round(radius * Math.cos(angle));
var y = Math.round(radius * Math.sin(angle));
$(this).css({
left: x + 'px',
top: -y + 'px'
});
angle += degree;
});
}
function reset() {
$('#menu-button a').css({
left: 0 + 'px',
top: 0 + 'px'
});
isOn = false;
}
body {
margin: 0;
background: #39D;
}
#menu-button:before {
position: absolute;
top: 0; left: 0;
width: 50px;
height: 50px;
background: #dde;
cursor: pointer;
text-align: center;
line-height: 50px;
color: #444;
border-radius:50%;
content:"\f0c9"; font: normal normal normal 14px/1 FontAwesome;
font-size:26px;
}
#menu-button {
position: absolute;
margin: auto;
top: 150px; left: 0; right: 0;
width: 50px;
height: 50px;
cursor: pointer;
text-align: center;
}
#menu-button > a {
position: absolute;
display: block;
width: 50px;
height: 50px;
-webkit-transition: top .5s, left .5s;
-moz-transition: top .5s, left .5s;
text-align: center;
text-decoration: none;
line-height: 50px;
color: #EBEAE8;
z-index: -1;
border-radius:50%;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Demo by http://creative-punch.net -->
<div id="menu-button" class="entypo-menu">
</div>
I made this changes in you example for displaying items only in top part of circle:
var items = document.querySelectorAll('.circle a');
var angle = 0;
var step = (Math.PI) / items.length;
for(var i = 0, l = items.length; i < l; i++) {
items[i].style.left = (50 - 35*Math.cos(angle).toFixed(4)) + "%";
items[i].style.top = (50 + 35* (-Math.abs(Math.sin(angle)))).toFixed(4) + "%";
angle += step;
}
So you need only angles from 0 to 180 degrees. That's why i use (-Math.abs(Math.sin(angle)))