Wenn eine Maus über einem Bild schwebt. Es wird durch diese if-Anweisung erkannt:
if ((distance(circles[this.index].x, circles[this.index].y, mouse.x, mouse.y)) < circles[this.index].radius)
Ich möchte auch erkennen, wann eine Maus es außerhalb eines Bildes. Nach dieser vorherigen if-Anweisung kann ich sie nicht mehr verwenden. Der Grund dafür ist:
Wenn ich mehrere Bilder auf dem Bildschirm generiere und wenn meine Maus über 1 Bild schwebt. Es schwebt über diesem Bild und der Code erkennt es, aber es schwebt auch nicht über allen anderen Bildern. Dies ist der Grund, warum 4 Mal "außerhalb des Kreises" und 1 Mal "innerhalb des Kreises" angezeigt wird.
Wie im Protokoll zu sehen:
Ausgabe von Console.log:
Mouse inside circle
Mouse outside circle 4
Mouse inside circle
Mouse outside circle 4
Ich suche nach einem Weg, um zu erkennen, wann die Maus einen Kreis verlässt.
Den Code, mit dem ich arbeite, finden Sie unten:
PS: Es ist wichtig, dass es erkennt, in welchem (Index-) Kreis sich die Maus befindet und verlässt. Ich möchte eine große Anzahl von Bildern erstellen, aber im folgenden Code habe ich 5 für Demo-Zwecke verwendet.
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;
}
// 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(circles[this.index].x, circles[this.index].y, mouse.x, mouse.y)) < circles[this.index].radius) {
// Mouse inside circle
console.log("Mouse inside circle")
} else{
//The mouse is in one circle
//And out of 4 other circles
console.log("Mouse outside circle")
}
},
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></canvas>
quelle
Mehrdeutigkeiten
Es ist nicht klar, was Sie in Bezug auf Kreise und einen Punkt benötigen (in diesem Antwortpunkt ist ein Ersatz für die Maus und erfordert nur, dass sie die Eigenschaften hat
x
undy
gültig ist).Der Mangel an Informationen in Ihrer Frage betrifft die Fakten
so viele Kreise können gleichzeitig unter dem Punkt sein.
und dass sich mehr als ein Kreis von unter nach außen oder von unter nach unter dem Punkt pro Bild bewegen kann.
Der Wortlaut der Frage deutet darauf hin, dass Sie sich nur nach einem Kreis befinden, der im Widerspruch zu den beiden oben genannten Bedenken steht.
Annahmen
Ich gehe davon aus, dass die Interaktion mit den Kreisen mehr als nur eine einfache Interaktion unter Ereignissen ist. Dass sie animationsbezogene Verhaltensweisen enthalten können, die durch den auf den Punkt bezogenen Status ausgelöst werden.
Ich gehe davon aus, dass die visuelle Reihenfolge der Kreise bestimmt, wie Sie interessierende Kreise auswählen.
Dass alle Kreise pro Frame die erforderlichen Bedingungen erfüllen und schnell zugänglich sind.
Diese Leistung ist wichtig, da Sie viele Kreise haben möchten, die mit einem Punkt interagieren.
Dass es nur einen Punkt (Maus, Berührung, andere Quelle) pro Frame gibt, der mit den Kreisen interagiert
Es ist keine Kreis-Kreis-Interaktion erforderlich
Lösung
Das folgende Beispiel deckt die obigen Annahmen ab und löst alle Unklarheiten in der Frage. Es ist so konzipiert, dass es effizient und flexibel ist.
Die Kreise werden in einem Array gespeichert, dessen Eigenschaften erweitert wurden
circles
Rendering und Statussätze
Die Funktion
circles.updateDraw(point)
aktualisiert und zeichnet alle Kreise. Das Argumentpoint
ist ein Punkt, anhand dessen der Kreis überprüft werden kann. Der Standardwert ist dermouse
.Alle Kreise werden mit einem Umriss gezeichnet. Kreise unter dem Punkt (z. B. Maus) sind mit Grün gefüllt, Kreise, die gerade unter den Punkt verschoben wurden (z. B. onMouseOver), sind mit Gelb gefüllt, Kreise, die gerade von unten herausgezogen wurden, sind mit Rot gefüllt.
Es gibt 3 Arrays als Eigenschaften von Kreisen, die Kreise enthalten, wie definiert ...
circles.under
Alle Kreise unter dem Punktcircles.outFromUnder
Alle Kreise kommen gerade unter dem Punkt hervorcircles.newUnder
Alle Kreise neu unter dem PunktDiese Arrays werden von der Funktion gefüllt
circles.updateDraw(point)
Fragen Sie den Kreisstatus aller Kreise ab
Kreise haben auch 3 Funktionen,
set
die sich standardmäßig auf die obigen Arrays beziehencircles.under
.Die Funktionen sind ..
circles.firstInSet(set)
Gibt den ersten Kreis (der visuell unterste Punkt) inset
oder zurückundefined
circles.lastInSet(set)
Gibt den letzten Kreis (das visuell oberste) inset
oder zurückundefined
circles.closestInSet(set)
Gibt den nächstgelegenen Kreis zum Punkt inset
oder zurückundefined
Zum Beispiel, um den visuell obersten Kreis direkt unter der Maus
circles.lastInSet(circles.newUnder)
zu erhalten, die Sie aufrufen würden, oder um den Kreis, der der Maus am nächsten liegt, aus allen Kreisen unter der Maus zu erhalten, die Sie aufrufen würdencircles.closestInSet(circles.newUnder)
(oder standardmäßig denunder
Anruf festzulegencircles.closestInSet()
).Kreise zusätzliche Zustände ein
Jeder Kreis hat einige zusätzliche Eigenschaften.
Circle.distSqr
ist das Quadrat der Entfernung vom PunktCircle.rSqr
ist das Quadrat des Radius, der bei der Konstruktion berechnet wird.Circle.underCount
Dieser Wert kann verwendet werden, um Animationen auf den Kreis basierend auf seinem relativen Status zum Punkt anzuwenden.Demo ausführen
Bewegen Sie sich mit der Maus über Kreise. Der Kreis, der am nächsten und unter der Maus liegt, ist mit Weiß mit Alpha = 0,5 gefüllt
quelle
Nun, die Maus bewegt sich und Sie können einfach ein Set erstellen, das Kreisobjekte enthält, in denen die Kreise gespeichert sind, in denen Sie sich befinden:
und dann an der Schleife:
und die
update
:quelle
Ich würde folgendes vorschlagen:
Bewahren Sie einen Stapel von Figuren in der Reihenfolge auf, in der sie erstellt wurden (oder in einer anderen sinnvollen Reihenfolge). Dies ist erforderlich, um Bewegungen über überlappenden Figuren zu erkennen.
Implementieren Sie eine Funktion / Methode, die den Stapel iteriert und feststellt, ob sich der Cursor in einer der Figuren befindet.
Denken Sie daran, dass der letzte Zustand beim Zustandsübergang innerhalb von>> ouside ein Ereignis auslöst.
Verwenden Sie es jetzt:
quelle