Showing posts with label progress bar. Show all posts
Showing posts with label progress bar. Show all posts

Friday, 9 January 2015

The Bowline Bend Analogy

Following the web tutorial for the Wayang Progress Bar posted last year, I received some feedback from a reader. And because I take all feedback seriously (OK fine, I take some feedback seriously) I've decided to dedicate a blog post to this.

The reader stated that she did not bother with the tutorial because the end result wasn't something she would use anyway - if a page takes more than 10 seconds to load, she'd consider it a failure. That point of view is valid; however, she may be approaching this from the wrong angle.

To explain my statement, I'm going to use what I call the Bowline Bend Analogy.

The What?

Back in 1999, I was a crew member on board a warship in the Republic of Singapore Navy. The Executive Officer (XO) decided to test one of the Junior Officers (JO).

XO: What's the Bowline used for?
JO: To make a non-slip loop, Sir.
XO: Can the Bowline be used to join two lines?
JO: Er...
XO: Corporal, can the Bowline be used to join two lines?
Me: Yes Sir.

This is a Bowline

Later, the Junior Officer pressed me for details for the question he was tested with earlier.

JO: How can the Bowline be used to join two lines? It's not a joining knot, it's a loop knot!
Me: You just tie two Bowlines and interlock them, Sir.
JO: What the hell?! That's a trick question!
Me: Well, yes and no. Yes in the sense that it tests your knowledge of the Bowline and all other loop knots, and no in the sense that there actually is such a knot...
JO: Yes, fine, whatever.


This is a Bowline Bend


Two interlocking Bowlines, otherwise known as the Bowline Bend, was actually a valid way to join two lines. It leveraged on the excellent breaking strength of the Bowline to create a knot with similar breaking strength. Its use has been somewhat deprecated as there have been found equally sound ways of joining lines without using that much rope. But, in order to understand the use of the Bowline Bend, first, one has to have a pretty good grasp of the Bowline! In other words, you can't tie a Bowline Bend without first knowing how to tie a Bowline. And while the Bowline Bend isn't that useful, the Bowline certainly is.

The Junior Officer wasn't being tested on his ability to tie a Bowline. Any crewman, right down to the lowliest Private, can tie a crummy Bowline. He was being tested on his understanding of how the Bowline worked. He didn't need to learn how to tie a Bowline Bend. He only needed to know that such a thing was possible.

And back to the Wayang Progress Bar...

That's where the web tutorial comes in.

You may not think you need a Wayang Progress Bar. In fact, you may never need a Wayang Progress Bar. But the whole point wasn't about the Wayang Progress Bar. The Wayang Progress Bar leveraged on several smaller building blocks that were combined in a certain way for the final product, much the same way that two Bowlines were combined to give you the Bowline Bend!

Therefore, the whole point here was to learn all the little snippets (HTML, CSS, JavaScript) that made up the final product. In future, these building blocks can be used to make something else altogether. And that, again, was the real point of the exercise.

Keep your feedback coming. I will knot turn you away!
T___T

Friday, 14 November 2014

Web Tutorial: The Wayang Progress Bar (Part 4/4)

We've reached the last part of this web tutorial, and in this one, we're going to make your Wayang Progress Bar load more realistically.

Realistic how?

Well, take a look at your bar. It moves very predictably. One pixel at a time, one percentage at a time, just as it's programmed to in the JavaScript. But in real situations, the page doesn't load like that. Sometimes it loads some things faster, sometimes it takes more time with other components. To simulate that, we're going to add a random element to your animation.

Change the following line in the process_loader() function of your JavaScript:
                function process_loader(varloadercontent)
                {
                    var inc=Math.floor((Math.random() * 50) + 1);
                    var marginleft = document.getElementById(varloadercontent).style.marginLeft;
                    marginleft=marginleft.replace("px","");
                    marginleft=parseInt(marginleft)+inc;

                    if (marginleft>=0)
                    {
                        document.getElementById(varloadercontent).style.marginLeft="-5px";
                        document.getElementById(varloadercontent+"_text").innerHTML="Loading 95%"+dots;
                    }
                    else
                    {

                        var percent=(((500+marginleft)/500)*100).toFixed(0);
                        document.getElementById(varloadercontent+"_text").innerHTML="Loading "+percent+"%"+dots;
                        document.getElementById(varloadercontent).style.marginLeft=marginleft+"px";
                    }
                }

