user2684452 user2684452 - 4 months ago 27
Javascript Question

Smooth out shaky jquery animations

I have an image that rotates and bounces around inside of a parent element. I have it working great, expect the rotation seems a bit hickupy. The first few seconds it's smooth then it starts shaking a bit.

How do I smooth this out?

$.fn.bounce = function(options) {

var settings = $.extend({
speed: 10
}, options);

return $(this).each(function() {

var $this = $(this),
$parent = $this.parent(),
height = $parent.height(),
width = $parent.width(),
top = Math.floor(Math.random() * (height / 2)) + height / 4,
left = Math.floor(Math.random() * (width / 2)) + width / 4,
vectorX = settings.speed * (Math.random() > 0.5 ? 1 : -1),
vectorY = settings.speed * (Math.random() > 0.5 ? 1 : -1);

// place initialy in a random location
$this.css({
'top': top,
'left': left
}).data('vector', {
'x': vectorX,
'y': vectorY
});

var move = function($e) {

var offset = $e.offset(),
width = $e.width(),
height = $e.height(),
vector = $e.data('vector'),
$parent = $e.parent();

if (offset.left <= 0 && vector.x < 0) {
vector.x = -1 * vector.x;
}
if ((offset.left + width) >= $parent.width()) {
vector.x = -1 * vector.x;
}
if (offset.top <= 0 && vector.y < 0) {
vector.y = -1 * vector.y;
}
if ((offset.top + height) >= $parent.height()) {
vector.y = -1 * vector.y;
}

$e.css({
'top': offset.top + vector.y + 'px',
'left': offset.left + vector.x + 'px'
}).data('vector', {
'x': vector.x,
'y': vector.y
});

setTimeout(function() {
move($e);
}, 50);

};

move($this);
});

};

$(function() {
$('#wrapper li').bounce({
'speed': 7
});
});

$(function() {
var $elie = $("img");
rotate(0);
function rotate(degree) {
$elie.css({ WebkitTransform: 'rotate(' + degree + 'deg)'});
$elie.css({ '-moz-transform': 'rotate(' + degree + 'deg)'});
timer = setTimeout(function() {
rotate(--degree);
},30);
}
});


JS FIDDLE

Answer

The choppiness in your approach is from the timeout value of 50. A simple optimization is to just remove that interval and adjust the vector changes to keep the speed about the same.

setTimeout(function() {
  move($e);
}, 0);

vectorX = settings.speed * (Math.random() > 0.5 ? 0.1 : -0.1),
vectorY = settings.speed * (Math.random() > 0.5 ? 0.1 : -0.1);

http://jsfiddle.net/k3uvb5c0/6/