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

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>

Related

How to Draw on rotated canvas using mouse?

I want to draw on img its work fine but when i rotate the image its drawing axis is total change and it not draw on the right area
https://codepen.io/ali-shahzil/project/editor/AddPLW
var canvas;
var ctx;
var SCALE_MIN = 1,
SCALE_MAX = 25;
var currScale = 0; // def pic width=600px, 100px=1scale unit
var xscale = 1.0;
var scaleFactor = 1.00;
var painting = false,
mark = true,
lastX = 0,
lastY = 0,
lineThickness = 0.3,
width = 600,
height = 600;
var img = new Image();
img.src = 'img.JPG';
img.onload = function() {
canvas = document.getElementById("canvas1"),
ctx = canvas.getContext("2d");
canvas.height = height;
canvas.width = width;
ctx.drawImage(img, 5, 40, canvas.width, canvas.height);
canvas = document.getElementById("canvas2"),
ctx = canvas.getContext("2d");
canvas.height = height;
canvas.width = width;
ctx.drawImage(img, 5, 40, canvas.width, canvas.height);
canvas = ctx = ''; //reset
}
function doMarking() {
var checkBox = document.getElementById("mark");
if (checkBox.checked == true) {
mark = true;
if (canvas != null)
canvas.style.cursor = "pointer";
//currImgId = '';
} else {
mark = false;
if (canvas != null);
canvas.style.cursor = "";
}
lastX = 0,
lastY = 0,
painting = false;
}
function mouseDown(e) {
if (!mark)
return;
painting = true;
ctx.fillStyle = "#ffffff";
lastX = e.pageX - (e.target).offsetLeft;
lastY = e.pageY - (e.target).offsetTop;
//Calculating the scale how much it increase
var rect = canvas.getBoundingClientRect(); // abs. size of element
scaleX = canvas.width / rect.width; // relationship bitmap vs. element for X
scaleY = canvas.height / rect.height; // relationship bitmap vs. element for Y
lastX = lastX * scaleX;
lastY = lastY * scaleY;
//console.log('Before lasX=' + lastX + ' lastY=' + lastY+',currScale='+currScale);
//lastX=transformSimple(lastX);
// lastY=transformSimple(lastY);
//console.log('After lasX=' + lastX + ' lastY=' + lastY+', currScale='+currScale);
//console.log('offleft=' + (e.target).offsetLeft + ', offsetTop=' + (e.target).offsetTop);
// console.log('e=' + e);
}
/*
canvas1.onmousedown=function (e) {
console.log('mousedown2 id=' + e);
if (!mark)
return;
painting = true;
ctx.fillStyle = "#ffffff";
lastX = e.pageX - this.offsetLeft;
lastY = e.pageY - this.offsetTop;
console.log('lasX=' + lastX + ' lastY=' + lastY);
}
*/
function mouseUp(e) {
if (!mark)
return;
painting = false;
}
function mouseMove(e) {
if (!mark)
return;
if (painting) {
mouseX = e.pageX - (e.target).offsetLeft;
mouseY = e.pageY - (e.target).offsetTop;
//Calculating the scale how much it increase
var rect = canvas.getBoundingClientRect(); // abs. size of element
scaleX = canvas.width / rect.width; // relationship bitmap vs. element for X
scaleY = canvas.height / rect.height; // relationship bitmap vs. element for Y
mouseX = mouseX * scaleX;
mouseY = mouseY * scaleY;
// mouseX=transformSimple(mouseX);
// mouseY=transformSimple(mouseY);
//console.log('mx=' + mouseX + ', my=' + mouseY);
// find all points between
var x1 = mouseX,
x2 = lastX,
y1 = mouseY,
y2 = lastY;
var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
if (steep) {
var x = x1;
x1 = y1;
y1 = x;
var y = y2;
y2 = x2;
x2 = y;
}
if (x1 > x2) {
var x = x1;
x1 = x2;
x2 = x;
var y = y1;
y1 = y2;
y2 = y;
}
var dx = x2 - x1,
dy = Math.abs(y2 - y1),
error = 0,
de = dy / dx,
yStep = -1,
y = y1;
if (y1 < y2) {
yStep = 1;
}
lineThickness = 5 - Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) / 10;
if (lineThickness < 1) {
lineThickness = 1;
}
for (var x = x1; x < x2; x++) {
if (steep) {
// translate(y,x);
ctx.fillRect(y, x, lineThickness, lineThickness);
//ctx.fillRect(transformSimple(y), transformSimple(x), lineThickness, lineThickness);
} else {
ctx.fillRect(x, y, lineThickness, lineThickness);
}
error += de;
if (error >= 0.5) {
y += yStep;
error -= 1.0;
}
// console.log('x=' + x + ', y=' + y );
}
lastX = mouseX;
lastY = mouseY;
}
}
/*
canvas.addEventListener('click', function (event) {
if (mark)
return;
//get the img of convas
});*/
//-------------- img zooms
function zoomin_canvas() {
if (canvas != null) {
var currWidth = canvas.clientWidth;
//console.log('zoomin currWidth='+currWidth);
if (currWidth >= 1500) return false;
else {
canvas.style.width = (currWidth + 100) + "px";
//if (currScale < SCALE_MAX)
// currScale++;
//console.log('scale=' + currScale);
}
}
}
function zoomout_canvas() {
if (canvas != null) {
var currWidth = canvas.clientWidth;
if (currWidth <= 100) return false;
else {
canvas.style.width = (currWidth - 100) + "px";
//if (currScale > SCALE_MIN)
// currScale--;
//console.log('scale=' + currScale);
}
}
}
var currImgId = null;
function selectImg(e) {
if (currImgId != null) {
document.getElementById(currImgId).style.border = "none";
}
e.target.style.border = "2px solid orange";
currImgId = (e.target).getAttribute('id');
if (typeof canvas !== 'undefined') {
// the variable is defined
canvas = e.target;
ctx = canvas.getContext("2d");
}
//ctx.drawImage(img, 5, 40, canvas.width, canvas.height);
}
function rotate() {
if (currImgId != null) {
document.getElementById(currImgId).setAttribute("class", "rotated-image");
}
}
var degrees = 0;
function rotateRight() {
console.log('currimgid=' + currImgId);
var img = document.getElementById(currImgId);
degrees = parseInt(img.getAttribute("rotate"));
degrees = (degrees + 90) % 360;
img.style.setProperty('-ms-transform', 'rotate(' + degrees + 'deg)');
img.style.setProperty('-webkit-transform', 'rotate(' + degrees + 'deg)');
img.style.setProperty('transform', 'rotate(' + degrees + 'deg)');
img.setAttribute("rotate", degrees);
}
function rotateLeft() {
var img = document.getElementById(currImgId);
degrees = parseInt(img.getAttribute("rotate"));
degrees = (degrees - 90) % 360;
img.style.setProperty('-ms-transform', 'rotate(' + degrees + 'deg)');
img.style.setProperty('-webkit-transform', 'rotate(' + degrees + 'deg)');
img.style.setProperty('transform', 'rotate(' + degrees + 'deg)');
img.setAttribute("rotate", degrees);
}
function translate(X, Y) {
console.log('untransformed x=' + X + ', y=' + Y);
// const point = {x: 0, y: 0};
const matrix = ctx.getTransform();
const transformedPoint = {
x: matrix.a * X + matrix.c * Y + matrix.e,
y: matrix.b * X + matrix.d * Y + matrix.f,
};
console.log('transformed x=' + transformedPoint.x + ', y=' + transformedPoint.y);
}
function translateSimple(X, Y) {
//console.log('scalefactor='+scaleFactor);
console.log('untransformed x=' + X + ', y=' + Y);
if (scaleFactor >= 1.0)
console.log('transformed x=' + X / scaleFactor + ', y=' + Y / scaleFactor);
else
console.log('transformed x=' + X * scaleFactor + ', y=' + Y * scaleFactor);
}
function transformSimple(a) {
//return (parseInt(a/(scaleFactor*scaleFactor)));
if (currScale == 0)
return (a);
else
return (a - 16 * (currScale));
}
function draw() {
for (var x = 100; x < 102; x++)
ctx.fillRect(100, x, 4.9, 4.9);
}
.main_bottom {
background-color: #e8e9eb;
display: flex;
align-items: center;
justify-content: space-around;
border: 10px solid #e8e9eb;
border-top: 30px solid #e8e9eb;
height: 90vh;
}
form {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
margin-bottom: 5px;
}
.scrollit {
/*overflow-y: auto;*/
/* overflow-y: scroll;*/
height: 300px;
overflow-x: hidden;
overflow-y: auto;
}
.first {
display: flex;
flex-direction: row;
visibility: hidden;
}
.submit {
display: flex;
flex-direction: row;
}
img {
width: 100%;
max-width: 800px;
height: auto;
display: block;
margin-left: auto;
margin-right: auto;
}
.fix {
height: 300px;
margin-top: 200px;
}
body,
html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
}
#left_panel {
display: flex;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 700px;
background-color: white;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
flex-direction: column;
overflow: scroll;
}
#right_panel {
display: flex;
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 700px;
margin-right: 15px;
background-color: white;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
flex-direction: column;
overflow: scroll;
}
#drag {
position: absolute;
left: -4px;
top: 0;
bottom: 0;
width: 8px;
cursor: w-resize;
}
/*img zooms*/
#navbar {
overflow: hidden;
background-color: #099;
position: fixed;
top: 0;
width: 100%;
padding-top: 3px;
padding-bottom: 3px;
padding-left: 20px;
}
#navbar a {
float: left;
display: block;
color: #666;
text-align: center;
padding-right: 20px;
text-decoration: none;
font-size: 17px;
}
#navbar a:hover {
background-color: #ddd;
color: black;
}
#navbar a.active {
background-color: #4caf50;
color: white;
}
.main {
padding: 16px;
margin-top: 30px;
width: 100%;
height: 100vh;
overflow: auto;
cursor: grab;
cursor: -o-grab;
cursor: -moz-grab;
cursor: -webkit-grab;
}
.main img {
height: auto;
width: auto;
}
.button {
width: 300px;
height: 60px;
}
/*---- toggle switch*/
.switch {
position: relative;
display: inline-block;
width: 30px;
height: 17px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
}
.slider:before {
position: absolute;
content: "";
height: 13px;
width: 13px;
left: 4px;
bottom: 2px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
}
input:checked+.slider {
background-color: #2196f3;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196f3;
}
input:checked+.slider:before {
-webkit-transform: translateX(13px);
-ms-transform: translateX(13px);
transform: translateX(13px);
}
/* Rounded sliders */
.slider.round {
border-radius: 17px;
}
.slider.round:before {
border-radius: 50%;
}
.both {
margin-top: 50px;
display: flex;
justify-content: center;
}
<!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">
<link rel="stylesheet" href="./styles.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<title>Order by Picture</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<div id="navbar">
<button type="button" onclick="zoomin_canvas()">+</button>
<button type="button" onclick="zoomout_canvas()">-</button>
<button id="rotateRight" onclick="rotateRight()">Right</button>
<button id="rotateLeft" onclick="rotateLeft()">Left</button>
<button id="Button1" onclick="draw()">draw</button
<label> Marking</label>
<label class="switch">
<input type="checkbox" checked onclick="doMarking()" id="mark">
<span class="slider round"></span>
</label>
</div>
<div class="both">
<div class="canvas1">
<canvas id="canvas1" rotate="0" onclick="selectImg(event)" onmousedown="mouseDown(event)" onmouseup="mouseUp(event)" onmousemove="mouseMove(event)">
Your browser does not support the HTML5 canvas tag.
</canvas>
</div>
<div class="canvas2">
<canvas id="canvas2" rotate="0" onclick="selectImg(event)" onmousedown="mouseDown(event)" onmouseup="mouseUp(event)" onmousemove="mouseMove(event)">
Your browser does not support the HTML5 canvas tag.
</canvas>
</div>
</div>
</body>
</html>
Don't rotate the canvas
Draw the rotated image on the canvas, rather than rotate the canvas.
When you draw image on the canvas, rotate it, then you can draw over it using the normal mouse coords.
Rotating image on canvas
The code below will draw an image rotated by any amount. The image will be scaled down if needed to ensure it fits the canvas. The function will rotate the image any angle you want.
// ctx is canvas 2D context
// deg in degrees rotated CW from 3 O-clock
// img to render. NOTE image must be loaded first
function drawRotatedImage(ctx, deg, img) {
const w = img.naturalWidth;
const h = img.naturalHeight;
const cw = ctx.canvas.width;
const ch = ctx.canvas.height;
// convert deg to radians
const rad = deg * Math.PI / 180;
// Get vector for rotated xAxis ax, ay. With aax, aay in first quadrant
const ax = Math.cos(rad), aax = Math.abs(ax);
const ay = Math.sin(rad), aay = Math.abs(ay);
// get the rotated width and height of image
const tw = aax * w + aay * h;
const th = aay * w + aax * h;
// get scale so that image fits the canvas. Dont enlarge only reduce if to big
const scale = Math.min(1, cw / tw, ch / th);
// set canvas transform to center of canvas, rotated and scaled to fit
ctx.setTransform(ax * scale, ay * scale, -ay * scale, ax * scale, cw / 2, ch / 2);
// draw image on canvas offset by half its width and height
ctx.drawImage(img, -w / 2, -h / 2);
// restore canvas transform to default
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
Example
Example using the above function to render image to canvas and then use mouse to draw over the image. Click rotate to rotate the image.
const ctx = canvas.getContext("2d");
const mouse = {x: 0, y: 0, b: false, ox: 0, oy: 0};
var rot = 90;
const img = new Image;
img.src = "https://i.stack.imgur.com/C7qq2.png?s=420&g=1";
img.onload = () => rotImage(ctx, rot, img);
resize();
addEventListener("resize", resize);
rotBtn.addEventListener("click", () => img.complete && rotImage(ctx, rot += 90, img));
addEventListener("mousemove", mouseEvent);
addEventListener("mousedown", mouseEvent);
addEventListener("mouseup", mouseEvent);
addEventListener("mouseout", mouseEvent);
function resize() {
canvas.width = innerWidth;
canvas.height = innerHeight;
ctx.lineWidth = 3;
ctx.lineCap = "round";
ctx.strokeStyle = "#00F";
img.complete && rotImage(ctx, rot, img);
}
function mouseEvent(e) {
mouse.ox = mouse.x;
mouse.oy = mouse.y;
mouse.x = e.pageX;
mouse.y = e.pageY;
if (e.type === "mousedown") { mouse.b = true }
else if (e.type === "mouseup" || e.type === "mouseout") { mouse.b = false }
mouse.b && drawWithMouse(ctx, mouse);
}
function drawWithMouse(ctx, mouse) {
ctx.beginPath();
ctx.lineTo(mouse.ox, mouse.oy);
ctx.lineTo(mouse.x, mouse.y);
ctx.stroke();
}
function rotImage(ctx, deg, img) {
const cw = ctx.canvas.width, ch = ctx.canvas.height;
const w = img.naturalWidth, h = img.naturalHeight;
const rad = deg * Math.PI / 180;
const ax = Math.cos(rad), aax = Math.abs(ax);
const ay = Math.sin(rad), aay = Math.abs(ay);
const tw = aax * w + aay * h;
const th = aay * w + aax * h;
const sc = Math.min(1, cw / tw, ch / th);
ctx.clearRect(0, 0, cw, ch);
ctx.setTransform(ax * sc, ay * sc, -ay * sc, ax * sc, cw / 2, ch / 2);
ctx.drawImage(img, -w / 2, -h / 2);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
* {font-family: arial;}
button { position: absolute; top: 10px; left: 10px }
canvas { position: absolute; top: 0px; left: 0px }
<canvas id="canvas"></canvas>
<button id="rotBtn">Rotate</button>

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>

Detect circle overlap

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>

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 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