当鼠标靠近时排斥对象

时间:2012-04-07 20:56:12

标签: javascript jquery

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

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

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

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

2 个答案:

答案 0 :(得分:14)

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

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

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

evade

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

  1. 计算保险杠的中心(保险杠的corner加上outer dimensions分成两半)
  2. 计算鼠标偏移量向量(从mouse cursor到元素的中心)
  3. 接近度测试:如果距离>> =最小允许距离,则提前返回。
  4. 计算delta:到鼠标光标的距离太小,所以我们需要从保险杠所在的向量到它应该的位置(delta)。延长偏移矢量,使其为最小允许距离,给出保险杠中心相对于鼠标位置的位置。从中减去偏移向量会得到从邻近边缘到鼠标的增量,这也恰好是增量。
  5. 计算新职位:
    1. 将delta添加到当前位置。
    2. 边界检查:保留文档中圆圈的所有边框。
  6. 移动保险杠
  7. 在代码中:

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

    之后,剩下的就是绑定/取消绑定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

    您可以在jsFiddle

    中预览

答案 1 :(得分:1)

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