I am trying to shrink a circle by 50% upon mouse click. I did it by using jQuery UI's scale effect.
The div is
<div id='circle' class='circle'></div>
The Js is
var percent = 0.5;
$('#circle').click(function () {
var height = $(this).height();
var width = $(this).width();
var centerX = $(this).position().left + $(this).width()/2.0;
var centerY = $(this).position().top + $(this).height()/2.0;
$(this).effect( "scale", { percent: percent * 100 }, 1000, function () {
var newTop = centerY - (height * percent)/2.0;
var newLeft = centerX - (width * percent)/2.0;
$('#circle').offset({ 'top': newTop, 'left': newLeft });
$('#circle').css({'height': height * percent, 'width': width * percent });
});
});
That piece of code worked until i added some text on the circle like
<div id='circle' class='circle'>
<span class="title">Title</span>
</div>
The title did scale down with the circle but upon completion it restored to the original size and made the circle a oval. Please try this fiddle: http://jsfiddle.net/marsant/Ycakg/
Is there a neat way to solve this problem other than manually tweaking the completion callback? Thanks!
You could make a quick fix by adding something like:
$(this).find('*').filter(function(i) { return $(this).text != "" && !$(this).children().length }).each(function(i) {
var curSize = parseFloat($(this).css('fontSize'));
$(this).css('fontSize', curSize / 2);
});
$(this).find('*')
: get all inner elements of the circle div.filter(function(i) { return $(this).text != "" && !$(this).children().length })
: narrows our result to only inner elements that have text and no other inner elements.each(function(i) {
: begins going through each element so we can change it's font sizevar curSize = parseFloat($(this).css('fontSize'));
: get the current font size of the current inner element$(this).css('fontSize', curSize / 2);
: Set this inner elements font to a new font size that is half the oldIf you want to jazz it up a little to kind of match your reanimation you could go with:
var curSize = parseFloat($(this).css('fontSize')),
newSize = curSize / 2
$(this).animate({ fontSize: newSize });
Although if you want it to match exactly to the animation, you'll probably need to find a CSS solution or change your whole script a bit. I'll look, one sec ...
USING ANIMATE TO DO IT ALL AT ONCE:
$('#circle').click(function () {
var height = $(this).height(),
newHeight = height / 2,
width = $(this).width(),
newWidth = width / 2,
fontSize = parseFloat($(this).css('fontSize')),
newFontSize = fontSize / 2,
newLeft = parseFloat($(this).css('left')) + (newWidth / 2),
newTop = parseFloat($(this).css('top')) + (newHeight / 2);
$(this).animate({
height: newHeight,
fontSize: newFontSize,
left: newLeft,
top: newTop,
width: newWidth
});
});
NOTE This requires slight change in CSS. I would change the .circle
to have position relative
and move the font-size: 80px;
to the .circle
:
.circle {
background:red;
border-radius: 50%;
height: 200px;
width: 200px;
display: table-cell;
vertical-align: middle;
text-align: center;
top: 10px;
left: 10px;
font-size: 80px;
position: relative;
}
.title {
color: #fff;
font-family:'Helvetica';
}