Detect circle overlap - javascript

I'm trying to trigger a hover function when ANY part of a fake cursor hovers over a circle.
I have played around with the X and Y positions of the fake cursor, but that only works well for one direction. Is there a smarter way to go about this?
Here's a pen showing what I'm trying to do: trigger a hover function when any part of the pink circle (fake cursor) touches the green circle.
https://codepen.io/Jessels/pen/LYPxmqx
$('.cursor')
.eq(0)
.css({
left: e.pageX - 20,
top: e.pageY - 5
});

You can add this to your mousemove event.
Here we are finding the intersections and if the "cursor" is within the circle.
Here is where I found this code: Fiddle
Here is my CodePen Demo
$(document).mousemove(function(e) {
$('.cursor').eq(0).css({
left: e.pageX - 25,
top: e.pageY - 20
});
// circles
var c1 = $('.cursor');
var c2 = $('.circle');
// radius
var d1 = c1.outerWidth(true) / 2;
var d2 = c2.outerWidth(true) / 2;
// center of first circle
var x1 = c1.offset().left + c1.width() / 2;
var y1 = c1.offset().top + c1.height() / 2;
// center of second circle
var x2 = c2.offset().left + c2.width() / 2;
var y2 = c2.offset().top + c2.height() / 2;
function calc() {
var a = d2;
var b = d1;
var c = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
var d = (b * b + c * c - a * a) / (2 * c);
var h = Math.sqrt((b * b) - (d * d));
if (d < 0 || $.isNumeric(h)) {
c2.css('background', 'blue');
} else {
c2.css('background', 'green');
}
}
calc();
});
.cursor {
height: 50px;
width: 50px;
border-radius: 50%;
position: absolute;
pointer-events: none;
z-index: 999;
background: hotpink;
}
.circle {
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 200px;
height: 200px;
background: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="cursor"></div>
<div class="circle">
<div class="inter1 inter"></div>
<div class="inter2 inter"></div>
<div>

Related

Why does my animation teleport to the bottom left at the end

I am trying to make an animation of a circle bouncing around in a square. Currently when ever the animation reaches the last section of the script it warps to the bottom left. If any one knows why it is warping or a simpler way to write this animation let me know. Thank you for your time.
function myMove() {
var elem = document.getElementById("color");
var pos = 286;
var num = 0;
var id = setInterval(frame, 10);
function frame() {
if (num >= 183 && num < 512) {
pos--;
num++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
} else if (pos < 469 && num < 183) {
pos++;
num++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
} else if (pos == 140 || num >= 512 && num < 918) {
pos++;
num++;
elem.style.top = pos / 2 + 'px';
elem.style.left = pos + 'px';
} else if (pos <= 140 || num >= 918 && num < 929) {
pos--;
num++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
.square {
height: 500px;
width: 500px;
background-color: white;
border-style: solid;
border-width: 2px;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.circle {
height: 100px;
width: 100px;
background-color: #555;
border-radius: 50%;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<p>
<button onclick="myMove()">Click Me</button>
</p>
<div class="square"></div>
<div class="circle" id="color"></div>
This is how I would do it:
I commented my code with the steps I took.
I moved the circle into the square and changed the position to be relative to let css handle the rest.
var timer;
function myMove() {
var circle = document.getElementById("circle");
var square = document.getElementById("square");
var posx = 0, posy = 0;
var squarew = square.clientWidth, squareh = square.clientHeight;
// moved timer to outer scope to clear it evertime the button is clicked
if (timer) clearInterval(timer);
timer = setInterval(frame, 10);
// made the circle configurable to be able to change the size of it
var circleRadius = 50;
circle.style.height = circleRadius * 2 + 'px';
circle.style.width = circleRadius * 2 + 'px';
// this is how fast the ball is going to move (in pixels)
var distance = 10;
// fire off in a random direction
var randomDirection = Math.random(0, 100);
// get the velocity in the x direction and y direction
var vy = distance * Math.sin(randomDirection);
var vx = distance * Math.cos(randomDirection);
function frame() {
// if i hit any edge of the box
if (posy + vy <= 0) {
// reverse the direction
vy *= -1;
}
if (posy + vy >= squareh - circleRadius * 2) {
// reverse the direction
vy *= -1;
}
if (posx + vy <= 0) {
// reverse the direction
vx *= -1;
}
if (posx + vy >= squarew - circleRadius * 2) {
// reverse the direction
vx *= -1;
}
// keep track of the position
posx += vx;
posy += vy;
// apply it to the circle
circle.style.top = posy + 'px';
circle.style.left = posx + 'px';
}
}
#square {
height: 500px;
width: 500px;
background-color: white;
border-style: solid;
border-width: 2px;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#circle {
background-color: #555;
border-radius: 50%;
position: relative;
top: 0;
left: 0;
}
<p>
<button onclick="myMove()">Click Me</button>
</p>
<div id="square">
<div id="circle"></div>
</div>

sin and cos animations on a curved line with javascript and CSS

I am trying to use sin and cos to animate a CSS image to move on this shape. Can not make the CSS image to move on that curved bezier line.
Can someone assist on how to use sin or cos in so, if a CSS object added, it would move smoothly along such a line?
Here is the code that I tried to make the yellow circle to move on that line with sin and cos math in javascript.
Thanks
var field = document.getElementById("field");
var ball = document.getElementById("ball");
var ball2 = document.getElementById("ball2");
var maxX = field.clientWidth - ball.offsetWidth;
var maxY = field.clientHeight - ball.offsetHeight;
var duration = 5; // seconds
var gridSize = 50; // pixels
var start = null;
function step(timestamp) {
var progress, x, y, y2;
if (start === null)
start = timestamp;
progress = (timestamp - start) / duration / 1000; // percent
x = progress * maxX / gridSize; // x = ƒ(t)
y = 2 * Math.sin(x); // y = ƒ(x)
y2 = 2 * Math.cos(x);
ball.style.left = ball2.style.left = Math.min(maxX, gridSize * x)
+ "px";
ball.style.bottom = maxY / 2 + (gridSize * y) + "px";
ball2.style.bottom = maxY / 2 + (gridSize * y2) + "px";
if (progress >= 1)
start = null; // reset to start position
requestAnimationFrame(step);
}
requestAnimationFrame(step);
#field {
position: absolute;
height: 300px;
width: 300px;
z-index: 50;
top: 20px;
left: 20px;
}
#ball {
position: absolute;
left: 0;
bottom: 50%;
width: 40px;
background: yellow;
z-index: 5;
height: 40px;
border-radius: 200px;
}
#ball2 {
position: absolute;
left: 0;
bottom: 50%;
width: 20px;
height: 20px;
/*background: silver;*/
border-radius: 100px;
}
<div id="field">
<div id="ball"></div>
<div id="ball2"></div>
</div>
requestAnimationFrame calls the given function exactly ONCE
to animate, you need to call requestAnimationFrame within that given function, usually calling the function itself (though more complex animations may call something else, it doesn't matter)
The main point being, you need to call requestAnimationFrame for each frame you want to animate
var field = document.getElementById("field");
var ball = document.getElementById("ball");
var ball2 = document.getElementById("ball2");
var maxX = field.clientWidth - ball.offsetWidth;
var maxY = field.clientHeight - ball.offsetHeight;
var duration = 5; // seconds
var gridSize = 40; // pixels
var start = null;
function step(timestamp) {
var progress, x, y, y2;
if (start === null)
start = timestamp;
progress = (timestamp - start) / duration / 1000; // percent
x = progress * maxX / gridSize; // x = ƒ(t)
y = -2 * Math.cos(x); // y = ƒ(x)
y2 = 2 * Math.cos(x);
ball.style.left = ball2.style.left = Math.min(maxX, gridSize * x) +
"px";
ball.style.bottom = maxY / 2 + (gridSize * y) + "px";
ball2.style.bottom = maxY / 2 + (gridSize * y2) + "px";
if (progress >= 1)
start = null; // reset to start position
requestAnimationFrame(step);
}
requestAnimationFrame(step);
#field {
position: absolute;
height: 300px;
width: 300px;
z-index: 50;
top: 20px;
left: 20px;
}
#ball {
position: absolute;
left: 0;
bottom: 50%;
width: 40px;
background: yellow;
height: 40px;
border-radius: 200px;
}
#ball2 {
position: absolute;
left: 0;
bottom: 50%;
width: 20px;
height: 20px;
background: silver;
border-radius: 100px;
}
<div id="field">
<div id="ball"></div>
<div id="ball2"></div>
</div>

