Circular Divs with hover and expand

Handles clicking/hovering outside the circle. Finds optimal interior space for text using some trig.

by uttara

HTML

<div id="instructions">Click in cicle to expand. Click/hover in "corner" of circle (in div, but not in circle), doesn't expand</div>
<div id="one" class="circle"><img src="http://30.media.tumblr.com/tumblr_lpxdkjF9tP1qjyzfzo1_500.jpg" /></div>
<div id="two" class="circle"></div>
<div id="three" class="circle"></div>
<div id="four" class="circle"></div>
<div id="five" class="circle"></div>
<div id="six" class="circle"></div>
<div id="seven" class="circle"><div>click me. texty text, some long text wrapping</div></div>






































































































































<script>
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-23915674-6']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();
    
  setTimeout( function() 
  { 
    
    document.body.insertAdjacentHTML( 
        'afterBegin', 
        '<a href="http://thinkingstiff.com" '
        + 'target="_top" '
        + 'onmouseover="this.style.opacity=\'.95\'" '
        + 'onmouseout="this.style.opacity=\'1\'" '
        + 'style="'
            + 'background-color: black;'
            + 'background-image: linear-gradient( top, rgba( 255, 255, 255, .3), rgba( 255, 255, 255, 0) );'
            + 'background-image: -webkit-linear-gradient( top, rgba( 255, 255, 255, .3), rgba( 255, 255, 255, 0) );'
            + 'background-image: -moz-linear-gradient( top, rgba( 255, 255, 255, .3), rgba( 255, 255, 255, 0) );'
            + 'background-image: -o-linear-gradient( top, rgba( 255, 255, 255, .3), rgba( 255, 255, 255, 0) );'
            + 'background-image: -ms-linear-gradient( top, rgba( 255, 255, 255, .3), rgba( 255, 255, 255,...

CSS

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

#instructions {
    height: 200px;
    position: absolute;
    right: 0;
    top: 25px;
    width: 150px;
}

#one {
    border-radius: 100px;
    height: 200px;
    left: 50px;
    top: 50px;
    width: 200px; 
}

img {
    border-radius: 100px;
    display: block;
    height: 100%;
    width: 100%;
}

#two {
    width: 40px;
    height: 40px;
    border-radius: 20px;
    top: 240px;
    left: 60px;
}

#three {
    width: 100px;
    height: 100px;
    border-radius: 50px;
    top: 15px;
    left: 231px;
}

#four {
    width: 150px;
    height: 150px;
    border-radius: 75px;
    top: 200px;
    left: 211px;
}

#five {
    width: 60px;
    height: 60px;
    border-radius: 30px;
    top: 25px;
    left: 25px;
}

#six {
    width: 60px;
    height: 60px;
    border-radius: 30px;
    top: 330px;
    left: 330px;
}

#seven {
    background-color: transparent;
    border: 3px dashed black;
    width: 180px;
    height: 180px;
    border-radius: 90px;
    top: 280px;
    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;
}

JavaScript

//help from: http://stackoverflow.com/users/684890/james-khoury

//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( circleElement, expand, event )  {
        
    var $this = $( circleElement ),
        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;
            
       ...