Как заставить зависание вызывать анимацию только в области круга в div с границей радиуса с помощью jquery - PullRequest
1 голос
/ 28 ноября 2010

Я не программист, и я стараюсь изо всех сил, чтобы решить ситуацию, но после нескольких часов и головной боли я сдаюсь и прошу помощи.

У меня есть круговой логотип (div сдостаточно радиуса 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 Ответ

1 голос
/ 28 ноября 2010

Что касается вашего обновления, все выглядит хорошо.

Вы можете получить небольшое повышение производительности, изменив порядок двух параметров if(), так что myHover != "transition1" будет первым.&& - это короткое замыкание, поэтому, если myHover != "transition1" ложно, не требуется вызывать дорогостоящую проверку включения окружности.

Также на else if() может стоить установить некоторую переменную на что-тоэто говорит о том, что вы уже установили курсор, чтобы прекратить этот непрерывный вызов.

Глядя на класс SimpleCircle, единственные дорогостоящие операции, которые он выполняет, - это два вызова мощности и квадратный корень (Math.pow() x 2 + Math.sqrt()).Стоит ли пытаться добиться того, чтобы что-то более быстрое было спорным, единственная оптимизация, о которой я могу подумать, это проверить, находятся ли координаты внутри квадрата внутри круга, что является четырьмя быстрыми сравнениями, это покрывает 50% внутренних точек,но, очевидно, замедляет остальные 50% очков.Чтобы увидеть, улучшилось ли это, вам нужно проверить его.

Square inside a circle inside a square

...