How to change radius of circles but keep pattern?

I found some code online to draw circles around a center circle. How do I change the radius of the smaller circles without affecting the layout (currently all the circles shift and are not centered around the large circle anymore).
This happens when I change the radius(width & height) in the css file. Changing the large circle radius also causes the whole group of circles to shift right or left (although they maintain their symmetry).
Here is my code:
var div = 360 / 6;
var radius = 150;
var parentdiv = document.getElementById('parentdiv');
var offsetToParentCenter = parseInt(parentdiv.offsetWidth / 2); //assumes parent is square
var offsetToChildCenter = 20;
var totalOffset = offsetToParentCenter - offsetToChildCenter;
for (var i = 1; i <= 6; ++i) {
var childdiv = document.createElement('div');
childdiv.className = 'div2';
childdiv.style.position = 'absolute';
var y = Math.sin((div * i) * (Math.PI / 180)) * radius;
var x = Math.cos((div * i) * (Math.PI / 180)) * radius;
childdiv.style.top = (y + totalOffset).toString() + "px";
childdiv.style.left = (x + totalOffset).toString() + "px";
parentdiv.appendChild(childdiv);
}
#parentdiv {
position: relative;
width: 150px;
height: 150px;
background-color: red;
border-radius: 150px;
margin: 150px;
}
.div2 {
position: absolute;
width: 40px;
height: 40px;
background-color: red;
border-radius: 100px;
}
<div id="parentdiv"></div>
I would also like to move the circles to the center of the screen but I am not sure how.
I am very new to html/css/js and any help would be greatly appreciated!
To illustrate my comment. border-radius is a CSS rule to round boxe's corners.
https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius
The border-radius CSS property rounds the corners of an element's outer border edge. You can set a single radius to make circular corners, or two radii to make elliptical corners.
to modify the size , you can do it from the css file too, about the position , there is two vars to update : radius and offsetToChildCenter
Demo
var div = 360 / 6;
var radius = 180;
var parentdiv = document.getElementById('parentdiv');
var offsetToParentCenter = parseInt(parentdiv.offsetWidth / 2); //assumes parent is square
var offsetToChildCenter = 40;
var totalOffset = offsetToParentCenter - offsetToChildCenter;
for (var i = 1; i <= 6; ++i) {
var childdiv = document.createElement('div');
childdiv.className = 'div2';
childdiv.style.position = 'absolute';
var y = Math.sin((div * i) * (Math.PI / 180)) * radius;
var x = Math.cos((div * i) * (Math.PI / 180)) * radius;
childdiv.style.top = (y + totalOffset).toString() + "px";
childdiv.style.left = (x + totalOffset).toString() + "px";
parentdiv.appendChild(childdiv);
}
html {
display: flex;
height: 100%;
}
body {
margin: auto;
}
#parentdiv {
position: relative;
width: 150px;
height: 150px;
background-color: red;
border-radius: 150px;
margin: 150px;
}
.div2 {
position: absolute;
width: 80px;
height: 80px;
background-color: red;
border-radius: 10px;
}
<div id="parentdiv"></div>
You can center the circles by applying Flexbox to the parent circle's parent element. In my case, the parent element is <body>.
/* Apply Flexbox and use justify-content to
center parent circle horizontally. */
body {
width: 100vw;
display: flex;
justify-content: center;
}
To adjust the diameter of the smaller circles, you would have to remove the width and height properties in your .div2 selector and let Javascript calculate and set the width and height.
var parentdiv = document.getElementById('parentdiv');
var div = 360 / 6;
var radius = 150;
var offsetToChildCenter = 50; // Change me!
var offsetToParentCenter = parseInt(parentdiv.offsetWidth / 2); //assumes parent is square
var totalOffset = offsetToParentCenter - offsetToChildCenter;
for (var i = 1; i <= 6; ++i) {
var childdiv = document.createElement('div');
childdiv.className = 'div2';
childdiv.style.position = 'absolute';
var y = Math.sin((div * i) * (Math.PI / 180)) * radius;
var x = Math.cos((div * i) * (Math.PI / 180)) * radius;
childdiv.style.top = (y + totalOffset).toString() + "px";
childdiv.style.left = (x + totalOffset).toString() + "px";
// Let your JS code calculate the width and height
childdiv.style.width = `${offsetToChildCenter * 2}px`
childdiv.style.height = `${offsetToChildCenter * 2}px`
parentdiv.appendChild(childdiv);
}
body {
width: 100vw;
display: flex;
justify-content: center;
}
#parentdiv {
position: relative;
width: 150px;
height: 150px;
background-color: red;
margin: 150px;
/* Use 50% to ensure the element will always be a circle. */
border-radius: 50%;
}
.div2 {
position: absolute;
/* Remove width and height from CSS */
/* width: 40px; */
/* height: 40px; */
background-color: red;
/* Use 50% to ensure the element will always be a circle. */
border-radius: 50%;
}
<div id="parentdiv"></div>

