Skip to content

Instantly share code, notes, and snippets.

@lunr
Created July 19, 2012 19:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lunr/3146034 to your computer and use it in GitHub Desktop.
Save lunr/3146034 to your computer and use it in GitHub Desktop.
Animator: JS to animate a set of images in a 360 rotation -- Works on Touchscreen devices too
$(document).ready(function() {
var speedLimit = 4; // higher allows the spin to jump frames faster. More speed.
var sensitivity = 10; // higher numbers makes it *less* sensitive, i.e. get to the speed limit slower.
var dragCoefficient = 3; // higher numbers = more drag. Slows down faster after a drag-to-spin. % of speed to lose.
$.fn.animator = function() {
var that = this;
that.container = $(this).find('.frame-container');
that.frames = that.container.children();
that.totalFrames = that.frames.length - 1;
that.switch = 0;
that.momentum = 0;
that.residual = 0;
that.dX = 0;
that.currentFrame = 0;
that.showingFrame = false;
that.direction = 1; // Left-to-Right = -1, Right-to-Left = 1
that.looping = 1;
// use touch events?
that.isTouchDevice = (function() {
try {
document.createEvent("TouchEvent");
return true;
} catch (e) {
return false;
}
}()),
// names of events are dependent on whether device uses touch events
that.scrollEvents = that.isTouchDevice ?
{ start: "touchstart", move: "touchmove", end: "touchend" } :
{ start: "mousedown", move: "mousemove", end: "mouseup" },
/* Bind the touchstart event to the container */
that.container.bind(that.scrollEvents.start, function(e) {
e.preventDefault();
that.start = e.pageX;
that.lastX = e.pageX,
that.lastY = e.pageY;
that.momentum = 0;
that.residual = 0;
that.switch = 0;
/* On start, bind move and start tracking the touch movement */
that.container.bind(that.scrollEvents.move, function(e) {
e.preventDefault();
// calculate distance to travel based on deltaX
var newCurrentFrame = that.currentFrame;
var pageX = e.pageX,
pageY = e.pageY,
deltaX = that.lastX - pageX;
that.lastX = pageX;
that.lastY = pageY;
that.dX = that.dX + deltaX;
if (that.dX != 0) {
// set momentum
that.momentum = ((1 / (1 + Math.pow(Math.E, -that.dX/sensitivity))) - .5) * speedLimit;
that.dX = 0;
} else {
if (that.momentum != 0) {
that.momentum = that.momentum * ((100 - dragCoefficient) / 100);
if (Math.abs(that.momentum) < .5) {
// residual enables a graceful slowdown.
that.residual = that.residual + that.momentum;
}
if (Math.abs(that.momentum) < .2) {
that.momentum = 0;
}
} else {
that.residual = 0;
}
}
if (Math.round(that.momentum) != 0 || Math.abs(that.residual) > 1) {
that.switch++;
newCurrentFrame = that.currentFrame + (that.direction * (Math.round(that.momentum) + Math.round(that.residual)));
// set new frame
if (newCurrentFrame > that.totalFrames) {
if (that.looping) {
newCurrentFrame = newCurrentFrame - that.totalFrames;
} else {
newCurrentFrame = that.totalFrames - 1;
that.momentum = 0;
that.residual = 0;
}
} else if (newCurrentFrame < 0) {
if (that.looping) {
newCurrentFrame = that.totalFrames + (newCurrentFrame % that.totalFrames);
} else {
newCurrentFrame = 0;
that.momentum = 0;
that.residual = 0;
}
}
if (Math.abs(that.residual) > 1) {
that.residual = (that.residual < 0) ? that.residual + 1 : that.residual - 1;
}
}
if (newCurrentFrame != that.currentFrame) {
that.currentFrame = newCurrentFrame;
}
if (that.currentFrame != that.showingFrame) {
that.setFrame();
}
});
});
/* Bind end event to container and remove listener on movement */
that.container.bind(that.scrollEvents.end, function(e) {
e.preventDefault();
that.container.unbind(that.scrollEvents.move);
});
/* Set the selected frame */
that.setFrame = function() {
that.showingFrame = that.currentFrame;
$(that.frames).css('display', 'none').eq(that.showingFrame).css('display', 'block');
};
/* Run through startup */
that.setFrame();
};
});
<html>
<head>
<script type="text/javascript" src="animator.js">
<script type="text/javascript">
$('.animation').animator();
</script>
</head>
<body>
<div class="animation" style="overflow: hidden; position: relative;">
<div class="frame-container" style="position: relative; padding: 0; margin: 0;">
<span style="float: left; display: block; width: 400px; height: 400px;"><img width="400" height="400" src="image1.jpg"></span>
<span style="float: left; display: block; width: 400px; height: 400px;"><img width="400" height="400" src="image2.jpg"></span>
<span style="float: left; display: block; width: 400px; height: 400px;"><img width="400" height="400" src="image3.jpg"></span>
<span style="float: left; display: block; width: 400px; height: 400px;"><img width="400" height="400" src="image4.jpg"></span>
<span style="float: left; display: block; width: 400px; height: 400px;"><img width="400" height="400" src="image5.jpg"></span>
</div>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment