Smoothing Slow JavaScript Animation/Parallax


Update: Please note that this article was specifically looking at the issue of smooth parallax and pixel jogging at slow speeds when creating parallax with graphics in the DOM. There are two possible solutions now which are far better than what is discussed in this article. 1. In Safari, Chrome, and Firefox you can use CSS transforms and the translate() function to move your DOM objects with fractional pixel values. 2. If you don't want/need to use the DOM you could always render your parallax effect in a <canvas> tag which also supports fractional pixel values.

And now... the original article:

In both film and computer graphics, the illusion of animation and motion is created by rapidly displaying a series of slightly different still images. This illusion starts to break down for most people somewhere below 30 frames per second (FPS).

The minimum distance an object or image can move in a web browser is one pixel, and the size of a pixel is still large enough to be very much perceptible in most situations. As a consequence, in order to produce smooth, fluid motion, an object moving one pixel at a time must move 30 pixels in one second in order to achieve 30 frames per second animation. That's surprisingly fast movement.

The noticeable stop/start ticking motion of objects moving slower than 30 pixels per second in a web browser has always bugged me. Take for instance this example of parallax scrolling animation of clouds in a sky. The foreground clouds are moving 10 pixels/frames per second. The motion looks good (though not great). Compare this to the background clouds which are moving two pixels/frames per second. They are very jerky.

Digital video is also limited by pixel size. Yet, when you are watching a movie, even very slow objects on screen appear to move smoothly. Digital video has a fixed frame rate usually near the 30 FPS mark. Objects moving slowly across the screen at less than one pixel per frame are simply blurred into neighboring pixels to smooth out the animation transition.

As a sort of proof-of-concept I thought it might be interesting to try to manually recreate this smoothing by fading an image from one pixel to the next as it moves slower than 30 pixels per second across the browser window. You can see the result of this experiment below on the right, side-by-side with the original jerky movement on the left.

My method is far from constituting any sort of generalized solution, but tinkering with this was fun nonetheless. Basically what I am doing is keeping a duplicate of my slow moving object, placing it one pixel ahead of the original object's position, and fading it in. Then I fade out the original. Check out the code on the separate page for this demo. For most practical applications of this I think waiting for some sort of graphic accelerated fractional pixel resampling would be the better option.