4 Stimmen

Objekte abstoßen, wenn die Maus in der Nähe ist

Ich habe eine Reihe von Spann-Elementen in zufälligen Positionen innerhalb eines übergeordneten div namens '.background'. Diese werden mit Javascript erzeugt. Etwa so:

<span class="circle" style="width: 54px; height: 54px; background: #5061cf; top: 206px; left: 306px"></span>

Ich möchte, dass sie weg bewegen (oder abstoßen), wie die Maus nähert sich, aber ich habe keine Ahnung, wie man dies tun! Wie würde ich über das Erreichen dieser in jQuery gehen?

Ich stelle mir vor, dass man nach Spannweiten in der Nähe suchen und dann ihre Position ändern muss, wenn sie sich innerhalb eines bestimmten Radius um die Maus befinden, aber ich weiß wirklich nicht, wo ich anfangen soll. Für jede Hilfe bin ich dankbar!

14voto

outis Punkte 71613

Ein einfacher Ansatz wäre, jeden Bereich in einen anderen, größeren Bereich einzuschließen. Vergrößern Sie ihn auf jeder Seite um den Mindestabstand, den die Maus zu den inneren Bereichen haben soll. Binden Sie eine Funktion ( evade ), die jeden Wrapper nach mouseover auf den Verpackungen. Bei diesem Ansatz erhalten Sie einen quadratischen Rand. Wenn die grafischen Elemente in den inneren Bereichen nicht quadratisch sind, ist der Abstand zwischen der Maus und dem Rand des grafischen Elements nicht konstant, aber er ist leicht zu implementieren.

Alternativ können Sie den Stoßfänger für einen groben Näherungstest verwenden. Anstatt die Ausweichfunktion mit mouseover binden Sie eine Funktion ( beginEvade ), die bindet evade bei Mausbewegungen. Binden Sie außerdem eine Funktion an mouseout der die Bindung löst evade . Ihr evade kann dann einen genaueren Näherungstest durchführen.

Suchen Sie zunächst eine gute Geometriebibliothek, die einen Vektortyp bereitstellt. In Ermangelung einer solchen, hier ist ein Beispiel für die Implementierung:

Math.Vector = function (x,y) {
    this.x = x;
    this.y = y;
}
Math.Vector.prototype = {
    clone: function () {
        return new Math.Vector(this.x, this.y);
    },
    negate: function () {
        this.x = -this.x;
        this.y = -this.y;
        return this;
    },
    neg: function () {
        return this.clone().negate();
    },
    addeq: function (v) {
        this.x += v.x;
        this.y += v.y;
        return this;
    },
    subeq: function (v) {
        return this.addeq(v.neg());
    },
    add: function (v) {
        return this.clone().addeq(v);
    },
    sub: function (v) {
        return this.clone().subeq(v);
    },
    multeq: function (c) {
        this.x *= c;
        this.y *= c;
        return this;
    },
    diveq: function (c) {
        this.x /= c;
        this.y /= c;
        return this;
    },
    mult: function (c) {
        return this.clone().multeq(c);
    },
    div: function (c) {
        return this.clone().diveq(c);
    },

    dot: function (v) {
        return this.x * v.x + this.y * v.y;
    },
    length: function () {
        return Math.sqrt(this.dot(this));
    },
    normal: function () {
        return this.clone().diveq(this.length());
    }
};

Als Nächstes ein Beispiel für eine Zirkularausweichfunktion (die am einfachsten zu implementieren ist). Umriss:

  1. die Mitte des Stoßfängers zu berechnen (der Stoßfänger Ecke sowie die Außenabmessungen in zwei Hälften geteilt)
  2. den Maus-Offset-Vektor berechnen (aus dem Mauszeiger zum Mittelpunkt des Elements)
  3. Näherungstest: Wenn der Abstand >= der zulässigen Mindestdistanz ist, dann frühzeitige Rückkehr.
  4. Delta berechnen: Der Abstand zum Mauszeiger ist zu klein, also brauchen wir den Vektor von der Stelle, an der sich der Bumper befindet, zu der Stelle, an der er sich befinden sollte (das Delta). Verlängert man den Offset-Vektor so, dass er den minimal zulässigen Abstand hat, erhält man die Position, an der sich der Mittelpunkt des Bumpers befinden sollte, relativ zur Mausposition. Subtrahiert man den Offset-Vektor davon, erhält man das Delta von der Kante in der Nähe der Maus, das auch das Delta ist.
  5. neue Position berechnen:
    1. addiert das Delta zur aktuellen Position.
    2. Begrenzungsprüfung: Alle Ränder des Kreises bleiben innerhalb des Dokuments.
  6. den Stoßfänger verschieben

Im Code:

function evade(evt) {
    var $this = $(this),
        corner = $this.offset(),
        center = {x: corner.left + $this.outerWidth() / 2, y: corner.top + $this.outerHeight() / 2},
        dist = new Math.Vector(center.x - evt.pageX, center.y - evt.pageY),
        closest = $this.outerWidth() / 2;

    // proximity test
    if (dist.length() >= closest) {
        return;
    }

    // calculate new position
    var delta = dist.normal().multeq(closest).sub(dist),
        newCorner = {left: corner.left + delta.x, top: corner.top + delta.y};

    // bounds check
    var padding = parseInt($this.css('padding-left'));
    if (newCorner.left < -padding) {
        newCorner.left = -padding;
    } else if (newCorner.left + $this.outerWidth() - padding > $(document).width()) {
        newCorner.left = $(document).width() - $this.outerWidth() + padding;
    }
    if (newCorner.top < -padding) {
        newCorner.top = -padding;
    } else if (newCorner.top + $this.outerHeight() - padding > $(document).height()) {
        newCorner.top = $(document).height() - $this.outerHeight() + padding;
    }

    // move bumper
    $this.offset(newCorner);
}

Danach bleiben nur noch Funktionen zum Binden/Entbinden evade und die Anrufe, um alles einzurichten.

function beginEvade() {
    $(this).bind('mousemove', evade);
}

function endEvade() {
   $(this).unbind('mousemove', evade);
}

$(function () {
    // you can also wrap the elements when creating them.
    $('.circle').wrap('<span class="bumper" />')

    $('.bumper').bind('mouseover', beginEvade);
    $('.bumper').bind('mouseout', endEvade);
});

Eine Vorschau finden Sie unter jsFiddle

1voto

11684 Punkte 7230

Man wählt mit jQuery alle Objekte mit der Klasse circle aus, packt das in eine Variable und prüft dann bei einer Mausbewegung (könnte auch mit jQuery gemacht werden), ob sich eines in einem bestimmten Radius von der Maus befindet, indem man eine Schleife durch die Objekte zieht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X