Stop Motion Animation

Content © AEO All Rights Reserved.

Edit The Settings!

If Min and Max values are in conflict, a default value will be used.

If 0, no preview will be shown.
Percentage will automatically max out when preview width matches container width.

Reload Widget

More Info...


The Stop Motion carousel presents products dynamically and attractively, introducing a unique movement to the images without the burden of using videos. The application offers a versatile framework that can be effortlessly customized by business users using a simple data object.


Following years of the consistent "Jean Guide" appearance, AEO sought a change. Through collaboration with the design team, I developed a dynamic and scalable solution applied across various product categories. A notable achievement was eliminating the requirement for engineering resources to facilitate new instances or modifications.



Each model was filmed executing a simple movement, such as shifting their weight or moving their hands or legs. Ten frames were then chosen to serve as a repeatable and reversible motion.


Only one frame of the sprite is visible, with the rest being masked. The sprite is moved both up and down, creating the illusion of a moving image, similar to a GIF. Ensuring natural-looking movement in reverse enables us to derive two animations from a single sprite.

Setting the Size

A requirement is that each sprite has a uniform width and height. Moreover, the overall height of the sprite is incorporated, enabling the code to animate through the total number of frames unique to each sprite. These values can be easily adjusted within the code to accommodate a variety of ratios. While the sprites are not responsive, they are adaptive. Depending on the adjustable viewport, the number of visible sprites will adapt to accommodate any device width. Similarly, the draggable preview window will adjust and toggle visibility based on the viewport.

Technical Details

Building the Guide

By setting several properties, the user can decide the following:

  • Speed of frame animation
  • Minimum delay between animations
  • Maximum delay between animations
  • Display and size of preview window
  • Animating the intro of the guide on load
  • Display of scrollbar
  • Bounce animation of carousel arrows
  • Fading sprites based on viewport
  • Frame width and height
  • Sprite height
  • Sprite heading
  • Linking out to a URL
  • Image URL
  'speed': 100,
  'minInterval': 0,
  'maxInterval': 2.5,
  'preview': 30,
  'intro': true,
  'scrollbar': false,
  'bounce': false,
  'fade': false,
  'imgWidth': 144,
  'imgHeight': 365,
  'linkTo': false,
  'sprites': [
      "copy": "Sky High Jegging",
      "catId": "cat7010082",
      "imgSrc": "/projects/stop-motion/images/skyhighjegging.jpg",
      "imgHeight": 3650

Data Object

Each sprite is coded as a data object in the application. The system tracks the position and direction of the current sprite animation. Furthermore, it ensures that each sprite within the viewport completes one animation cycle before any sprite is animated for a second time.

for (var i = 0; i < animationCount; i++) {
  animations[i].leftPosition = Math.round($(animations[i]).position().left);
  animations[i].rightPosition = Math.round(animations[i].leftPosition + parseInt(animationOuterWidth, 10));
  animations[i].sprite = $(animations[i]).find('img');
  animations[i].frame_count = Math.round($(animations[i].sprite).attr('height') / animationHeight);
  animations[i].top_pos = 0;
  animations[i].hasPlayed = 0;
  animations[i].loopCount = 1;


To provide a more organic feel to the guide, two aspects have been randomized. Firstly, the timing between sprite animations is set with minimum and maximum values. A randomized value within this range is selected each time to prevent the user from becoming accustomed to a specific pace. Additionally, the order in which the sprites animate is also randomized.

//Create Random Delay Between Animations
function randomizeInterval() {
  randomized = true;

  var randomInterval = Math.floor(Math.random() * (animationData.maxInterval * 10 - animationData.minInterval * 10) + animationData.minInterval * 10) * 100;

  animationDelay = setTimeout(function() {
  }, randomInterval);
//Create Random Number for Animated Element
function randomizeNumber(){
  activeAnimation = Math.floor((Math.random() * animationCount));