Now reload. What do you see? Your progress bar now loads unpredictably. Sometimes it goes faster, and sometimes it goes slower. That's because the inc variable was originally set to 1. So your bar moved one pixel at a time. With this change, you've basically told your JavaScript to move the bar one to fifty pixels each time!

For more about JavaScript random number functions, click here. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

Final touch!

Now for the next bit of fun. Do you feel that your bar is moving a little jerkily? It probably wasn't obvious when it was moving one pixel at a time, but now that it surges forward up to fifty pixels any time, you can see it.

So let's smoothen the animation a bit. Add these lines to your CSS.
            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #ff4444; /* Old browsers */
                background: -moz-linear-gradient(top, #ff4444 0%, #ff9e9e 52%, #ff4444 100%); /* FF3.6+ */
                background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff4444), color-stop(52%,#ff9e9e), color-stop(100%,#ff4444)); /* Chrome,Safari4+ */
                background: -webkit-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Chrome10+,Safari5.1+ */
                background: -o-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Opera 11.10+ */
                background: -ms-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* IE10+ */
                background: linear-gradient(to bottom, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* W3C */
                filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff4444', endColorstr='#ff4444',GradientType=0 ); /* IE6-9 */
                transition: margin-left 1s;
  
            }

What we've done here is to tell your browser to render the changes incrementally over the space of one second, instead of moving your bar immediately. See what a difference this makes?

Here's an excellent tutorial on CSS3 Transitions. http://www.w3schools.com/css/css3_transitions.asp

And we're done!

The Wayang Progress Loader is meant for those situations where your HTML page is loading slowly (due to an image-intensive gallery or a very long-winded article) and you need the user to be patient.

Couldn't I just have done this in jQuery?

Dear Lord, please tell me you're joking. Of course you could have done it in jQuery or Mootools. But to load the jQuery library just to produce a simple piece of code like this? That's excessive. And nowhere as fun. Sure, you could have pulled this out of jQuery's long list of functions and utilities. But it would have saved you a couple minutes at best, and it isn't the same as knowing how to do it yourself.


Keep it real,
T___T

Wednesday, 12 November 2014

Web Tutorial: The Wayang Progress Bar (Part 3/4)

So now you have a working Wayang Progress Bar. (Hey it works, OK? Just not the way the typical user thinks it works.) What's next?

Numerical representation!

But why? I hear you wail. Well, some people just wanna watch the world burn need to see figures. Trust me, it adds value to your wayang.

So make the following changes to your code - CSS, JavaScript, HTML.
<!DOCTYPE html>
<html>
    <head>
        <title>Progress Loader test</title>
        <style type="text/css">
            .loader_box
            {
                width: 500px;
                height: 20px;
                border: 1px solid #777777;
                border-radius: 9px;
                overflow: hidden;
                margin-left: auto;
                margin-right: auto;
            }

            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #ff4444; /* Old browsers */
                background: -moz-linear-gradient(top, #ff4444 0%, #ff9e9e 52%, #ff4444 100%); /* FF3.6+ */
                background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff4444), color-stop(52%,#ff9e9e), color-stop(100%,#ff4444)); /* Chrome,Safari4+ */
                background: -webkit-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Chrome10+,Safari5.1+ */
                background: -o-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Opera 11.10+ */
                background: -ms-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* IE10+ */
                background: linear-gradient(to bottom, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* W3C */
                filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff4444', endColorstr='#ff4444',GradientType=0 ); /* IE6-9 */           
            }

            .loader_wrapper
            {
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.8);
                position: fixed;
                z-index: 600;
                top: 0px;
                left: 0px;
                padding-top: 50px;
                display: none;     
            }

            .loader_text
            {
                width: 500px;
                height: 20px;
                text-align: center;
                font-size: 14px;
                font-family: arial;
                color: #FFFFFF;

                margin-left: auto;
                margin-right: auto;
            }
        </style>

        <script>
            var loader;
            dots=".&nbsp;&nbsp;";

            function start_loader(varloader)
            {
                document.getElementById(varloader+"_wrapper").style.dislay="block";
                loader=setInterval(function () {process_loader(varloader+"_content")}, 500);

                if (dots==".&nbsp;&nbsp;")
                {
                    dots="..&nbsp;";
                }
                else if (dots=="..&nbsp;")
                {
                    dots="...";
                }
                else if (dots=="...")
                {
                    dots=".&nbsp;&nbsp;";
                }


                function process_loader(varloadercontent)
                {
                    var inc=1;
                    var marginleft = document.getElementById(varloadercontent).style.marginLeft;
                    marginleft=marginleft.replace("px","");
                    marginleft=parseInt(marginleft)+inc;

                    if (marginleft>=0)
                    {
                        document.getElementById(varloadercontent).style.marginLeft="-5px";
                        document.getElementById(varloadercontent+"_text").innerHTML="Loading 95%"+dots;
                    }
                    else
                    {

                        var percent=(((500+marginleft)/500)*100).toFixed(0);
                        document.getElementById(varloadercontent+"_text").innerHTML="Loading "+percent+"%"+dots;

                        document.getElementById(varloadercontent).style.marginLeft=marginleft+"px";
                    }
                }
            }

            function stop_loader(varloader)
            {
                 clearInterval(loader);
                 document.getElementById(varloader+"_wrapper").style.dislay="none";
            }
        </script>
    </head>

    <body>
        <div id="loader_wrapper" class="loader_wrapper">
            <div id="loader" class="loader_box">
                <div id="loader_content" class="loader_content" style="margin-left:-500px;">

                </div>
            </div>
            <br />
            <div id="loader_content_text" class="loader_text">

            </div>

        </div>

        <script>
            start_loader("loader");
        </script>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

        <script>
            //stop_loader("loader"); COMMENT THIS CODE OUT SO YOU CAN SEE WHAT'S HAPPENING.
        </script>
    </body>
</html>

Now run the code. This is what you should be seeing...

What did I just do?

You added a placeholder with id loader_text just under the loader_box. But still within the loader_wrapper div. And then you styled it as follows...

width: 500px - to match the width of loader_box.
height: 20px - well you may not really need this, but I'm a bit of a control freak.
text-align: center - because it would look weird otherwise.
font-size: 14px - what nice big font you have, grandma.
font-family: arial - because I fucking love arial. Shut up.
color: #FFFFFF - nice contrast to that black background.
margin-left: auto,margin-right: auto - centers it nicely within loader_wrapper.


And then you added a global variable dots to your JavaScript, and set an initial value of <dot><space><space>. Then a long-ass chained If-Else statement that masically changes the value of dots to the next applicable value. So as your text animation progresses and even when it stops moving because it's reached the end, the dots will keep animating. Clever, eh?

Next, you modified the If-Else statement in the process_loader() function to display a "Loading <percentage>%..." string which will change according to how far the loader_content div has moved from its original margin-left property of -500px!

I bet that was a lot to take in. Note that all of this is absolutely optional. So if you made it this far, give yourself a pat on the back... and roll those sleeves up because we've got more to do.

Next...

Making your Wayang Progress Bar move more realistically. (Yes it's fake, but the users don't have to know that)

Web Tutorial: The Wayang Progress Bar (Part 2/4)

Now that we have your Wayang Progress Bar, here's the next step: how to present it, and how to turn it off.

Firstly, we're going to add some filler content to the existing page, so that you can get a nice visual of what the final result looks like.

Add this markup code to your page.
    <body>
        <div id="loader" class="loader_box">
            <div id="loader_content" class="loader_content" style="margin-left:-500px;">

            </div>
        </div>

        <script>
            start_loader("loader");
        </script>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

    </body>


The result:


Next, what we're going to do may be a little tricky for a CSS beginner. We're going to place a layer over the entire screen, and plonk your Wayang Progress Bar right in the middle.

Make these amendments to your CSS and HTML.
<!DOCTYPE html>
<html>
    <head>
        <title>Progress Loader test</title>
        <style type="text/css">
            .loader_box
            {
                width: 500px;
                height: 20px;
                border: 1px solid #777777;
                border-radius: 9px;
                overflow: hidden;
                margin-left: auto;
                margin-right: auto;
            }

            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #ff4444; /* Old browsers */
                background: -moz-linear-gradient(top, #ff4444 0%, #ff9e9e 52%, #ff4444 100%); /* FF3.6+ */
                background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff4444), color-stop(52%,#ff9e9e), color-stop(100%,#ff4444)); /* Chrome,Safari4+ */
                background: -webkit-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Chrome10+,Safari5.1+ */
                background: -o-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Opera 11.10+ */
                background: -ms-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* IE10+ */
                background: linear-gradient(to bottom, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* W3C */
                filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff4444', endColorstr='#ff4444',GradientType=0 ); /* IE6-9 */  
       
            }

            .loader_wrapper
            {
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.8);
                position: fixed;
                z-index: 600;
                top: 0px;
                left: 0px;
                padding-top: 50px;      
            }

        </style>

        <script>
            var loader;

            function start_loader(varloader)
            {
                loader=setInterval(function () {process_loader(varloader+"_content")}, 500);

                function process_loader(varloadercontent)
                {
                    var inc=1;
                    var marginleft = document.getElementById(varloadercontent).style.marginLeft;
                    marginleft=marginleft.replace("px","");
                    marginleft=parseInt(marginleft)+inc;

                    if (marginleft>=0)
                    {
                        document.getElementById(varloadercontent).style.marginLeft="-5px";
                    }
                    else
                    {
                        document.getElementById(varloadercontent).style.marginLeft=marginleft+"px";
                    }
                }
            }
        </script>
    </head>

    <body>
        <div id="loader_wrapper" class="loader_wrapper">
            <div id="loader" class="loader_box">
                <div id="loader_content" class="loader_content" style="margin-left:-500px;">

                </div>
            </div>
        </div>

        <script>
            start_loader("loader");
        </script>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

    </body>
</html>

The result:

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
What we've done is to determine where your Wayang Progress Bar sits when visible. And now we're going to turn it invisible, which will be the default state.

Add the following code to your CSS.

            .loader_wrapper
            {
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.8);
                position: fixed;
                z-index: 600;
                top: 0px;
                left: 0px;
                padding-top: 50px;
                display: none;     
            }

