The fourth part of this JavaScript kinetic scrolling series shows an implementation of horizontal swipe to browse a gallery of photo. In addition to that, a simple parallax effect will be demonstrated as well.

Scrolling sideways is a common pattern in many application. The ubiquitous example is the home screen of many mobile tablets and phones, where the user needs to swipe left and right to scroll through the choices of many application icons. A typical photo application, even since the very first iPhone, allows the user to view the next and previous picture by a quick swipe. Tabbed view in many Android applications also feature the possibility of flicking to switch tabs (instead of tapping on the tab directly).

A clever tweak to a horizontal swipe interface is the extra parallax effect. It is easier to explain this if you see the Android home screen. As you swipe left/right, you can watch how the icons are moving at a different distance compared to the wallpaper. This gives the impression that the icons are floating in the air, as supposed to stick right on top of the wallpaper.

Another popular application leveraging the parallax effect is the native weather application (iOS and Android) from Yahoo!, as illustrated in the following diagram. In the right screenshot, I am dragging the screen to the right halfway. However, you can see that the black-and-white building does not disappear from the screen. If you look carefully at the left screenshot, that building is in the right-half of the screen. Without any parallax effect, if I push the background halfway, the right-half (and thus also the building) should not be visible anymore.


What does it take to implement this horizontal scrolling using vanilla JavaScript? Apparently, we already have the foundation in place. Dragging to the left/right is not foreign, this basic handling is in the Part 1 of this series. The flick gesture is already covered in Part 2. The fact that the screen needs to snap to the left or the right is simply the snap-to-grid feature, already explained in details in Part 3. What we need to change is the direction of the gesture detection as now we have to move horizontally.

To get the feeling of the implementation, open your browser and navigate to ariya.github.io/kinetic/4. Swipe left and right to scroll through the (wonderful) photos.

The core of the implementation is the three-card system, each represents the left, center, and right photo. Under normal circumstances, the center card occupies the entire view and both the left and right are out of the view. If the user swipes to the right, then we pulls the left card to the view (the center card is behind the left one). In addition to that, we also moves the center card at half the distance for the parallax effect.


The same scenario happens (in the reverse direction) if the user swipes to the left instead. Once the flick gesture is fully completed, we tweak all the three cards so that they all represents the final arrangement. All this logic takes only about 180 lines of JavaScript code (see scroll.js for details).

As an exercise for the reader, try to adjust the parallax implementation so that it faithfully resembles what Yahoo! Weather application does. With that application, you will notice that the new image (from the left or right) which got pulled as you swipe the center image has a peculiar parallax-ness as well. To implement something like this, you can’t use the img element directly as you need to wrap the image in another container, e.g. a div element, and adjust the offset of the image relative to its container. That seems challenging, but it is not too complicated to implement.

I hope this parallax effect is fascinating. See you in Part 5!


Many JavaScript projects are using Mocha to run the unit tests. Combining Mocha with Istanbul and Karma, it is easy to track the code coverage of the application code when running the tests.

While Mocha has a built-in support for running the tests from the command-line via Node.js, in some cases you still want to verify your code with the real web browsers. The easiest way to do that with by using Karma to automatically launch the browsers, control them, and execute the tests. The repository github.com/ariya/coverage-mocha-istanbul-karma shows a simple example on how to do this. To experiment with it, simply clone the repository and then run

npm install
npm test

You should get something like:

Running "karma:test" (karma) task
INFO [karma]: Karma v0.10.8 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [launcher]: Starting browser Firefox
INFO [PhantomJS 1.9.2 (Linux)]: Connected on socket ASrZI0wwAgPFSaxNmDHI
INFO [Firefox 25.0.0 (Ubuntu)]: Connected on socket sBSK-fR9V5s-8pWWmDHJ
PhantomJS 1.9.2 (Linux): Executed 2 of 2 SUCCESS (0.327 secs / 0.023 secs)
Firefox 26.0.0 (Ubuntu): Executed 2 of 2 SUCCESS (0.446 secs / 0.002 secs)
Done, without errors.

The configuration file for Karma, shown below, specifies that the tests should run on PhantomJS and Firefox. Of course, it is also easy to add other browsers.

