当鼠标靠近时排斥对象

我在一个名为’.background’的父div中包含一些随机位置的span元素。 这些是使用Javascript生成的。 像这样:

 

我希望它们在鼠标靠近时移开(或击退),但我不知道该怎么做! 我将如何在jQuery中完成此任务?

我想你必须搜索附近的跨距,如果它们在鼠标周围的某个半径范围内,则改变它们的位置,但我真的不知道从哪里开始。 任何帮助表示赞赏!

一种简单的方法是将每个跨度包裹在另一个更大的跨度中。 通过您希望鼠标能够接近内跨的最小距离,使每侧更大。 绑定一个函数( evade ),将每个包装器移动到包装器上的mouseover 。 这种方法为您提供了方形边框,因此如果内部跨度中的图形元素不是方形,则鼠标到图形元素边框的距离不会是恒定的,但很容易实现。

或者,使用保险杠进行粗略接近测试。 不是将beginEvade函数绑定到mouseover ,而是绑定一个在mousemove上绑定beginEvade的函数( beginEvade )。 此外,将函数绑定到mouseout绑定的mouseout 。 然后,您的evade可以执行更精确的接近测试。

首先,找到一个提供矢量类型的好几何库。 如果没有,这是一个示例实现:

 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()); } }; 

接下来,一个样本循环逃避函数(这是最简单的实现)。 大纲:

  1. 计算保险杠的中心(保险杠的角落加外部尺寸除以一半)
  2. 计算鼠标偏移矢量(从鼠标光标到元素的中心)
  3. 接近度测试:如果距离> =最小允许距离,则提前返回。
  4. 计算delta:到鼠标光标的距离太小,所以我们需要从保险杠所在的向量到达应有的位置(delta)。 延长偏移矢量,使其为最小允许距离,给出保险杠中心相对于鼠标位置的位置。 从中减去偏移向量给出了从邻近边缘到鼠标的增量,这也恰好是增量。
  5. 计算新职位:
    1. 将delta添加到当前位置。
    2. 边界检查:保留文档中圆圈的所有边界。
  6. 移动保险杠

在代码中:

 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); } 

在那之后,剩下的就是绑定/取消绑定evade函数,以及设置一切的调用。

 function beginEvade() { $(this).bind('mousemove', evade); } function endEvade() { $(this).unbind('mousemove', evade); } $(function () { // you can also wrap the elements when creating them. $('.circle').wrap('') $('.bumper').bind('mouseover', beginEvade); $('.bumper').bind('mouseout', endEvade); }); 

您可以在jsFiddle中预览

你用jQuery选择带有类圈的所有对象,把它放在变量中,然后通过循环检查mousemove(也可以用jQuery完成),如果一个在鼠标的某个半径范围内。