简体   繁体   中英

Circle Navigation Effect with jQuery

I am very new to jQuery and would like to animate a circle button on my web page.

From finding a fiddle I adapted it as far as I could with my limited Javascript knowledge. Here is my current Demo .

My Demo : http://jsfiddle.net/FcBPh

I was wondering if I could do the following with it:

1. Fix the circle element to one position. Currently it expands outwards in equal direction, I'd like to expand but still remain in the same position - so perhaps it opens out to the right?

2. Is it possible to stick the 'placehold' graphic outside the circle, so it pokes out a little?

My HTML:

<div id="seven" class="circle">
    <div><img src="http://placehold.it/100x100" style="position:relative;margin-top:-20px" /></div>
    <div style="float:left;margin-left:100px">click me. texty text, some long text wrapping</div>
</div>

Javascript

//setup
$( ".circle" ).each( function() {

    var radius = $( this ).outerWidth() / 2,
        left = $( this ).offset().left,
        top = $( this ).offset().top;

    $( this ).data( { 

        "radius": radius, 
        "left": left, 
        "top": top,
        "clicked": false

    } );

    $( "body" ).data ( { "hovering":false } );

} );

//move and expand
function setLocations( circle, expand, event )  {

    var $this = $( circle ),
        circle = $this.data(),
        hoveredX = circle.left + circle.radius,
        hoveredY = circle.top + circle.radius;

    $( "body" ).data( "hovering", true );

    //expand circle you're over
    $this.animate( { 

        "width": ( 2 * circle.radius ) + expand + "px",
        "height": ( 2 * circle.radius ) + expand + "px",
        "left": circle.left - ( expand / 2 ) + "px",
        "top": circle.top - ( expand / 2 ) + "px",
        "border-top-left-radius": circle.radius + ( expand / 2 ) + "px",
        "border-top-right-radius": circle.radius + ( expand / 2 ) + "px",
        "border-bottom-left-radius": circle.radius + ( expand / 2 ) + "px",
        "border-bottom-right-radius": circle.radius + ( expand / 2 ) + "px"

    }, 75 );

    //images have to be done separately
    $this.children( "img" ).animate( { 

        "border-top-left-radius": circle.radius + ( expand / 2 ) + "px",
        "border-top-right-radius": circle.radius + ( expand / 2 ) + "px",
        "border-bottom-left-radius": circle.radius + ( expand / 2 ) + "px",
        "border-bottom-right-radius": circle.radius + ( expand / 2 ) + "px"

    }, 75 );

    //text in circle
    if( $this.children( "div" ).length ) {

        var h = circle.radius + ( expand / 2 ),
            a = h / Math.sqrt( 2 ),
            size = 2 * a,
            padding = h - a;

        $this.children( "div" ).animate( { 

            "left": padding,
            "top": padding,
            "width": size,
            "height": size

        }, 75 );

    };

    //move other cicles out of the way
    $this.siblings( ".circle" ).each( function() {
        debugger;
        var $this = $( this );
        var circle = $this.data();
        var circleX = circle.left + circle.radius;
        var circleY = circle.top + circle.radius;
        var angle = Math.atan2(hoveredY - circleY, hoveredX - circleX);
        var topMove = ((expand /2 ) * Math.sin(angle));
        var leftMove = ((expand /2 ) * Math.cos(angle));

        $this.animate( { 

            "left": "-=" + leftMove + "px",
            "top":  "-=" + topMove + "px"

        }, 75 );

    });

};

//put everything back the way it was
function resetLocations() {

    $( ".circle" ).each( function() {

        var $this = $( this ),
            circle = $this.data();

         $this.stop().animate( { 

            "width": ( 2 * circle.radius ) + "px",
            "height": ( 2 * circle.radius ) + "px",
            "left": circle.left + "px",
            "top": circle.top + "px",
            "border-top-left-radius": circle.radius + "px",
            "border-top-right-radius": circle.radius + "px",
            "border-bottom-left-radius": circle.radius + "px",
            "border-bottom-right-radius": circle.radius + "px"

        }, 75 );

        $this.children( "img" ).stop().animate( { 

            "border-top-left-radius": circle.radius + "px",
            "border-top-right-radius": circle.radius + "px",
            "border-bottom-left-radius": circle.radius + "px",
            "border-bottom-right-radius": circle.radius + "px"

        }, 75 );

        if( $this.children( "div" ).length ) {

            var h = circle.radius,
                a = h / Math.sqrt( 2 ),
                size = 2 * a,
                padding = h - a;

            $this.children( "div" ).animate( { 
                "left": padding,
                "top": padding,
                "width": size,
                "height": size

            }, 75 );

        };

    } );

    $( "body" ).data( "hovering", false );

};

//is mouse inside circle or in "corner" of div
function inCircle( circle, x, y ) {

    var radius = circle.outerWidth() / 2,
        circleX = circle.offset().left + radius,
        circleY = circle.offset().top + radius,
        xDiff = ( circleX - x ),
        yDiff = ( circleY - y ),
        mouseDistance = Math.sqrt( ( xDiff * xDiff ) + ( yDiff * yDiff ) );

    return ( mouseDistance > radius ? false : true );

};

$( ".circle" ).mouseleave( function( event ) {

    resetLocations();
    $( this ).data( "clicked", false );

});

$( ".circle" ).mousemove( function( event ) {

    if( inCircle( $( this ), event.pageX, event.pageY ) ) {

        if ( !$( "body" ).data( "hovering" ) ) {

            setLocations( this, 40, event );

        };

    } else {

        if ( $( "body" ).data( "hovering" ) ) {

            resetLocations();
            $( this ).data( "clicked", false );

        };

    };

});

$( ".circle" ).click( function( event ) {

    if( $( this ).data( "clicked" ) ) {

        resetLocations();
        $( this ).data( "clicked", false );

    } else {

        if( inCircle( $( this ), event.pageX, event.pageY ) ) {

            $( this ).data( "clicked", true );
            setLocations( this, 200, event );

        } else {

            resetLocations();
            $( this ).data( "clicked", false );

        };

    };

});

CSS

.circle {
    background-color: black;
    overflow: hidden;
    position: absolute;
}

#seven
{
    background-color: transparent;
    border: 1px solid black;
    width: 80px;
    height: 80px;
    border-radius: 90px;
    top: 40px;
    left: 40px;
}

#seven div
{
    /* h=radius, a=h/sqrt(2), height=width=2a, left=top=h-a */
    height: 128px;
    left: 26px; 
    position: absolute;
    top: 26px;
    width: 128px;

}

Many thanks for any pointers with this.

To fix the circle element to the top left so it expands to the bottom right, comment out these two lines:

"left": circle.left - ( expand / 2 ) + "px",
"top": circle.top - ( expand / 2 ) + "px",

And to make the contents of the circle stick outside of it, remove overflow:hidden; in the CSS for the .circle element.

尝试在css中删除此行

overflow: hidden;

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