How do I calculate the minimal distance to a rectangle in JavaScript?

I want to calculate the minimal distance to a rectangle in JavaScript:
--------
| | <- Rectangle
--------
* <- Point
But I only found a script to get the distance to the center of a rectangle. Please try to avoid JQuery because I don't want to use it in my code.
Example: (distance to center)
var distance = Infinity,
rect,
out;
document.mouse = {
x: Infinity,
y: Infinity
}
window.addEventListener("load", function(e) { // set vars
rect = document.getElementById("rect");
out = document.getElementById("out");
}, false);
window.addEventListener("mousemove", function(e) {
document.mouse = {
x: e.pageX,
y: e.pageY
} // get mouse position
distance = elementDistanceToCursor(rect) // get distance to element
out.innerHTML = ["distance: ", distance].join(""); // show result
}, false);
function elementDistanceToCursor(elem) { // get distance to element center
var b = elem.getBoundingClientRect();
return Math.floor(
Math.sqrt(
Math.pow(document.mouse.x - (b.left + (elem.offsetWidth / 2)), 2)
+Math.pow(document.mouse.y - (b.top + (elem.offsetHeight / 2)), 2)
)
);
}
div#rect {
width: 200px;
height: 100px;
border: 1px solid black;
background-color: aqua;
margin: auto;
margin-top: 50px;
}
out {
margin: auto;
vertical-align: middle;
text-align: center;
display: block;
height: 20px;
margin-top: 30px;
}
<div id="rect">
<out id="out"></out>
</div>
To compute the minimal distance from a rectangle to a point you use signed distances on each dimension, then compute the sqrt of squared sums.
var distance = Infinity,
rect,
out;
document.mouse = {
x: Infinity,
y: Infinity
}
window.addEventListener("load", function(e) { // set vars
rect = document.getElementById("rect");
out = document.getElementById("out");
}, false);
window.addEventListener("mousemove", function(e) {
document.mouse = {
x: e.pageX,
y: e.pageY
} // get mouse position
distance = elementDistanceToCursor(rect) // get distance to element
out.innerHTML = ["distance: ", distance].join(""); // show result
}, false);
function elementDistanceToCursor(elem) { // get distance to element
var b = elem.getBoundingClientRect();
var dx = 0;
var dy = 0;
//Compute distance to elem in X
if (document.mouse.x < b.left)
dx = b.left - document.mouse.x;
else if (document.mouse.x > b.right)
dx = b.right - document.mouse.x;
//Compute distance to elem in Y
if (document.mouse.y < b.top)
dy = b.top - document.mouse.y;
else if (document.mouse.y > b.bottom)
dy = b.bottom - document.mouse.y;
return Math.floor(Math.sqrt(dx * dx + dy * dy));
}
div#rect {
width: 200px;
height: 100px;
border: 1px solid black;
background-color: aqua;
margin: auto;
margin-top: 50px;
}
out {
margin: auto;
vertical-align: middle;
text-align: center;
display: block;
height: 20px;
margin-top: 30px;
}
<div id="rect">
<out id="out"></out>
</div>

