Brandon
Brandon

Reputation: 4523

Center zooming (width/height/top/left) smoothly

So, I'm converting a flash widget into HTML/CSS/JS and I'm having problems emulating a center-oriented zooming effect for images.

So, currently I have a structure in HTML like this:

<div id="outer">
  <img />
</div>

With CSS similar to the following:

#outer{
  width: 690px;
  height: 440px;
  position: relative;
}
#outer img{
  width: 690px;
  height: 440px;
  position: absolute;
  top: 0px;
  left: 0px;
}

Then in jQuery, I'm doing this to create the zoom effect:

$image = $("#outer img");
scale = 1.16;
var w = parseInt($image.data("width")); //Set earlier to 690px
var h = parseInt($image.data("height")); //Set earlier to 440px
$image
  .animate({
    width: w*scale,
    height: h*scale,
    left: -(((w*scale) - w)/2),
    top: -(((h*scale) - h)/2)
  }, 5000, "linear");

jFiddle here

It's a little hard to see with this specific image that I found but it's (for one reason or another) more easily seen in the images my client gave me. What I'm seeing is a jagged/shaky/jittery movement which I assume might be because decimal values for left/top/width/height not lining up well enough to keep it centered always.

Is there a better way to go about this or maybe an easing function that will produce a better result?

If there's anything I can clear up, let me know.

Thanks!

Edit: I've begun to think maybe if I could write an easing function that would increase the width/height by 2 every time the left/top decreases by 1 to make it stay center all the time, but I'm not sure how to go about that in jQuery. I tried messing around with the step argument of the animate function but I can't figure out how to force the left/top properties to increase/decrease by integer values (whole numbers) only...

Upvotes: 1

Views: 6521

Answers (3)

arttronics
arttronics

Reputation: 9955

jsFiddle DEMO 2nd Example

A great jQuery library to handle zoom requirements is .transit() plugin.

$(".thumbnail-1").hover(
    function () {
     $(this).stop(true,true).transition({ scale: 1.3 });
  }, 
    function () {
    $(this).stop(true,true).transition({ scale: 1.0 });
  }
);

Upvotes: 1

Ant&#243;nio Almeida
Ant&#243;nio Almeida

Reputation: 10117

You can always try CSS3 animations, but there's a huge problem with it, IE9 doesn't support it...

However it's pretty smooth, check the result here: http://jsfiddle.net/YSJQu/

#outer img {
    (...)
    animation:zoom 5s;
    -moz-animation:zoom 5s; /* Firefox */
    -webkit-animation:zoom 5s; /* Safari and Chrome */
    -o-animation:zoom 5s; /* Opera */
}

@keyframes zoom {
    from { transform:scale(1) }
    to { transform:scale(1.2) }
}
@-moz-keyframes zoom {
    from { -moz-transform:scale(1) }
    to { -moz-transform:scale(1.2) }
}
@-webkit-keyframes zoom {
    from { -webkit-transform:scale(1) }
    to { -webkit-transform:scale(1.2) }
}
@-o-keyframes zoom {
    from { -o-transform:scale(1) }
    to { -o-transform:scale(1.2) }
}

Upvotes: 6

Alvaro Louren&#231;o
Alvaro Louren&#231;o

Reputation: 1341

Animations had been hard subject in HTML. Some solutions work smoothly in desktops, but not so smooth in mobiles and vice-versa, across browsers they usually performs differently too.

If you are coming from a Flash background, I could easily recommend GSAP JS. It will perform a lot better than jQuery. Its javascript based, and have almost identical syntaxes for both JS and AS.

They also provide a good speed test. Maybe you would like to try.

Upvotes: 2

Related Questions