Как заставить зависание вызывать анимацию только в области круга в div с границей радиуса с помощью jquery
Я не программист, и я стараюсь изо всех сил, чтобы решить ситуацию, но после нескольких часов и головной боли я сдаюсь и прошу помощи.
У меня есть круглый логотип (элемент с достаточным радиусом px, чтобы он стал кругом, и в нем есть текст), и у меня есть анимация, которая появляется из-за логотипа при наведении на него курсора.
Я заметил, что моя анимация срабатывает на "пустой области" между круглым логотипом и элементом div, в котором находится логотип (что он по-прежнему квадратный). На данный момент мой сценарий таков:
$("#logo").hover(function(event){ // Hovering
myHover = "transition";
$("#black").stop().animate({"top":"-200px"}, speed/2, function(){
myHover = 1;
});
},function(event){ // Finish hovering
myHover = "transition";
$("#black").stop().animate({"top":"0px"}, speed/2, function(){
myHover = 0;
});
});
Я попытался поискать в Интернете и переполнении стека, чтобы найти что-то, что мне поможет, и самое близкое, что я нашел, это:
http://jsbin.com/oqewo - из этого другого вопроса Точно определить событие при наведении курсора на div с закругленными углами
Я попытался реализовать это, и у меня получилось что-то, что оно недостаточно плавно, как анимация (я пытался отлаживать, пытаясь перемещаться назад и вперед с помощью мыши на логотипе, чтобы увидеть реакцию сценария):
$(".myCircle").hover(
// when the mouse enters the box do...
function(){
var $box = $(this),
offset = $box.offset(),
radius = $box.width() / 2,
circle = new SimpleCircle(offset.left + radius, offset.top + radius, radius);
$box.mousemove(function(e){
if(circle.includesXY(e.pageX, e.pageY) && myHover != "transition"){
$(this).css({"cursor":"pointer"});
myHover = "transition";
$("#black").stop().animate({"top":"-200px"}, speed/2, function(){
myHover = 1;
});
}else if(!circle.includesXY(e.pageX, e.pageY)){
$(this).css({"cursor":"default"});
myHover = "transition";
$("#black").animate({"top":"0px"}, speed/2, function(){
myHover = 0;
});
}
});
},
// when the mouse leaves the box do...
function() {
//alert("in")
//$(this).includesXY(e.pageX, e.pageY)
myHover = "transition";
$(this).css({"cursor":"default"});
$("#black").stop().animate({"top":"0px"}, speed/2, function(){
myHover = 0;
});
}
)
Я вставил переменную myHover = 0; в начале моих функций, потому что мне нужна была переменная, которая сообщала бы мне, когда анимация завершена, она скрыта за логотипом или в процессе перехода.
И я не знаю, КОГДА и КАК использовать свойство.unbind, поэтому я не буду высасывать достаточно ресурсов процессора. Есть ли что-нибудь лучше, чем событие Mouseenter? Это срабатывает разное время, и только когда я перемещаю мышь на логотипе, а не когда у меня есть мышь на логотипе во время анимации. В любом случае любое предложение или пересмотр любого рода по подходу к этой проблеме приветствуется:)
==========================
ОБНОВИТЬ
Я мог бы найти способ, кажется, он работает, но я не уверен, возможно ли его оптимизировать / очистить, или если я правильно использую unbind, кто-то может проверить мой код?
$(".myCircle").hover(
// when the mouse enters the box do...
function(){
var $box = $(this),
offset = $box.offset(),
radius = $box.width() / 2,
circle = new SimpleCircle(offset.left + radius, offset.top + radius, radius);
$box.mousemove(function(e){
if(circle.includesXY(e.pageX, e.pageY) && myHover != "transition1"){
$(this).css({"cursor":"pointer"});
myHover = "transition1";
$("#black").stop().animate({"top":"-200px"}, speed/2, function(){
myHover = 1;
});
}
else if(!circle.includesXY(e.pageX, e.pageY)){
$(this).css({"cursor":"default"});
if(myHover == 1 || myHover == "transition1"){
myHover = "transition0";
$("#black").stop().animate({"top":"0px"}, speed/2, function(){
myHover = 0;
});
}
}
});
},
// when the mouse leaves the box do...
function() {
if(myHover == 1 || myHover == "transition1"){
myHover = "transition0";
$(this).css({"cursor":"default"});
$("#black").stop().animate({"top":"0px"}, speed/2, function(){
myHover = 0;
})
};
$("#container").unbind('mousemove');
}
)
SimpleCircle
Класс, используемый в этом коде, из упомянутой выше демонстрации, определяется как:
function SimpleCircle(x, y, r) {
this.centerX = x;
this.centerY = y;
this.radius = r;
}
SimpleCircle.prototype = {
distanceTo: function(pageX, pageY) {
return Math.sqrt(Math.pow(pageX - this.centerX, 2) + Math.pow(pageY - this.centerY, 2));
},
includesXY: function(x, y) {
return this.distanceTo(x, y) <= this.radius;
}
};
1 ответ
Что касается вашего обновления, все выглядит хорошо.
Вы можете получить небольшое повышение производительности, изменив порядок двух if()
параметры, так что myHover != "transition1"
это первое. &&
короткое замыкание, так что если myHover != "transition1"
ложно, дорогая проверка на включение круга вызывать не нужно.
Также на else if()
возможно, стоит установить некоторую переменную, которая говорит о том, что вы уже установили курсор, чтобы прекратить этот непрерывный вызов.
Глядя на SimpleCircle
класс, единственные дорогостоящие операции, которые он делает, это два мощных вызова и квадратный корень (Math.pow() x 2 + Math.sqrt()
). Стоит ли пытаться добиться того, чтобы что-то более быстрое было спорным, единственная оптимизация, о которой я могу подумать, - это проверить, находятся ли координаты внутри квадрата внутри круга, что составляет четыре быстрых сравнения, это покрывает 50% внутренних точек, но, очевидно, замедляет остальные 50% очков. Чтобы увидеть, улучшилось ли это, вам нужно проверить его.