How to make a div follow the cursor, but shifted by Xpx towards the center of window?

Div should follow the cursor, but shifted 20px by X and Y axis toward the center of the screen, based on the quarter in which is the mouse cursor?
Like this: https://i.imgur.com/XaDk1hI.png
I used trigonometry to find vector from cursor to center of the window, so I have cursor coordinates, center coordinates, and third point C, but div moves in strange circles and I don't where I made mistake.
var lt = document.getElementById('lt')
var ltPosition = lt.getBoundingClientRect();
var element = document.getElementById('element');
var mousePosX = 0;
var mousePosY = 0;
document.onmousemove = function(e){
function angle(xCursor, yCursor, xCenter, yCenter){
var distanceA = xCursor - xCenter;
var distanceB = yCursor - yCenter;
var distanceC = Math.sqrt(distanceA*distanceA + distanceB*distanceB);
var theta = Math.atan2(distanceA, distanceB);
theta *= 180 / Math.PI;
var offsetX = distanceC * Math.sin(theta);
var offsetY = distanceC * Math.cos(theta);
function follow(x,y){
element.style.left = x + "px";
element.style.top = y +"px";
}
follow(e.clientX + offsetX, e.clientY + offsetY);
}
angle(e.clientX, e.clientY, ltPosition.right, ltPosition.bottom);
}
Here is fiddle: https://jsfiddle.net/sgvpvqhc/
What else should I do here in order to have this functionality?
What is that theta *= 180 / Math.PI; doing there? sin and cos take the angle in radians, just like atan returns it. If you want to display it, sure, convert it to degrees, but inside the Math API no conversion are needed.
(updated fiddle demo)
I though you might like this. I put it here too. https://jsfiddle.net/sgvpvqhc/5/
function mouseMover(element, offX, offY) {
var e = element,
bc = e.getBoundingClientRect();
var ox = offX,
oy = offY;
if (ox === undefined && oy === undefined) {
ox = -Math.round(bc.width / 2);
oy = -Math.round(bc.height / 2);
}
e.parentNode.onmousemove = function(eventObj) {
var ev = eventObj,
b = this.getBoundingClientRect();
var x = Math.round(ev.clientX - b.left);
var y = Math.round(ev.clientY - b.top);
e.style.left = x + (ox) + 'px';
e.style.top = y + (oy) + 'px';
}
}
mouseMover(document.getElementById('element'), 20, 20)
html, body {
margin: 0;
height: 100%;
}
.container {
width: 100%;
height: 100%;
}
#lt, #rt, #ld, #rd {
float: left;
width: 50%;
height: 50%;
display: inline-block;
}
#element {
background-color: red;
width: 50px;
height: 50px;
position: absolute;
}
#lt, #rd {
background-color: green;
}
#rt, #ld {
background-color: yellow;
}
<div id='container' class='container'>
<div id='element'></div>
<div id='lt'></div>
<div id='rt'></div>
<div id='ld'></div>
<div id='rd'></div>
</div>
<div class='box'></div>

Categories

Resources