简体   繁体   中英

How to make the hovering trigger an animation only on a circle area in a div with radius border with jquery

I am not a programmer, and I am trying my best to solve the situation but after several hours and headache I give up and I am asking for help.

I have a circular logo (a div with enough radius px to become a circle and some text in it), and I have an animation that come out from behind the logo when I hover on it.

I noticed that my animation it triggers on the "empty area" between the circular logo and the div that hold the logo (that it is still a square). At the moment my script it is this:

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

I tried looking on the web and on stack overflow to find something that will help me, and the nearest thing that I found it is this:

http://jsbin.com/oqewo - from this other question Accurately detect mouseover event for a div with rounded corners

I tried to implement it and I did come out with something that it is not smooth enough as animation (I tried to debug trying to move back and forward with the mouse on the logo to see the reaction of the script):

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

I inserted a variable myHover = 0; at the start of my functions because I needed a variable that would let me know when the animation is completed, it is hidden behind the logo, or in transition.

And I don't know WHEN and HOW to use the .unbind property so I will not suck enough cpu. Is there anything better than mouseenter event? It triggers various time, and only when I move the mouse on the logo, and not when I have the mouse on the logo during the animation. Anyway any suggestion or revision of any kind on approach this problem it is more than welcome :)

==========================

UPDATE

I might find a way, it seems to work, but I am not sure if it is possible to optimise/clean it, or if I am using unbind properly, someone can check my code?

$(".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');
    }
)

The SimpleCircle class used within this code, from the demo mentioned above, is defined as:

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

With regard to your update, it all looks good.

You may get a slight performance upgrade by reversing the order of the two if() parameters so that myHover != "transition1" is first. The && is short-circuit, so if myHover != "transition1" is false, the expensive circle inclusion check does not need to be called.

Also on the else if() might be worth having some variable set to something that says you have already set the cursor to stop that getting called continuously.

Looking at the SimpleCircle class, the only expensive operations it makes are two power calls and a square root ( Math.pow() x 2 + Math.sqrt() ). Whether or not it is worth trying to get that any faster is debatable, only optimisation I can think of there is to check if the coordinates are within the square within the circle which is four quick comparisons, this covers 50% of the interior points, but obviously slows down the other 50% of points. To see if it improved matters you would have to test it.

内方圆内方圆

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM