J'ai un tas d'éléments de portée dans des positions aléatoires enfermées à l'intérieur d'un parent div appelé '.background'. Ceux-ci sont générés avec Javascript. Comme ça:
<span class="circle" style="width: 54px; height: 54px; background: #5061cf; top: 206px; left: 306px"></span>
Je veux qu'ils s'éloignent (ou repoussent) à mesure que la souris s'approche, mais je n'ai aucune idée de comment faire ça! Comment puis-je accomplir cela dans jQuery?
J'imagine que vous devriez chercher des espaces proches, puis changer de position s'ils se trouvaient à l'intérieur d'un certain rayon entourant la souris, mais je ne sais vraiment pas par où commencer. Toute aide est appréciée!
Une approche simple serait d'envelopper chaque portée dans une autre, une plus grande portée. Faites-en plus grand de chaque côté par la distance minimale que vous voulez que la souris puisse aborder les travées intérieures. Liez une fonction ( evade
) qui déplace chaque enveloppe pour passer la mouseover
sur les wrappers. Cette approche vous donne une bordure carrée, donc si les éléments graphiques dans les travées internes ne sont pas carrés, la distance entre la souris et la bordure de l'élément graphique ne sera pas constante, mais elle est facile à mettre en œuvre.
Alternativement, utilisez le pare-chocs pour un test de proximité approximatif. Au lieu de relier la fonction d' mouseover
à la mouseover
, liez une fonction ( beginEvade
) qui se lie à evade
à mousemove. Aussi, lier une fonction à la mouseout
qui se détache evade
. Votre evade
peut ensuite effectuer un test de proximité plus précis.
Tout d'abord, trouvez une bonne bibliothèque de géométrie qui fournit un type de vecteur. En l'absence d'un, voici un exemple de mise en œuvre:
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 += vx; this.y += vy; 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 * vx + this.y * vy; }, length: function () { return Math.sqrt(this.dot(this)); }, normal: function () { return this.clone().diveq(this.length()); } };
Ensuite, un exemple de fonction d'évasion circulaire (qui est le plus simple à mettre en œuvre). Contour:
Dans du 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); }
Ensuite, tout ce qui reste sont des fonctions pour lier / déconnecter l' evade
et les appels pour configurer tout.
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); });
Vous pouvez l'afficher en jsFiddle
Vous sélectionnez tous les objets avec le cercle de classe avec jQuery, placez-le dans une variable, puis vérifiez mousemove (peut-être également fait avec jQuery) en les bouclant si l'un est dans un certain rayon de la souris.