gpt4 book ai didi

javascript - 当鼠标靠近时排斥物体

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:53:54 25 4
gpt4 key购买 nike

我在名为“.background”的父 div 中封闭了随机位置的一堆 span 元素。这些是用 Javascript 生成的。像这样:

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

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

我想您必须搜索附近的 span,然后如果它们在鼠标周围的特定半径范围内则更改它们的位置,但我真的不知道从哪里开始。感谢您的帮助!

最佳答案

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

或者,使用保险杠进行粗略的接近测试。不是将 evade 函数绑定(bind)到 mouseover,而是绑定(bind)一个在 mousemove 上绑定(bind) evade 的函数 (beginEvade)。此外,将函数绑定(bind)到 mouseout 以解除绑定(bind) evade。然后,您的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 += 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());
}
};

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

  1. 计算保险杠的中心(保险杠的 corner 加上 outer dimensions 分成两半)
  2. 计算鼠标偏移向量(从 mouse cursor 到元素的中心)
  3. 接近测试:如果距离 >= 最小允许距离,则提前返回。
  4. 计算增量:到鼠标光标的距离太小,所以我们需要从保险杠所在位置到它应该在的位置(增量)的向量。延长偏移向量,使其成为允许的最小距离,从而给出保险杠的中心相对于鼠标位置的位置。从中减去偏移向量得到从邻近边缘到鼠标的增量,这也恰好是增量。
  5. 计算新位置:
    1. 将增量添加到当前位置。
    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);
}

在那之后,剩下的就是绑定(bind)/解除绑定(bind) 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('<span class="bumper" />')

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

您可以在 jsFiddle 中预览

关于javascript - 当鼠标靠近时排斥物体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10058308/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com