And viola! All that's left is your Lorem Ipsum filler content. Now we're going to include code to turn your Wayang Progress Bar visible when the page loads, and then turn it invisible again when the page is done loading.

Modify your JavaScript and HTML as shown below:
<!DOCTYPE html>
<html>
    <head>
        <title>Progress Loader test</title>
        <style type="text/css">
            .loader_box
            {
                width: 500px;
                height: 20px;
                border: 1px solid #777777;
                border-radius: 9px;
                overflow: hidden;
                margin-left: auto;
                margin-right: auto;
            }

            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #ff4444; /* Old browsers */
                background: -moz-linear-gradient(top, #ff4444 0%, #ff9e9e 52%, #ff4444 100%); /* FF3.6+ */
                background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff4444), color-stop(52%,#ff9e9e), color-stop(100%,#ff4444)); /* Chrome,Safari4+ */
                background: -webkit-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Chrome10+,Safari5.1+ */
                background: -o-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Opera 11.10+ */
                background: -ms-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* IE10+ */
                background: linear-gradient(to bottom, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* W3C */
                filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff4444', endColorstr='#ff4444',GradientType=0 ); /* IE6-9 */           
            }

            .loader_wrapper
            {
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.8);
                position: fixed;
                z-index: 600;
                top: 0px;
                left: 0px;
                padding-top: 50px;
                display: none;     
            }
        </style>

        <script>
            var loader;

            function start_loader(varloader)
            {
                document.getElementById(varloader+"_wrapper").style.dislay="block";
                loader=setInterval(function () {process_loader(varloader+"_content")}, 500);

                function process_loader(varloadercontent)
                {
                    var inc=1;
                    var marginleft = document.getElementById(varloadercontent).style.marginLeft;
                    marginleft=marginleft.replace("px","");
                    marginleft=parseInt(marginleft)+inc;

                    if (marginleft>=0)
                    {
                        document.getElementById(varloadercontent).style.marginLeft="-5px";
                    }
                    else
                    {
                        document.getElementById(varloadercontent).style.marginLeft=marginleft+"px";
                    }
                }
            }

            function stop_loader(varloader)
            {

                 clearInterval(loader);
                 document.getElementById(varloader+"_wrapper").style.dislay="none";
            }
        </script>
    </head>

    <body>
        <div id="loader_wrapper" class="loader_wrapper">
            <div id="loader" class="loader_box">
                <div id="loader_content" class="loader_content" style="margin-left:-500px;">

                </div>
            </div>
        </div>

        <script>
            start_loader("loader");
        </script>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

        <script>
            stop_loader("loader");
        </script>
    </body>
