How to detect when mouse is outside of a certain circle?
just add another property to circle
function Circle(x, y, radius, index) {
//Give var for circle
this.x = x;
this.y = y;
this.dx = 1;
this.dy = 1;
this.radius = radius;
this.index = index;
this.mouseInside = false
}
and then the update logic change to this
if ((distance(this.x, this.y, mouse.x, mouse.y)) < circles[this.index].radius) {
if (!this.mouseInside) {
this.mouseInside = true
console.log(`mouse enter circele at ${this.index}`)
}
}
else if (this.mouseInside) {
this.mouseInside = false
console.log(`mouse leave circele at ${this.index}`)
}
check if circles overlap and the you can decide if you want to update
var overlapsCircles = circles.filter(circle => {
var diffrentId = circle.index != this.index
var overlapping =
distance(this.x, this.y, circle.x, circle.y) < this.radius
return diffrentId && overlapping
})
if (overlapsCircles.length > 0) {
var overlapCircle = overlapsCircles.map(circle => circle.index)
console.log('overlap circle with index ' + overlapCircle)
}
var mouse = {
x: innerWidth / 2,
y: innerHeight / 2
};
// Mouse Event Listeners
addEventListener('mousemove', event => {
mouse.x = event.clientX;
mouse.y = event.clientY;
});
//Calculate distance between 2 objects
function distance(x1, y1, x2, y2) {
let xDistance = x2 - x1;
let yDistance = y2 - y1;
return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2));
}
// Sqaure to circle
function makeCircleImage(radius, src, callback) {
var canvas = document.createElement('canvas');
canvas.width = canvas.height = radius * 2;
var ctx = canvas.getContext("2d");
var img = new Image();
img.src = src;
img.onload = function () {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
// we use compositing, offers better antialiasing than clip()
ctx.globalCompositeOperation = 'destination-in';
ctx.arc(radius, radius, radius, 0, Math.PI * 2);
ctx.fill();
callback(canvas);
};
}
function Circle(x, y, radius, index) {
//Give var for circle
this.x = x;
this.y = y;
this.dx = 1;
this.dy = 1;
this.radius = radius;
this.index = index;
this.mouseInside = false
}
// use prototyping if you wish to make it a class
Circle.prototype = {
//Draw circle on canvas
draw: function () {
var
x = (this.x - this.radius),
y = (this.y - this.radius);
// draw is a single call
c.drawImage(this.image, x, y);
},
//Updates position of images
update: function () {
var
max_right = canvas.width + this.radius,
max_left = this.radius * -1;
this.x += this.dx;
if (this.x > max_right) {
this.x += max_right - this.x;
this.dx *= -1;
}
if (this.x < max_left) {
this.x += max_left - this.x;
this.dx *= -1;
}
if ((distance(this.x, this.y, mouse.x, mouse.y)) < circles[this.index].radius) {
if (!this.mouseInside) {
this.mouseInside = true
console.log(`mouse enter circele at ${this.index}`)
}
}
else if (this.mouseInside) {
this.mouseInside = false
console.log(`mouse leave circele at ${this.index}`)
}
},
init: function (callback) {
var url = "https://t4.ftcdn.net/jpg/02/26/96/25/240_F_226962583_DzHr45pyYPdmwnjDoqz6IG7Js9AT05J4.jpg";
makeCircleImage(this.radius, url, function (img) {
this.image = img;
callback();
}.bind(this));
}
};
//Animate canvas
function animate() {
c.clearRect(0, 0, window.innerWidth, window.innerHeight);
circles.forEach(function (circle) {
circle.update();
});
circles.forEach(function (circle) {
circle.draw();
});
requestAnimationFrame(animate);
}
//Init canvas
var canvas = document.querySelector('canvas');
var c = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
//init circle objects
var circles = [
new Circle(10, 100, 50, 0),
new Circle(10, 200, 30, 1),
new Circle(10, 300, 50, 2),
new Circle(10, 400, 50, 3),
new Circle(10, 500, 50, 4)
];
var ready = 0;
circles.forEach(function (circle) {
circle.init(oncircledone);
});
function oncircledone() {
if (++ready === circles.length) {
animate()
}
}
<canvas id="ctx"></canvas>