간단한 방법은 각 범위를 다른 하나의 큰 범위로 묶는 것입니다. 마우스를 내부 범위에 접근 할 수있는 최소 거리만큼 각면을 더 크게 만듭니다. 랩퍼에서 각 랩퍼를 mouseover
으로 이동시키는 함수 (evade
)를 바인드하십시오. 이 방법은 사각형 테두리를 제공하므로 안쪽 범위의 그래픽 요소가 사각형이 아닌 경우 마우스에서 그래픽 요소의 테두리까지의 거리가 일정하지 않지만 구현하기 쉽습니다.
또는 거친 근접 테스트를 위해 범퍼를 사용하십시오. evade 함수를 mouseover
에 바인딩하는 대신 evade
을 바인딩하는 함수 (beginEvade
)를 mousemove에 바인딩하십시오. 또한 함수를 mouseout
에 바인드하여 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());
}
};
다음으로 구현할 가장 간단한 회피 함수입니다. 개요 :
- 범퍼의 중심을 계산 (범퍼의 corner 플러스 반으로 나눈 outer dimensions)
- 는
- 근접 테스트합니다 (mouse cursor에서 요소의 중심) 마우스 오프셋 벡터를 계산 : 거리 인 경우 > = 허용되는 최소 거리. 그런 다음 일찍 돌아옵니다.
- 델타 계산 : 마우스 커서까지의 거리가 너무 작기 때문에 범퍼가 있어야하는 위치 (델타)에서 벡터가 필요합니다. 오프셋 벡터를 길게하여 최소 허용 거리를 지정하면 범퍼의 중심이 마우스의 위치와 관련하여 있어야합니다. 오프셋 벡터를 빼면 델타가 근접 에지에서 마우스로 이동하며 델타도 발생합니다.
- 새로운 위치를 계산하십시오 :
- 델타를 현재 위치에 추가하십시오.
- 범위 검사 : 문서 내의 모든 경계선을 유지합니다.코드에서
- 이동 범퍼
: 그 후
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('<span class="bumper" />')
$('.bumper').bind('mouseover', beginEvade);
$('.bumper').bind('mouseout', endEvade);
});
당신은 jQuery로 클래스 원 모든 개체를 선택 jsFiddle
철저한 답변! –
하지만 [완벽하지] (http://jsfiddle.net/outis/bA8YE/39/). z- 색인은 하나 이상의 회피 자에게 문제를 일으 킵니다. – outis
JSfiddle은 재미있게 놀 수 있습니다. '클릭 해주세요!'라는 링크로 사용하는 것이 상상할 수 있습니다. 그런 다음 할 수 없게됩니다. – Partack