</html>

And you're done! Sit back and watch the show.

Not displaying?

I thought that might happen. The start_loader() function takes effect after 500 milliseconds. But if your page is done loading within 500 milliseconds, the stop_loader() function kills it! So all you're going to see (if you're lucky) is a flash of black. In order to actually see your code working, you need to replace the filler content with something more substantial, like an entire gallery of images.

In any case, this is more like what you should be seeing.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Next...

Adding more visual input to your Wayang Progress Bar. The code can be used and is fully functional. But we're not done yet, sunshine! If you're gonna wayang, be professional about it! We're going to value-add!

Tuesday, 11 November 2014

Web Tutorial: The Wayang Progress Bar (Part 1/4)

In my University days, we studied HCI (Human-Computer Interaction). And somewhat unavoidably, we learned from a charming gentleman by the name of Peter Bickford, an expert in the field. I quote him below:

Switching to a watch cursor during the wait delayed the subject's departure for about 20 seconds. An animated watch cursor was good for over a minute, and a progress bar would keep them waiting until the Second Coming - or Windows 98, whichever came first.

More at http://web.archive.org/web/20040913083444/http://developer.netscape.com/viewsource/bickford_wait.htm#bio

Granted, this was maybe two decades ago, but his words still hold true. However, to keep this up-to-date, we'll need to roughly halve the waiting times mentioned. This is the iPad generation. Bandwidth and data transfer speeds have quadrupled. Instant gratification is the in-thing. People are getting used to obtaining information with a swipe of the finger. These days, it takes roughly 2 to 5 seconds of waiting time before the user will turn to you and holler "Ah hia! Your website broken lah, dey!"

