Exploring TypeScript: JQuery Parallax Starfield

Tags: TypeScript

The next TypeScript Sample I’ll explore is the JQuery Parallax Starfield sample.  You can see it running here.  The source that I’ll be describing is here.

This sample creates the effect of a view at a starfield where some of the stars are closer and some others are farther in the distance. The stars that are closer appear to be scrolling faster, and the stars that are farther away scroll more slowly.

The Parallax effect is achieved by scrolling multiple copies of the same image by different factors so that it appears the nearer copies scroll faster than the farther copies. As I go through the code, you’ll understand what I mean in more detail.

 

The HTML Page

Let’s begin by discussing examining the HTML page for this sample.  First, there are several CSS styles that describe how to display each of the images when they are first loaded.  You can see that the #plax<number> styles are quite similar. The difference is the Z index, and the initial background position. The  Z index layers the different images relative to each other . The position provides an initial offset for the images so that each image starts in a different location.

 

<style type="text/css">
   
#plaxHost {
        height: 2000px;
        background-color: Black;
    }
    #plaxHost div {
        width: 95%;
    }
    #plax1 {
        position: fixed;
        color:White;
        height: 2000px;
        background-image: url(starfield2.png);
        top: 0; left: 0;
        z-index: 1;
    }
    #plax2 {
        position: fixed;
        height: 2000px;
        background-image: url(starfield.png);
        background-position: 1087px 0;
        top: 0; left: 0;
        z-index: 2;
    }
    #plax3 {
        position: fixed;
        height: 2000px;
        background-position: 577px 0;
        background-image: url(starfield.png);
        top: 0; left: 0;
        z-index: 3;
    }
    #plax4 {
        position: fixed;
        height: 2000px;
        background-position: 337px 0;
        background-image: url(starfield.png);
        top: 0; left: 0;
        z-index: 4;
    }
    #plax5 {
        position: fixed;
        height: 2000px;
        background-position: 145px 0;
        background-image: url(starfield.png);
        top: 0; left: 0;
        z-index: 5;
    }
</style>

 

Next, the HTML file contains 5 different div tags nested inside another div tag that will hold each of the images:

<div id="plaxHost">
   
<div id="plax1"> &nbsp; </div>
    <div id="plax2"> &nbsp; </div>
    <div id="plax3"> &nbsp; </div>
    <div id="plax4"> &nbsp; </div>
    <div id="plax5"> &nbsp; </div>
</div>

Finally, this references the javaScript files that comprise the application. Notice that this file must include JQuery (because this application uses JQuery). However, notice that it does not include the type definitions for JQuery (read below).

<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.10.1.min.js"></script>
<script type="text/javascript" src="parallax.js"></script>
<script type="text/javascript">
    var p = new Parallax.ParallaxContainer(window, 0.7);
    for (i = 1; i <= 5; ++i) {
        var star_layer = new Parallax.ParallaxSurface(document.querySelector('#plax' + i));
        p.addSurface(star_layer);
    }
</script>

The inline script creates a ParallaxContainer object (defined in parallax.ts). Then, it creates and adds 5 ParallaxSurface objects (also defined in parallax.ts) to the container.

After this script runs, the HTML page contains the five images, and you can scroll the image to see the parallax affect.

The JQuery Type Descriptor

Next, let’s look at jquery.d.ts.  This is a type descriptor for the interfaces and variables this application uses that are part of the JQuery library.  It’s a rather large file, so I won’t repeat it here. You can see the full listing here. This file contains TypeScript definitions for JQueryAjaxSettings, JQueryXHR, JQueryCallback, JQueryPromise, JQueryDeferred, JQueryEventObject, JQueryBrowserInfo, JQuerySupport, JQueryStatic, and JQuery. After defining those interfaces, it declares external variable references for JQuery, and $, both of type JQueryStatic.

You’ll need to create a type descriptor file for any JavaScript library that you use. Or, you’ll need to find one. There’s a great Github project called DefinitelyTyped that contains type definitions for many common JavaScript libraries. These packages are also available as NuGet packages.  If you are using an external JavaScript package, look at this project first. Chances are there are already type descriptors for the library you need. However, if not, you should contribute any type definitions you need to create.

The Parallax.ts file

This file contains the main logic for the application.  There are a few new concepts shown in this file.

The first line directs the TypeScript compiler to reference the jquery.d.ts type descriptor file.

/// <reference path="jquery.d.ts" />

By referencing the type descriptor, this file can use any of the types and variables declared in the type descriptor file without generating any compiler errors.

The types defined in this file are contained in the module Parallax.

 

module Parallax {
   // …...
}

 

That provides encapsulation for those types. To reference one of those types, you must include the module name as a namespace qualifier (see the code above). There are two types defined in this file: the ParallaxContainer and the ParallaxSurface.

The ParallaxContainer demonstrates are couple new TypeScript features:

export class ParallaxContainer {
    private content: HTMLElement;
    private perspective: number;
    private surface: ParallaxSurface[];
    //  …...
}

The export keyword indicates that this class can be referenced outside of this module. The private keyword on the field definitions defines that these variables should not be accessed outside of this type. I say ‘should not’ because you can access these fields in the compiled JavaScript. The TypeScript compiler will generate errors if you access these private fields.

There’s a few other syntax elements that appear in this sample.  You can see the => syntax for a lambda expression:

$(scrollableContent).scroll((event: JQueryEventObject) => {
    this.onContainerScroll(event);
});

And, this snippet shows how TypeScript can directly call JavaScript libraries (JQuery in this snippet).

The onContainerScroll method is a private method that has a void return type:

private onContainerScroll(e: JQueryEventObject): void {

The rest of the code should be familiar at this point.  When you scroll, each of the images scrolls a percentage of the distance based on its z index. You can see that code in the implementation of the oncontainerScroll. 

Add a Comment