module.exports = function(config) {
    basePath: '', 
    autoWatch: true,
    frameworks: ['mocha'],
    files: [
    browsers: ['PhantomJS', 'Firefox'],
    reporters: ['progress', 'coverage'],
    preprocessors: { '*.js': ['coverage'] },
    singleRun: true

npm test will run the tests by executing the right Karma task as mentioned inside Gruntfile.js. Note that Grunt is not mandatory here, running Karma directly is as easy as:

node_modules/.bin/karma start karma.conf.js

Just like in the previous coverage examples (using QUnit and Jasmine), the code we want to test is the following simple implementation of the square root function:

var My = {
    sqrt: function(x) {
        if (x < 0) throw new Error("sqrt can't work on negative number");
        return Math.exp(Math.log(x)/2);

The tests for that function are in test/test.sqrt.js. In fact, it is also possible to run the tests manually with a web browser, simply open test/index.html file and you will see the report:


As an exercise, try to remove one test and see what happens as you run the test again. In fact, open the coverage report (look under coverage directory) and you will find the glaring warning from Istanbul, indicating the worrying level of coverage confidence.


Just like a good code coverage tool, Istanbul reports missing branch coverage. This is very important as looking only at the statement coverage may hide some latent bugs.

Now, if make it this far, you are very close to implement full enforcement of coverage threshold.


PageSpeed Module from Google, available for Apache and nginx, is a quick solution to improve web application network performance. As a bonus, if we configure nginx as a proxy server, then it can also serve as a web acceleration solution.

pagespeedThere is a growing number of PageSpeed optimization filters, anything from a straightforward CSS minification to a sophisticated images recompression. If you are already using Apache or nginx, PageSpeed module is relatively easy to use.

A different use case for PageSpeed is as a proxy server which you use for your daily browsing, e.g. what @jedisct1 has implemented via Apache proxy module. In this blog post, I show an alternative setup by using nginx instead, mainly by following the steps described in the ngx_pagespeed project.

Rather that doing things manually, you can just use the automated setup using Vagrant with VirtualBox. Simply clone pagespeed-proxy Git repository and then you only need to run:

vagrant up

For this experiment, the virtual machine is based on Ubuntu 12.04 LTS (Precise Pangolin) 64-bit. If you tweak the configuration inside Vagrantfile to a CentOS-based Vagrant box, e.g. from Opscode Bento collection, it should also work just fine. Should you rather trust your own virtual machine, you can create a Vagrant box from scratch automatically, check out my previous blog post on Using Packer to Create Vagrant Boxes.

The provisioning script of the box takes care the step of downloading the latest nginx and compile it with Google’s PageSpeed module. When it is ready, the script will also launch nginx as a forward proxy at port 8000 (this port is also forwarded and hence the proxy is available for the host machine as well). The proxy will run two optimizations filters (as a starting point): HTML comment removal and JavaScript minification, this can be proved by looking at the provided configuration file nginx.conf:

http {
    server {
        listen 8000;
        server_name localhost;
        location / {
            proxy_pass http://$http_host$uri$is_args$args;
        pagespeed on;
        pagespeed RewriteLevel PassThrough;
        pagespeed EnableFilters remove_comments,rewrite_javascript;
        pagespeed FileCachePath /home/vagrant/cache;

To verify the operation of the optimizing proxy, run these two commands (on the host machine) and observe the different outcomes:

curl http://ariya.github.io/js/random/index.html
curl -x localhost:8000 http://ariya.github.io/js/random/index.html

The second one pipes the original HTML content through the enabled optimization filters, comment removal and script rewrite, and thereby it will result in a smaller page. This is definitely just an illustration, feel free to play with a number of other PageSpeed filters and observe the impacts.

Obviously, it is also possible to setup your web browser to use the proxy at localhost:8000. When looking at the same URL given above, it will result in something like the following screenshot. Again, compare it with the case where you view the page without using the proxy.


For a more practical usage of the proxy, stay tuned!


In the third part of this JavaScript kinetic scrolling series, the so-called snap to grid feature is demonstrated. The implementation is rather straightforward, it is a matter of figuring out where the scrolling should stop and then adjusting that target position to the intended location.

The second part of the series discussed the scrolling deceleration technique by using an exponential decay concept. With a flick list, this means that the list will slow down and stop at some point, depending on the launch velocity at the moment the user releases the grip. It turns out that this also becomes the important key to implement snap to grid.

Note that the exponential decay curve permits us to know about two things (1) when the scrolling will stop (2) where it will stop. As soon as the launch velocity is known, these two values can be computed analytically. This is very powerful, in particular since the final stop position can be adjusted right away. For a quick live demo, go to ariya.github.io/kinetic/3 (preferably using your smartphone browser), flick the list, and see how it always stops to align the color entry to the overlaid slot.

The following diagram illustrates the concept. Without any snap to grid, the curve of the scrolling position as a function of time is depicted in the gray line. Let us assume that the final position will be at 110 px. If we know that the snapping grid is every 25 px, then that final position needs to be adjusted either to 100 px or 125 px. Since the former is the closest, that will be the ultimate final position and the deceleration will follow the curve colored in blue.


The relevant code for this feature can be seen in the repository github.com/ariya/kinetic. Really, it is not much different than the code shown already in the previous second part. The new addition is this following fragment:

target = Math.round(target / snap) * snap;

The variable snap here stores the row height of each item (it is computed once during the initialization). If you already familiarize yourself with the exponential decay implementation, target contains the final scrolling position when the deceleration finishes. Without snapping feature, we don’t tweak this value. When we want to adjust the final scrolling position to be magnetically anchored to nearest snapping location, then we simply change this value.

Also, observe that there is no requirement that snap has to be a constant. A list with non-uniform row height can still enjoy snap to grid feature. All we need is an array of possible values for the final position and every deceleration target must be modified to the closest value. In case you study physics, this is quite similar to the idea of discrete packets of electromagnetic energy in quantum mechanics.

In some libraries which implement kinetic scrolling, snap to grid is implemented by continuously tracking the scrolling position. When it is about to stop, then the position is adjusted to move to the closest possible position based on the grid distance. Not only this results in a more complicated code, such an approach has a major drawback. In some cases, the list can overshoot before it bounces back and therefore it does not demonstrate a smooth scrolling effect at all. With the analytical technique described here, this awkward effect will not happen at all. As always, a proper solution often comes with the cleanest implementation!

What will be shown in the fourth part? Let’s keep it as a surprise!



It is getting colder, it starts to feel like winter. Right when it will be warmer again slowly, it is time for me to give another round of tech talks.

My first stop is Atlanta, for DevNexus 2014, February 24-25 (follow @devnexus to get all updates). It is not in California, so I expect a true end-of-winter experience. For DevNexus, I’ll have two talks on Tweaking CSS3 for Hardware Acceleration and JavaScript API Design Principles.

If you can’t be in Atlanta, I plan to give another Design Strategies for JavaScript API presentation for the evergrowing Fluent 2014 in San Francisco, March 11-13. I spoke at this wonderful conference twice already, every year was wonderful. Follow @fluentconf for more information on this 2014 edition. If you decide to attend it, it is also packed with other awesome talks.

Last but not least, EclipseCon NA 2014 will be held in Burlingame, March 17-20 (make sure to track @eclipsecon). This time, I will use the opportunity to continue my campaign for a better development experience with the talk titled Next-generation JavaScript Language Tooling. There is a healthy growing front-end developers using Eclipse and expect to see more talks related to JavaScript at this conference.

If you plan to be in Atlanta, San Francisco, or Burlingame, let’s have a chat!

Update: I will be also at jQuery Conference 2014 in San Diego, Feb 12-13. At this conference, my presentation will be about Dynamic Code Analysis for JavaScript. This will be my first jQuery event and I’m pretty excited about that.


In the second part of this series of JavaScript kinetic scrolling example, the inertial effect is implemented. This is done by tracking the movement while the user is still dragging the view and then automatically scroll the view until it stops at some point.

The first part already covered the basic drag-and-scroll technique (if you have not read it yet, please do so because the concept will be reused here). Before we add the kinetic effect, let us see first what happens to the scroll offset of a list view as the user taps, drags, and releases his finger.


The shaded area in the above diagram is when the user still manually controls the list, he scrolls up and then down and then up again. Right when this user finally releases his finger, the list starts to enter the automatic scrolling mode. During this mode, the list starts moving at a certain speed but then it slows down and then eventually it comes to a halt. To carry out the automatic scrolling, it is important to figure out the initial velocity right at that release moment. This is done by tracking the finger position and computes the velocity, this happens between the tap and release.

If this kinetic scrolling is implemented properly, what we would get is something depicted in the following animation (GIF, forgive the quality). Should you want to play with the live demo, go to ariya.github.io/kinetic/2 with your favorite modern smartphone. Pay attention to the smooth scrolling as you flick the list. Note that it does not have edge bouncing feature yet, we will cover this in some future episode.

How to track the velocity while the user is still dragging and scrolling the list? A simple approach, among a billion possibilities, is to use a periodic timer. When the timer fires, retrieve the current position and use it to compute the velocity. Empirically, tracking the position 10 times per second (a timer interval of 100 ms) proves to be sufficient.

This tracking activity shall start as soon as the user initiates the tap, hence we modify our tap() function implementation to look like the following. The key here is that the function track() which will be invoked repeatedly as long as we still want to track the velocity.

function tap(e) {
    pressed = true;
    reference = ypos(e);
    velocity = amplitude = 0;
    frame = offset;
    timestamp = Date.now();
    ticker = setInterval(track, 100);
    return false;

The code for track() is quite short. The idea is to compare the current position and time to the previous recorded position and time, frame and timestamp, respectively. From this delta, the instantaneous velocity v is easily obtained. The last line acts as a simple moving average filter, this protects us from any wild variation, either from the user’s own erratic movement or from other input noise.

function track() {
    var now, elapsed, delta, v;
    now = Date.now();
    elapsed = now - timestamp;
    timestamp = now;
    delta = offset - frame;
    frame = offset;
    v = 1000 * delta / (1 + elapsed);
    velocity = 0.8 * v + 0.2 * velocity;

The track() function plays its role during the manual dragging (the shaded part in the previous diagram). Once the user releases his finger from the touch device, the situations changes dramatically. Now we have to use the computed launch velocity to decide the next move, as evidenced from the implementation of the following function.

function release(e) {
    pressed = false;
    if (velocity > 10 || velocity < -10) {
        amplitude = 0.8 * velocity;
        target = Math.round(offset + amplitude);
        timestamp = Date.now();
    return false;

Compared to the original code (in Part 1), there is additional block to trigger the automatic scrolling, autoScroll function. The threshold speed of 10 pixels/second is used to prevent any automatic scrolling if the velocity is too low. The launch velocity is used to compute where the scrolling needs to stop, this is the purpose of the amplitude variable. The factor 0.8 is tweakable. If you want to make the list feel "heavy" reduce the number. Consequently, a higher factor will give the illusion of a smooth and frictionless list. Updating the scroll offset is the responsibility of autoScroll() function. Note how this is trigger using requestAnimationFrame for a jankfree animation.


A typical flick list has a deceleration that is a form of exponential decay. In other words, the deceleration system is just an overdamped spring-mass system. Fortunately, it is a standard differential equation and its solution is rather straightforward (ŷ is the target position, A is the amplitude, t is the current time, τ is the time constant).

The math may look scary but the actual code is not that complicated. As long as this autoScroll() function still needs to move the list by more than 0.5 pixel, it will be repeatedly invoked. In fact, the following lines of code (it is indeed quite short, isn’t it?) is the heart of this well-known deceleration effect.

function autoScroll() {
    var elapsed, delta;
    if (amplitude) {
        elapsed = Date.now() - timestamp;
        delta = -amplitude * Math.exp(-elapsed / timeConstant);
        if (delta > 0.5 || delta < -0.5) {
            scroll(target + delta);
        } else {

The value of timeConstant here is quite important. If you want to really mimic iOS (in its UIWebView, decelerationRate normal), the suggested value is 325. This corresponds to a time constant of 325 ms. Math geeks may also realize that with the animation interval of 16.7 ms (from 60 fps), this automatic scrolling effectively reduces the scrolling velocity by a factor of 0.95, which is Math.exp(-16.7 / 325), until it barely moves and therefore the scrolling is stopped completely.

Just to emphasize again, the chart of position as a function of time for this deceleration is depicted below, created using Google plot 150*(1-exp(-t/325)). You may have seen the tail (last part) of the first diagram showing this kind of exponential decay curve.


Note that this kind of automatic scrolling also means that the scrolling will stop, regardless of the initial velocity computed earlier, after approximately 1.95 seconds (6 * 325). System theory tells us that after the duration of 6x the time constant, the position will be within 0.25% of the target position (mathematically, you can get that from calculating Math.exp(-6)). Thus, by choosing the time constant, you can make the list feel light or heavy, depending on your need.

How about the rest of the code? It is, surprisingly, still the same as the one presented in first part. There is no need to modify drag() function because the behavior is still the same. Also the helper functions need not change at all. Recycling always feels good!

To see the full JavaScript code (roughly 130 lines), check the repository github.com/ariya/kinetic/. It has been tested on Android 4.3 or later (Chrome, Firefox), Android 2.3 (Kindle Fire), and iOS 6 or later (Mobile Safari). Also, as I mentioned in the beginning of this series, treat this example code as an example, nothing more and nothing less (it is optimized for readability and less on performance). Use the basic knowledge to inspire you to write, implement, and tweak your own variant of kinetic scrolling. That said, it doesn’t mean that this particular code is really slow. With Nexus 4 and Nexus 7, there is no problem of hitting 60 fps most of the time. This can also be verified by looking at the detailed frame statistics (using Chrome Developer Tools). Obviously, the painting time HUD is also very useful in this analysis.

The physics effect has fascinated many developers since iPhone popularized the concept. In fact, the web-oriented implementation of this concept exists in various forms (virtually in all mobile-focused libraries), from the early PastryKit edition to a dedicated microlibrary such as FTScroller. If you are always curious about the math and the physics behind it, I hope my explanation above shows that there is nothing really mystical about it.

In the third part, an important feature will be shown: snap to grid.
Update: It is published, please enjoy Part 3.