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.
Related
I have a stormTrooper characters randomly placed around my circle called deathStar. I am trying to make my stormTroopers place in the location that my mouse clicks once they have already been clicked. But instead they are placing in random locations. I'm still having problems grasping the concept of getBoundingClientRect() and offset. I thought adding them together and subtracting from mouseClick would be the solution. I'm also open to any other advice for this project. The area I'm having problems with is the mouseDown event listener.
//Global variables
let deathStar = document.querySelector(".deathStar")
let counter = 0;
let darthVader = document.querySelector(".darthVader");
let vaderX = darthVader.offsetLeft;
let vaderY = darthVader.offsetTop;
//Death Star information
const x1 = window.scrollX + deathStar.getBoundingClientRect().left; // top left X
const y1 = window.scrollY + deathStar.getBoundingClientRect().top; // top left Y
const x2 = window.scrollY + deathStar.getBoundingClientRect().right; // bottom right X
const y2 = window.scrollY + deathStar.getBoundingClientRect().bottom; // top right Y
let midPointX = (x2 + x1) / 2;
let midPointY = (y2 + y1) / 2;
let radius = x2 - midPointX - 10;
//Create a storm trooper
function createStormTrooper(){
colorArray = ['blue', 'green', 'orange', 'yellow', 'white', 'red','purple', 'pink'];
counter++;
//create each div
let stormTrooper = document.createElement('div');
let body = document.createElement('div');
let gun = document.createElement('div');
let head = document.createElement('div');
let legSplit = document.createElement('div');
//append div to proper div
deathStar.append(stormTrooper);
stormTrooper.append(body);
body.append(gun);
body.append(head);
body.append(legSplit);
//add classes
stormTrooper.classList.add("trooper",'stormTrooperPart' + counter, "stormTrooper");
body.classList.add("trooper", 'stormTrooperPart' + counter, "body");
gun.classList.add("trooper", 'stormTrooperPart' + counter, "gun");
head.classList.add("trooper", 'stormTrooperPart' + counter, 'head');
legSplit.classList.add("trooper", 'stormTrooperPart' + counter, "legSplit");
let randomColor = Math.floor(Math.random()*8);
body.style.backgroundColor = colorArray[randomColor];
placeInsideDeathStar(stormTrooper);
}
//Places a trooper in a random spot inside the death star
function placeInsideDeathStar(stormTrooper){
let theta = Math.random() * Math.PI * 2;
let r = (Math.sqrt(Math.random()) * radius);
let yRandom = r * Math.sin(theta);
let xRandom = r * Math.cos(theta);
stormTrooper.style.transform = "translate(" + (xRandom) + "px," + (yRandom) + "px)";
}
//Create Troopers
for(let i = 0; i < 10;i++ ){
createStormTrooper();
}
let targetFound = false;
let stormTrooper;
//Storm Trooper placing and removing
document.addEventListener('mousedown', (e) => {
//variable to check if type stormtrooper
let typeTrooper = e.target.className.split(" ")[0];
//If type storm trooper of already have a target
if(typeTrooper == "trooper" || targetFound == true){
//if no stormTrooper found yet
if(targetFound == false){
stormTrooperChecker = document.querySelector("." + e.target.className.split(" ")[1]);
targetFound = true;
}
//if stormTrooper found
else{
//Distance to move stormTrooper
var xposition = (e.clientX - stormTrooperChecker.getBoundingClientRect().left + stormTrooperChecker.offsetLeft);
var yposition = (e.clientY - stormTrooperChecker.getBoundingClientRect().top + stormTrooperChecker.offsetTop);
//Move Storm Trooper
stormTrooperChecker.style.transform = "translate("+ (xposition)+ "px," + yposition + "px)";
//Check if outside of death star
if(pTheoremAB(stormTrooperChecker.offsetTop, stormTrooperChecker.offsetLeft) > pTheoremC(radius) || pTheoremAB(stormTrooperChecker.offsetTop, stormTrooperChecker.offsetLeft) < -pTheoremC(radius)){
stormTrooperChecker.classList.add("explosion")
stormTrooperChecker.innerHTML = "";
setTimeout(() => stormTrooperChecker.remove(), 1000);
}
//reset targetFound
targetFound = false;
}
//stormTrooperChecker.remove();
}
});
//P theorem
function pTheoremAB(a,b){
return ((a * a) + (b * b));
}
function pTheoremC(c){
return c * c;
}
function wDown(){
vaderY -= 2;
darthVader.style.top = vaderY + "px";
if(-pTheoremAB((vaderX - 345),(vaderY - 335)) <= -pTheoremC(radius)){
vaderY +=2
}
}
function sDown(){
vaderY += 2;
darthVader.style.top = vaderY + "px";
if(pTheoremAB((vaderX - 345),(vaderY - 335)) >= pTheoremC(radius)){
vaderY -= 2;
}
}
function aDown(){
vaderX -= 2;
darthVader.style.left = vaderX + "px";
if(-pTheoremAB((vaderX - 345),(vaderY - 335)) <= -pTheoremC(radius)){
vaderX += 2;
}
}
function dDown(){
vaderX += 2;
darthVader.style.left = vaderX + "px";
if(pTheoremAB((vaderX - 345),(vaderY - 335)) >= pTheoremC(radius)){
vaderX -= 2;
}
}
const controller = {
'w': {pressed: false},
'a': {pressed: false},
's': {pressed: false},
'd': {pressed: false},
}
document.addEventListener("keydown", (e) => {
if(controller[e.key]){
controller[e.key].pressed = true
}
if(controller['w'].pressed){
wDown();
}
if(controller['a'].pressed){
aDown();
}
if(controller['s'].pressed){
sDown();
}
if(controller['d'].pressed){
dDown();
}
})
document.addEventListener("keyup", (e) => {
if(controller[e.key]){
controller[e.key].pressed = false
}
})
body{
border: 0;
background: black;
display: flex;
align-items: center;
justify-content: center;
}
.deathStar {
position: relative;
display:flex;
height: 700px;
width: 700px;
border-radius: 50%;
background-color: darkgrey;
top: 50%;
align-items: center;
justify-content: center;
}
.hole{
display: flex;
height: 100px;
width: 50px;
border-radius: 50%;
background-color: gray;
top: 50%;
transform: translateX(-60PX);
}
.stormTrooper{
display: flex;
position: absolute;
z-index: 2;
}
.body{
display: flex;
position: relative;
height: 30px;
width: 10px;
z-index: 2;
}
.head{
display: flex;
position: absolute;
height: 7px;
width: 7px;
transform: translate(0, 1px);
background-color: black;
}
.gun{
position: absolute;
display: flex;
height: 2px;
width: 10px;
background-color: black;
transform: translate(-9px, 10px)
}
.legSplit{
position: absolute;
display: flex;
width: 1px;
height: 8px;
background-color: black;
transform: translate(4px, 22px);
}
.darthVader{
display: flex;
position: absolute;
height: 30px;
width: 10px;
z-index: 3;
background-color: black;
}
.explosion{
position: absolute;
display: flex;
height: 0px;
width: 0px;
border-radius: 50%;
background-color: red;
transform: translate(80px, 80px);
animation-duration: 1s;
animation-name: move;
}
#keyframes move {
25% {
width: 10px;
height: 10px;
}
50% {
width: 20px;
height: 20px;
}
75% {
width: 30px;
height: 30px;
}
100% {
width: 40px;
height: 40px;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<div class="deathStar" id="deathStar">
<div class="darthVader"></div>
</div>
<div class="hole"></div>
<script src="main.js"></script>
</body>
</html>
The translate positioning is relative to the Death Star element's center, so I updated that.
translate does not affect offsetTop/Left, so your "in Death Star" logic was failing. I fixed that.
Also, you do not need to adjust for the scroll position (comes into effect only when scrolled). I fixed that.
Lastly, I had to put in some code in the handler to calculate the new midpoint of the Death Star element, as you only calculated it on initialization (it should be recalcuated on every use).
//Global variables
let deathStar = document.querySelector(".deathStar")
let counter = 0;
let darthVader = document.querySelector(".darthVader");
let vaderX = darthVader.offsetLeft;
let vaderY = darthVader.offsetTop;
//Death Star information
const x1 = deathStar.getBoundingClientRect().left; // top left X
const y1 = deathStar.getBoundingClientRect().top; // top left Y
const x2 = deathStar.getBoundingClientRect().right; // bottom right X
const y2 = deathStar.getBoundingClientRect().bottom; // top right Y
let midPointX = (x2 + x1) / 2;
let midPointY = (y2 + y1) / 2;
let radius = x2 - midPointX - 10;
//Create a storm trooper
function createStormTrooper(){
colorArray = ['blue', 'green', 'orange', 'yellow', 'white', 'red','purple', 'pink'];
counter++;
//create each div
let stormTrooper = document.createElement('div');
let body = document.createElement('div');
let gun = document.createElement('div');
let head = document.createElement('div');
let legSplit = document.createElement('div');
//append div to proper div
deathStar.append(stormTrooper);
stormTrooper.append(body);
body.append(gun);
body.append(head);
body.append(legSplit);
//add classes
stormTrooper.classList.add("trooper",'stormTrooperPart' + counter, "stormTrooper");
body.classList.add("trooper", 'stormTrooperPart' + counter, "body");
gun.classList.add("trooper", 'stormTrooperPart' + counter, "gun");
head.classList.add("trooper", 'stormTrooperPart' + counter, 'head');
legSplit.classList.add("trooper", 'stormTrooperPart' + counter, "legSplit");
let randomColor = Math.floor(Math.random()*8);
body.style.backgroundColor = colorArray[randomColor];
placeInsideDeathStar(stormTrooper);
}
//Places a trooper in a random spot inside the death star
function placeInsideDeathStar(stormTrooper){
let theta = Math.random() * Math.PI * 2;
let r = (Math.sqrt(Math.random()) * radius);
let yRandom = r * Math.sin(theta);
let xRandom = r * Math.cos(theta);
stormTrooper.style.transform = "translate(" + (xRandom) + "px," + (yRandom) + "px)";
}
//Create Troopers
for(let i = 0; i < 10;i++ ){
createStormTrooper();
}
let targetFound = false;
let stormTrooper;
//Storm Trooper placing and removing
document.addEventListener('mousedown', (e) => {
//variable to check if type stormtrooper
let typeTrooper = e.target.className.split(" ")[0];
//If type storm trooper of already have a target
if(typeTrooper == "trooper" || targetFound == true){
//if no stormTrooper found yet
if(targetFound == false){
stormTrooperChecker = document.querySelector("." + e.target.className.split(" ")[1]);
targetFound = true;
}
//if stormTrooper found
else{
//Distance to move stormTrooper
const x1 = deathStar.getBoundingClientRect().left; // top left X
const y1 = deathStar.getBoundingClientRect().top; // top left Y
const x2 = deathStar.getBoundingClientRect().right; // bottom right X
const y2 = deathStar.getBoundingClientRect().bottom; // top right Y
let midPointX = (x2 + x1) / 2;
let midPointY = (y2 + y1) / 2;
var xposition = (e.clientX - midPointX);
var yposition = (e.clientY - midPointY);
//Move Storm Trooper
stormTrooperChecker.style.transform = "translate("+ (xposition)+ "px," + yposition + "px)";
//Check if outside of death star
if(pTheoremAB(yposition, xposition) > pTheoremC(radius) || pTheoremAB(yposition, xposition) < -pTheoremC(radius)){
stormTrooperChecker.classList.add("explosion")
stormTrooperChecker.innerHTML = "";
setTimeout(() => stormTrooperChecker.remove(), 1000);
}
//reset targetFound
targetFound = false;
}
//stormTrooperChecker.remove();
}
});
//P theorem
function pTheoremAB(a,b){
return ((a * a) + (b * b));
}
function pTheoremC(c){
return c * c;
}
function wDown(){
vaderY -= 2;
darthVader.style.top = vaderY + "px";
if(-pTheoremAB((vaderX - 345),(vaderY - 335)) <= -pTheoremC(radius)){
vaderY +=2
}
}
function sDown(){
vaderY += 2;
darthVader.style.top = vaderY + "px";
if(pTheoremAB((vaderX - 345),(vaderY - 335)) >= pTheoremC(radius)){
vaderY -= 2;
}
}
function aDown(){
vaderX -= 2;
darthVader.style.left = vaderX + "px";
if(-pTheoremAB((vaderX - 345),(vaderY - 335)) <= -pTheoremC(radius)){
vaderX += 2;
}
}
function dDown(){
vaderX += 2;
darthVader.style.left = vaderX + "px";
if(pTheoremAB((vaderX - 345),(vaderY - 335)) >= pTheoremC(radius)){
vaderX -= 2;
}
}
const controller = {
'w': {pressed: false},
'a': {pressed: false},
's': {pressed: false},
'd': {pressed: false},
}
document.addEventListener("keydown", (e) => {
if(controller[e.key]){
controller[e.key].pressed = true
}
if(controller['w'].pressed){
wDown();
}
if(controller['a'].pressed){
aDown();
}
if(controller['s'].pressed){
sDown();
}
if(controller['d'].pressed){
dDown();
}
})
document.addEventListener("keyup", (e) => {
if(controller[e.key]){
controller[e.key].pressed = false
}
})
body{
border: 0;
background: black;
display: flex;
align-items: center;
justify-content: center;
}
.deathStar {
position: relative;
display:flex;
height: 700px;
width: 700px;
border-radius: 50%;
background-color: darkgrey;
top: 50%;
align-items: center;
justify-content: center;
}
.hole{
display: flex;
height: 100px;
width: 50px;
border-radius: 50%;
background-color: gray;
top: 50%;
transform: translateX(-60PX);
}
.stormTrooper{
display: flex;
position: absolute;
z-index: 2;
}
.body{
display: flex;
position: relative;
height: 30px;
width: 10px;
z-index: 2;
}
.head{
display: flex;
position: absolute;
height: 7px;
width: 7px;
transform: translate(0, 1px);
background-color: black;
}
.gun{
position: absolute;
display: flex;
height: 2px;
width: 10px;
background-color: black;
transform: translate(-9px, 10px)
}
.legSplit{
position: absolute;
display: flex;
width: 1px;
height: 8px;
background-color: black;
transform: translate(4px, 22px);
}
.darthVader{
display: flex;
position: absolute;
height: 30px;
width: 10px;
z-index: 3;
background-color: black;
}
.explosion{
position: absolute;
display: flex;
height: 0px;
width: 0px;
border-radius: 50%;
background-color: red;
transform: translate(80px, 80px);
animation-duration: 1s;
animation-name: move;
}
#keyframes move {
25% {
width: 10px;
height: 10px;
}
50% {
width: 20px;
height: 20px;
}
75% {
width: 30px;
height: 30px;
}
100% {
width: 40px;
height: 40px;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<div class="deathStar" id="deathStar">
<div class="darthVader"></div>
</div>
<div class="hole"></div>
<script src="main.js"></script>
</body>
</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>
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>
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)))
I'm looking to create a horizontal chart with thresholds at certain percentages- if you've ever used Battle.Net, kind of similar to their download bar:
Blizzard Download Bar
I'm sure there's a name for it, I just don't know what it is...
Thanks!
I made this just in case it helps. Have 'fun'.
You can edit the little threshold pointer so they look stylish with css. But yea that all depends on what you want to do
// Btw, I'm a big fan of the canvas element that's why I'm doing this. Otherwise, you can also use a progress bar
var c = document.getElementById('progressBar'),
dt = document.getElementById('download-text'),
btn = document.querySelector('button'),
p2 = document.querySelector('progress');
var cx = c.getContext('2d');
var counter = 0,
loop;
btn.onclick = function() {
btn.innerText = 'N';
var timeInter = setInterval(function(){
btn.innerText += 'o';
},70);
setTimeout(function(){
clearTimeout(timeInter);
btn.hidden = true;
p2.hidden = false;
progress2();
},1000);
}
var loop2 = '',
counter2 = 0;
function progress2() {
counter2++;
var percentage = (counter2 / 17).toFixed(2);
if (percentage - 0 >= 100) {
percentage = 100;
}
p2.value = percentage - 0 +'';
if (percentage - 0 > 100) {
cancelAnimationFrame(loop2);
} else {
loop2 = requestAnimationFrame(progress);
}
//This is me failing to animate the progress bar
}
function progress() {
counter++;
var percentage = (counter / 17).toFixed(2);
if (percentage >= 100) {
percentage = 100+'.00';
}
dt.innerText = "Download: " + percentage + "%";
cx.fillStyle = '#00FFFF';
cx.fillRect(0, 0, c.width * percentage / 100, c.height);
cx.strokeStyle = '#ccc';
cx.beginPath();
cx.moveTo(100, 70);
cx.lineTo(100, 0);
cx.stroke();
cx.moveTo(300, 70);
cx.lineTo(300, 0);
cx.stroke();
if (percentage - 0 > 100) {
cancelAnimationFrame(loop);
} else {
loop = requestAnimationFrame(progress);
}
}
progress();
#progressBar {
border: 1px solid grey;
z-index: -10;
}
#progressBar,
#download-text,
#playable,
#optimal,
button,
progress{
position: absolute;
top: 0px;
left: 0px;
}
button,
progress{
top:200px;
}
#download-text {
height: 70px;
padding-top: 25px;
padding-left: 7px;
font-family: sans-serif;
background-color: transparent;
}
#playable,
#optimal {
width: 100px;
height: 43px;
text-align: center;
padding-top: 20px;
font-family: sans-serif;
font-weight: bolder;
}
#playable {
background-color: yellow;
position: absolute;
top: 72px;
left: 100px;
}
#optimal {
background-color: green;
position: absolute;
top: 72px;
left: 300px;
}
<div>
<canvas id="progressBar" width="430px" height="70px"></canvas>
<div id="download-text">Hello</div>
</div>
<div id="playable">PLAYABLE</div>
<div id="optimal">OPTIMAL</div>
<button type="button">Please don't press me just stick to canvas</button>
<progress max="100" hidden="true"></progress>