当鼠标靠近时排斥对象 [英] Repel Objects when mouse is near

查看:45
本文介绍了当鼠标靠近时排斥对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a bunch of span elements in random positions enclosed inside a parent div called '.background'. These are generated with Javascript. Like this:

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

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

I want them to move away (or repel) as the mouse draws near, but I have no idea how to do this! How would I go about accomplishing this in jQuery?

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

I imagine you'd have to search for spans that were nearby, and then change their position if they were inside a certain radius surrounding the mouse, but I really don't know where to start. Any help is appreciated!

推荐答案

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

A simple approach would be to wrap each span in another, larger span. Make it larger on each side by the minimal distance you want the mouse to be able to approach the inner spans. Bind a function (evade) that moves each wrapper to mouseover on the wrappers. This approach gives you a square border, so if the graphical elements in the inner spans aren't square, the distance from the mouse to the graphical element's border won't be constant, but is easy to implement.

或者,使用保险杠进行粗略接近测试。而不是将evade函数绑定到 mouseover ,绑定一个绑定 evade的函数( beginEvade on mousemove。另外,将函数绑定到 mouseout ,解除绑定 evade 。然后你的 evade 可以进行更精确的接近度测试。

Alternatively, use the bumper for a rough proximity test. Instead of binding the evade function to mouseover, bind a function (beginEvade) that binds evade on mousemove. Also, bind a function to mouseout that unbinds evade. Your evade can then perform a more precise proximity test.

首先,找一个提供矢量的好几何库类型。在没有一个的情况下,这是一个示例实现:

First, find a good geometry library that provides a vector type. In absence of one, here's a sample implementation:

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

接下来,一个示例循环规避函数(最简单的实现)。大纲:

Next, a sample circular evasion function (which is the simplest to implement). Outline:


  1. 计算保险杠的中心(保险杠的角落加上外部尺寸分成两半)

  2. 计算鼠标偏移量向量(从鼠标光标到元素的中心)

  3. 接近度测试:如果距离>> =允许的最小距离,则提前返回。

  4. 计算delta:距离的距离鼠标光标太小,所以我们需要从保险杠所在的向量到达应有的位置(delta)。延长偏移矢量,使其为最小允许距离,给出保险杠中心相对于鼠标位置的位置。从中减去偏移向量会得到从邻近边缘到鼠标的增量,这也恰好是增量。

  5. 计算新位置:

  1. calculate the bumper's center (the bumper's corner plus the outer dimensions divided in half)
  2. calculate the mouse offset vector (from the mouse cursor to the element's center)
  3. proximity test: if the distance is >= the minimum allowed distance, then return early.
  4. calculate delta: The distance to the mouse cursor is too small, so we need the vector from where the bumper is to where it should be (the delta). Lengthening the offset vector so it's the minimum allowed distance gives where the bumper's center should be, relative to the mouse's position. Subtracting the offset vector from that gives the delta from the proximity edge to the mouse, which also happens to be the delta.
  5. calculate new position:

  1. 将增量添加到当前位置。

  2. 边界检查:保留文档中圆圈的所有边框。


  • 移动保险杠

  • 代码:

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

    之后,剩下的就是绑定/解除绑定<$ c $的函数c> evade ,以及设置所有内容的调用。

    After that, all that's left are functions to bind/unbind evade, and the calls to set everything up.

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

    您可以在 jsFiddle

    这篇关于当鼠标靠近时排斥对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