With that in mind, we're going to create a Progress Bar. Ostensibly, this displays how much of the current page has been loaded, and should keep the user content to wait. Except that this isn't a real loader. It's just an animated bar designed to harness the user's attention span. Hence, what I like to refer to as the Wayang Progress Bar. If you're neither Singaporean nor Indonesian and don't know what wayang is, wayang kulit is a form of shadow puppetry which originated in Java, Indonesia, and essentially means, in local parlance, "purely for show".

Shadow Puppet

And that's exactly what the Wayang Progress Bar is; purely for show. It won't speed up your website, nor will it actually display how much of the site has loaded. Its purpose is merely to stall the user till your page is done loading!

This Wayang Progress Bar will have no graphics, because graphics take time to load and the whole point of the Wayang Progress Bar would be lost if it significantly increased waiting time. Instead, we'll be leveraging heavily on HTML, CSS and JavaScript.

This is your layout:
<!DOCTYPE html>
<html>
    <head>
        <title>Progress Loader test</title>
    </head>

    <body>
        <div id="loader" class="loader_box">
            <div id="loader_content" class="loader_content" style="margin-left:-500px;">

            </div>
        </div>
    </body>
</html>

Now add the CSS declaration to the head tag.
<!DOCTYPE html>
<html>
    <head>
        <title>Progress Loader test</title>
        <style type="text/css">
            .loader_box
            {
                width: 500px;
                height: 20px;
                border: 1px solid #777777;
                overflow: hidden;
            }

            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #440000;        
            }
        </style>

    </head>

    <body>
        <div id="loader" class="loader_box">
            <div id="loader_content" class="loader_content" style="margin-left:-500px;">

            </div>
        </div>
    </body>
</html>

This is how it's going to look like at the moment:



Nothing fantastic, huh? Just a long rectangle. Not to worry, we're just getting started! 500 pixels is a rough guide. You may want to make the progress bar longer or shorter, but you'll need to adjust the margin-left property of the loader_content div tag accordingly.

