Using RxJs for an Image Rotator with jQuery by ThinqLinq

Using RxJs for an Image Rotator with jQuery

In trying to come up with some compelling demos for RxJs, I happened upon a scenario that some of you may find helpful. I wanted to create the ability to display images on a timer loop and keep looping through them while the user is on the page. I realize that there are a plethora of jQuery plugins that do this already, but  I have a new hammer (RxJs), I might as well see how well it works myself.

As I did in my port of the ObservableSensor in the last RxJs post,  let’s start by defining the presentation portion:

<!DOCTYPE html>
<html>
<head>
     <title>Observable Rotator</title>
     <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
     <script type="text/javascript" src="Scripts/rx.js"></script>
</head>
<body>
     <img id="imageRotator" alt="rotating" />
</body>
</html>

Clean and simple HTML5, except I didn’t set the source of the image. We’ll do that in our JavaScript code instead. Let’s get right to it then:

<script type="text/javascript">
    $(function () {
        var images = ["Images/image1.png",
                    "Images/somethingElse.png",
                    "Images/someAd.png",
                    "Images/JimHeadShot.jpg",
                    "Images/logo.gif"
                    ];

        $("#imageRotator").attr("src", images[0]);

        var delayedSites = Rx.Observable.GenerateWithTime(
             1,                                           // Starting index
            function (x) { return true; },                // Keep iterating always
            function (index) {               
                if (index < images.length - 1) 
                    return index + 1;                     // Increment index
                else
                    return 0; // if the current index exceeds the array bounds, reset the index 
            },
            function (index) { return images[index]; },  // OnNext
            function () { return 5000 });                // Time interval


        delayedSites
            .Subscribe(function (uri) {
                $("#imageRotator").attr("src", uri);
            });
    });
</script>

The start of this method should be easy enough. I’m setting up an array containing the locations of the images I want to rotate through. Of course, you could get this array from a xml file, json service request, using the FileSystemObject, or any number of other options. It doesn’t matter how you get the array.

Once we have the array, we’ll go ahead and populate the first item in that array as the starting image using the jQuery attr method setting the src attribute to images[0].  With that out of the way, we’re ready to start with the RxJs goodness.

In order to push out items from our array, we could use Rx.Observable.FromArray which is the same as the .ToObservable extension method in .Net, however we would need to set-up a custom scheduler to handle the delay. Instead, we’ll just use the GenerateWithTime method to pull items from the array OnNext passing in a time delay (30000 for 30 seconds). We also check to see if the current iteration index exceeds the number of items in the list and if so, reset the index to start looping from the start again.

Now that we are sending out new image uri’s every 30 seconds, we simply need to change the src attribute of the imgageRotator img tag, which we’ll do as the function we pass into the Subscribe method.

Naturally, there are plenty of enhancements that can be done to this example, including randomizing the starting index, setting the size of the imageRotator to keep all of them the same, adding jQuery fadeIn/fadeOut and other animation effects, etc. I’ll leave these tasks as an exercise for the reader.

My question dear reader is, do you thinq that the RxJs version is any better or worse that other image rotator examples you’ve seen? Why?

Posted on - Comment
Categories: JQuery - Rx -
comments powered by Disqus