Now, add this JavaScript snippet to your header tag. Also, add the JavaScript event handler to your HTML.
<!DOCTYPE html>
<html>
    <head>
        <title>Progress Loader test</title>
        <style type="text/css">
            .loader_box
            {
                width:500px;
                height:20px;
                border:1px solid #777777;

                overflow:hidden;
            }

            .loader_content
            {
                width:500px;
                height:20px;
                background: #440000;        
            }
        </style>

        <script>
            var loader;

            function start_loader(varloader)
            {
                loader=setInterval(function () {process_loader(varloader+"_content")}, 500);

                function process_loader(varloadercontent)
                {
                    var inc=1;
                    var marginleft = document.getElementById(varloadercontent).style.marginLeft;
                    marginleft=marginleft.replace("px","");
                    marginleft=parseInt(marginleft)+inc;

                    if (marginleft>=0)
                    {
                        document.getElementById(varloadercontent).style.marginLeft="-5px";
                    }
                    else
                    {
                        document.getElementById(varloadercontent).style.marginLeft=marginleft+"px";
                    }
                }
            }
        </script>

    </head>

    <body>
        <div id="loader" class="loader_box">
            <div id="loader_content" class="loader_content" style="margin-left:-500px;">

            </div>
        </div>

        <script>
            start_loader("loader");
        </script>

    </body>
</html>

For more about JavaScript timer functions, click here: http://www.w3schools.com/js/js_timing.asp

Now refresh your browser, sit back, and enjoy the magic!

How do I use this?

You can slip the loader div anywhere you please. Though I'd recommend having it just after your body tag.

What the code does

There's an outer div with the id loader_box. And an inner div loader_content, colored brown (#440000), within it. The loader_content div is offset 500px to the left initially. The overflow:hidden CSS value ensures that any part of loader_content that goes out of loader_box is invisible.

As soon as the timer function process_loader() is triggered, it progressively alters the margin-left property of loader_content so that it appears as though the loader_box is filling up! You can adjust the speed of the animation by changing the value highlighted below. This line basically tells your browser to trigger the process_loader() function every 500 milliseconds, so decrease the value if you need to speed it up!

loader=setInterval(function () {process_loader(varloader+"_content")}, 500);

This Wayang Progress Bar should be good for an average page lag of 20 seconds. If you need a longer time, adjust the animation speed or the length of the Wayang Progress Bar.

Cool, eh? But that's not all. Look at the JavaScript in the If-Else statement. If the margin-left value exceeds 0px, which means the box is full, the display automatically keeps it at roughly 99%. So if it reaches 100% and your page is still not loaded, the user won't be asking why?

Let's make it pretty!

 Give your progress bar rounded corners! Add the following code to your CSS.

        <style type="text/css">
            .loader_box
            {
                width: 500px;
                height: 20px;
                border: 1px solid #777777;
                border-radius: 9px;
                overflow: hidden;
            }

            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #440000;        
            }
        </style>



Now change the colour of your bar. For some cool color combos, visit http://www.colorzilla.com/gradient-editor/

I'm just going to go with a nice flamingo pink. This is CSS3, but you don't need to learn it all right now, we're just having a little fun.

        <style type="text/css">
            .loader_box
            {
                width: 500px;
                height: 20px;
                border:1px solid #777777;
                border-radius: 9px;
                overflow: hidden;
            }

            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #ff4444; /* Old browsers */
                background: -moz-linear-gradient(top, #ff4444 0%, #ff9e9e 52%, #ff4444 100%); /* FF3.6+ */
                background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff4444), color-stop(52%,#ff9e9e), color-stop(100%,#ff4444)); /* Chrome,Safari4+ */
                background: -webkit-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Chrome10+,Safari5.1+ */
                background: -o-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Opera 11.10+ */
                background: -ms-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* IE10+ */
                background: linear-gradient(to bottom, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* W3C */
                filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff4444', endColorstr='#ff4444',GradientType=0 ); /* IE6-9 */   
  
            }
        </style>

A This is just a simulation of how the final result will be. Get creative!


There are more enhancements you may like to consider for your Wayang Progress Bar. They'll be discussed in the following parts of this web tutorial.

Next...

How to turn your Wayang Progress Bar off! You didn't think I left that out, did you?