Friday 19 December 2014

Web Tutorial: The QBasic Xmas Tree

Merry Christmas and Happy Holidays!

The occasion calls for some festive light-hearted fun, and what better than something I used to fool around with as an awkward geeky teenager?

QBasic! For more on this: http://en.wikipedia.org/wiki/QBasic

Now that I'm a slightly less awkward, even more geeky adult, here's an updated version of a little program I wrote back then, to test my mastery of nested loops and logic - the QBasic Xmas Tree!

Ah, the nostalgia.

This isn't a web tutorial per se, because QBasic has nothing to do with the web. On the other hand, this tutorial is being posted on the web, so... enough dithering! Let's fire up your QBasic editor and get right to it!

First, type the following code in your console.
INPUT "How many sections should your Xmas tree have"; sections

Run this line, and it should be enough to give you the following:

The program starts with user input.

This will serve to obtain user input (only in numerical format) and assign it to the variable sections. This is important because the program will generate a Xmas Tree with that number of sections.

Of course, we're not done yet. The first line works, but it's useless on its own unless you have the rest of the program. But first, a preview of what your Xmas Tree will look like with four sections!

Ta daaaaa


INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14

cols = sections * 20
cols = cols + (cols MOD 2)

filler = (cols - 1) / 2

CLS clears the screen after obtaining input. and COLOR 14 changes the text color to Yellow. You'll need to do this because we're drawing the star!

cols = sections *20 defines the total theoretical amount of width (in spaces) your tree should take up. It should commensurate with the number of sections the user specifies. cols = cols + (cols MOD 2) makes sure it's an odd number.  filler=cols-1 defines the number of empty spaces on the left. In this case, you deduct 1 from it because the first line is going to be your filler, followed by one character dedicated to the star. So add the following lines to draw the star!

INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"

PRINT line$

The star is supposed to be dead center top of your tree. It's of course, followed by the top of the tree. I'm going to use the character "^" and call it a leaf.

INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"
PRINT line$

COLOR 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "^"

PRINT line$

Of course, COLOR 2 changes the text color to Green.

Now, we have the star, and we have the top of the tree. Now we're going to keep using leaves to draw the rest! For that, we'll need to employ a certain amount of logic.

Here are the rules:

The first section starts with two lines, just after the top of the tree. The first line of the first section will be 3 leaves. Subsequent lines will be 2 leaves more than the previous line of the same section, and the filler will be one space less.

Subsequent sections will have one more row than the previous section. And each row will start with the same number of leaves as the second-last row of the previous section!

To show you what I mean, refer to the illustration below:

(star and top)
                    *
                    ^
(section 1)
                   ^^^
                  ^^^^^
(section 2)
                   ^^^
                  ^^^^^
                 ^^^^^^^
(section 3)
                 ^^^^^^^
                ^^^^^^^^^
               ^^^^^^^^^^^
              ^^^^^^^^^^^^^  
(and so on)

So maybe we should represent this numerically, in tabular form, in order to understand better.
section rows leaves per row
1 2 3,5
2 3 3,5,7
3 4 7,9,11,13
4 5 11,13,15,17,19

So now we're going to add the first loop for sections, and implement the rows logic.
INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"
PRINT line$

COLOR 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "^"

PRINT line

FOR i = 1 TO sections STEP 1
    rows = 1 + i

NEXT i

And then we'll nest another FOR loop within the first one,
INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"
PRINT line$

COLOR 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "^"

PRINT line

FOR i = 1 TO sections STEP 1
    rows = 1 + i

    FOR j = 1 TO rows STEP 1
        line$ = ""
        nextstartcol = 0

    NEXT j
NEXT i

In the nested loop, we initialize the variable line to nothing and nextstartcol to 0, because they will be changed frequently. Now, next  one's a biggie. It's a nested IF loop that implements the logic of leaves per row.
INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"
PRINT line$

COLOR 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "^"

PRINT line

FOR i = 1 TO sections STEP 1
    rows = 1 + i

    FOR j = 1 TO rows STEP 1
        line$ = ""
        nextstartcol = 0

        IF i = 1 THEN
            IF j = 1 THEN
                sectioncols = 3
                nextstartcols = 3
            ELSE
               
sectioncols = sectioncols + 2
            END IF
        ELSE
            IF j = 1 THEN
               
sectioncols = nextstartcols
            ELSE
               
sectioncols = sectioncols + 2

                IF j = rows - 1 THEN
                    nextstartcols =
sectioncols
                END IF
            END IF
        END IF

    NEXT j
NEXT i

Now that the hard part's out of the way, we've determined nextstartrows and sectioncols for each row. Time to draw it!
INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"
PRINT line$

COLOR 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "^"

PRINT line

FOR i = 1 TO sections STEP 1
    rows = 1 + i

    FOR j = 1 TO rows STEP 1
        line$ = ""
        nextstartcol = 0

        IF i = 1 THEN
            IF j = 1 THEN
                sectioncols = 3
                nextstartcols = 3
            ELSE
                sectioncols = sectioncols + 2
            END IF
        ELSE
            IF j = 1 THEN
                sectioncols = nextstartcols
            ELSE
                sectioncols = sectioncols + 2

                IF j = rows - 1 THEN
                    nextstartcols = sectioncols
                END IF
            END IF
        END IF

        filler = (cols - sectioncols) / 2

        FOR k = 1 TO filler STEP 1
            line$ = line$ + " "
        NEXT k

        FOR k = 1 TO sectioncols STEP 1
            line$ = line$ + "^"
        NEXT k

        PRINT line$

    NEXT j
NEXT i

And there you have your Xmas Tree. I'm gonna add one last segment of code as a message:
INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"
PRINT line$

COLOR 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "^"

PRINT line

FOR i = 1 TO sections STEP 1
    rows = 1 + i

    FOR j = 1 TO rows STEP 1
        line$ = ""
        nextstartcol = 0

        IF i = 1 THEN
            IF j = 1 THEN
                sectioncols = 3
                nextstartcols = 3
            ELSE
                sectioncols = sectioncols + 2
            END IF
        ELSE
            IF j = 1 THEN
                sectioncols = nextstartcols
            ELSE
                sectioncols = sectioncols + 2

                IF j = rows - 1 THEN
                    nextstartcols = sectioncols
                END IF
            END IF
        END IF

        filler = (cols - sectioncols) / 2

        FOR k = 1 TO filler STEP 1
            line$ = line$ + " "
        NEXT k

        FOR k = 1 TO sectioncols STEP 1
            line$ = line$ + "^"
        NEXT k

        PRINT line$
    NEXT j
NEXT i

COLOR 15
filler = (cols - 15) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "MERRY CHRISTMAS!"

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

PRINT line$

filler = (cols - 5) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "T___T"

PRINT line$

And that's the entire piece of code for the QBasic Xmas Tree. Pretty old-school stuff, especially when you consider it was done way back before the Internet came with color.

Pretty easy, wasn't it? One could even say it was... wait for it... elemen-tree!
T___T

Sunday 7 December 2014

Establishing a Transition Sequence in CSS3

Transitions can be rewarding in CSS3. Gone are the days a developer had to manipulate DOM properties and multiple timing functions in JavaScript. With the right combination of JavaScript and CSS3 - sometimes with only CSS3 - one can work wonders.

Take the following HTML/CSS3/JavaScript code below:

<!DOCTYPE html>
<html>
    <head>
        <title>CSS3 test</title>
        <style type="text/css">
            .bigcircle
            {
                width:200px;
                height:200px;
                border:1px solid #777777;
                background-color:#FFAA00;
                border-radius:150px;
                margin-left:0px;
                -webkit-transition: all 5s;
                transition: all 5s;   
            }

            .newpos
            {
                -webkit-transform: rotate(0deg);
                -moz-transform: rotate(720deg);
                -o-transform: rotate(720deg);
                -ms-transform: rotate(720deg);
                transform: rotate(720deg);
                margin-left:500px;
            }

            .oldpos
            {
                margin-left:0px;
            }

            .smallcircle
            {
                width:20px;
                height:20px;
                margin-top:5px;
                border-radius:9px;
                margin-left:auto;
                margin-right:auto;
                background-color:#FFCC00;          
            }

        </style>

        <script>
            function start_rolling()
            {  
                var pos=(document.getElementById("wheel").className=="bigcircle newpos"?"oldpos":"newpos");
                document.getElementById("wheel").className="bigcircle "+pos;

                if (pos=="oldpos")
                {
                    document.getElementById("btRoll").value="click me to see the ball roll";
                }
                else
                {
                    document.getElementById("btRoll").value="click me to see the ball roll back";
                }
            }
        </script>
    </head>

    <body>
        <input id="btRoll" type="button" value="click me to see the ball roll" onclick="start_rolling();">
        <div id="wheel" class="bigcircle">
            <div class="smallcircle">

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

When the button is clicked, the wheel rolls to the right. Click the button again, the ball rolls to the left. Try it. It works here!



But what happens if you want the wheel to first be invisible, then pop up and roll to the right? And then turn invisible again after rolling back to the left?

Try changing the code below:

<!DOCTYPE html>
<html>
    <head>
        <title>CSS3 test</title>
        <style type="text/css">
            .bigcircle
            {
                width:200px;
                height:200px;
                border:1px solid #777777;
                background-color:#AA7700;
                border-radius:150px;
                margin-left:0px;
                -webkit-transition: all 5s;
                transition: all 5s;
                display:none;
            }

            .newpos
            {
                -webkit-transform: rotate(0deg);
                -moz-transform: rotate(720deg);
                -o-transform: rotate(720deg);
                -ms-transform: rotate(720deg);
                transform: rotate(720deg);
                margin-left:500px;
            }

            .oldpos
            {
                margin-left:0px;
            }

            .smallcircle
            {
                width:20px;
                height:20px;
                margin-top:5px;
                border-radius:9px;
                margin-left:auto;
                margin-right:auto;
                background-color:#FFAA00;          
            }

        </style>

        <script>
            function start_rolling()
            {  
                var pos=(document.getElementById("wheel").className=="bigcircle newpos"?"oldpos":"newpos");
                document.getElementById("wheel").style.display="block";
                document.getElementById("wheel").className="bigcircle "+pos;

                if (pos=="oldpos")
                {
                    document.getElementById("btRoll").value="click me to see the ball roll";
                    document.getElementById("wheel").style.display="none"; 
                }
                else
                {
                    document.getElementById("btRoll").value="click me to see the ball roll back";
                }
            }
        </script>
    </head>

    <body>
        <input id="btRoll" type="button" value="click me to see the ball roll" onclick="start_rolling();">
        <div id="wheel" class="bigcircle">
            <div class="smallcircle">

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

Did it work? Guess not! The ball remained hidden.

Why?

Simply put, not every property can be manipulated by a CSS3 transition. The display property is one of these. While we specified that the change to the margin-left property would take 5 seconds to fully finish, the truth is that both changes to the display and margin-left properties were started simultaneously.

And this confused the processor.

To rectify this, we need to establish a proper sequence for the changes. So we're going to make the following change to the JavaScript.

        <script>
            function start_rolling()
            {  
                var pos=(document.getElementById("wheel").className=="bigcircle newpos"?"oldpos":"newpos");
                document.getElementById("wheel").style.display="block";
                setTimeout(function() {document.getElementById("wheel").className="bigcircle "+pos;},100);

                if (pos=="oldpos")
                {
                    document.getElementById("btRoll").value="click me to see the ball roll";
                    setTimeout(function() {document.getElementById("wheel").style.display="none";},5500);
                }
                else
                {
                    document.getElementById("btRoll").value="click me to see the ball roll back";
                }
            }
        </script>

Magic! Now the ball appears and rolls to the right. And when you click the second time, it rolls back to the left and disappears!

Read more about JavaScript timing functions here: http://www.w3schools.com/js/js_timing.asp

What sorcery is this?!

We introduced a slight time delay, about 100 milliseconds, for the margin-left property to change after the display property change. And when the ball rolled left, we set a time delay (5500 milliseconds) for the ball to disappear. The processor no longer tries to execute changes to a non-transitionable property (display) and a transitionable property (margin-left) at the same time. No more conflict!

Hope you enjoyed reading this. It's how I roll, yo.
T___T

Thursday 4 December 2014

Big Bang Media Undersells

Following the unintended comedy generated by a workplace happiness survey, conceived by the Singapore Human Resources Institute and consulting firm Align Group, a new phrase was born: Under Happy.

I'm not even going to go into the numerous and obvious wicked puns derivable from this one, but take a gander at this job ad.
Click to enlarge

Last month, we took a look at a spectacularly bad job ad by Sugar Technologies, and now we have an actual example of wit from Big Bang Media Pte Ltd. A sly dig at the workplace happiness survey in a mercifully short piece. Less is more, so a favorite developer maxim goes, and this one doesn't disappoint.

It's probably not the recommended way to write a job ad, but it's still a better love story than Twilight sight better than the pretentious crap on offer by Sugar Technologies.

I chortled.

Watch and learn, Sugar.


Now that's what I call under-stated humor!
T___T

Tuesday 2 December 2014

How I became a Web Developer (Part 2/2)

Battle of the Bottle

And then, like many young people, I got carried away with the fact that I had money. I started drinking. It began as weekend binges, then trickled down to weekdays as well. Waking up with strangers, puking my guts out. That kind of thing. I started calling in sick. I could have still worked, I just didn't want to. It showed in my attitude. I became snarky, unhelpful and short-tempered.

Pretty soon, I was going through the motions at work and waiting for the monthly paycheck just so there would have money for booze. And of course, I needed money to drink because it helped me deal with how much I hated this job. If at this point, you're thinking that this sounds stupid, you're absolutely right. I was a stupid kid. I wasn't being fair to the company or myself, and this was definitely not how a responsible working adult should carry himself.

Yep, this loser.


One day all this came to a head.

The company presented me with a gift: a nice wristwatch engraved with my name, and a letter congratulating me for having completed five years in their employ. I'm sure they meant well, but it was like a slap in the face.

Five. Fucking. Years.

I was supposed to have been gone by the third year. What happened to the wildly ambitious twenty-three year old who stepped into this company five years ago? That kid got sidetracked. He got stuck in a job with precious few prospects, because, as technology advances and becomes increasingly ingrained into our daily lives, fewer users are dumb enough to need much desktop support anymore. That kid hated his job, so in the past few years he hadn't learned a damned thing about networking or server support. He basically followed orders and went through the motions. Meanwhile, his pay kept rising. Whereas once he was good value for money, he was now rapidly becoming an expensive liability.

This kid's relationship with this company was over. It was just a matter of who realized it first.

Epiphany

I got drunk again that night. The following morning, I looked in the mirror. My wasted unshaven face and bloodshot eyes stared back at me judgmentally. I'd run out of excuses. What was holding me back? Stagnating economy? IT employment squeeze? Bad timing?

Bullshit. I was the one holding myself back. My fate was in my hands, and always had been. And from that moment of clarity, came resolve. I still liked to drink, but I hated my job more than I liked to drink. And if I was tired of being treated like desktop support, the answer was simple. Stop being desktop support.

Action

From that day, I stopped drinking. No allowances, no excuses. And made a plan. To make myself employable somewhere else without having to leverage on years of desktop support experience, I would need a skill upgrade. Fortune favored me then. There was a polytechnic offering post-grad courses. After some careful deliberation, I enrolled for a course in e-commerce technology.

So now instead of drinking, I was spending my time after office hours studying, experimenting and doing research. A year later, I obtained my certification. Another company offered me a web developer's position, but at a pay cut. I took it without hesitation. And never looked back. I've stayed (mostly) dry since, and since that day I have never needed to call in sick.

That's how I finally became a web developer. I was earning less than before and had to start from the bottom, but I was free.

Was it smooth sailing from then on? Oh hell, no. This was just the beginning. There was a looming mountain in front of me and a journey that promised to be rough and treacherous. I dug in and started climbing.


Just the beginning, kiddo.

What's the point of this story? 

To congratulate myself on a job well done? To make a big song and dance about my personal and professional journey?

Well, I'd be lying if I told you I don't have a healthy amount of self-esteem from having clawed my way out of that pit. Sure, there are stories out there way more amazing, and struggles way more epic than mine. And I wouldn't be the first person in the world to wake up one day, stop drinking, and take control of his life.

But it's my blog. It's my experience. I get to tell my tale, and if you get something out of this as well, good for you.

If there's anyone out there who's at a vastly different place than you envisioned yourself to be and are feeling dissatisfied with life, perhaps this will help you reach the same realizations. With far less fuss.

Sometimes the answer really is that simple - stop whining and move on. And if you're telling me it isn't easy, well of course it isn't, sunshine. It isn't supposed to be easy at all.


You're in a boat and life is a stream. Start rowing!
T___T

Monday 1 December 2014

How I Became a Web Developer (Part 1/2)

I just turned thirty-seven two weeks ago. It's been almost fifteen years since I embarked on this journey. Warning: long story ahead, make yourself comfortable!

Some Background

It was 2001 and I had just graduated with a Bachelor's Degree in Information Technology. The possibilities were endless. The problem was, in the face of a slumbering economy and lack of job opportunities, I soon wound up taking odd jobs. Basic computer literacy training. Small websites.

And in the course of building one of those small projects that had been outsourced to me from a vendor, I visited his shophouse office in Little India. He took me around and introduced me to his team. It was a tiny dingy room with precious little furniture. Four PCs in the room, and a big smoldering ash-tray in the middle. The air reeked of sweat and old cigarette smoke.

It was heaven to my young eyes. These Indians, were, to me, the epitome of cool. This was what I was going to do for the rest of my life. I was hooked.

I didn't become a full-fledged web developer right away. It took years of screwing up to get to this point. In retrospect, perhaps my dreams could have been a little bit bigger.

But, for better or worse, this is what I am. This is what I do.

And after that day...

The path towards becoming a web developer turned out to be slightly more complicated.

Somehow I landed a job as desktop support in a legal firm. My first full-time job ever. It wasn't where I envisioned myself being, but it would do for a start. I would leech whatever experience I could from this, and move on in maybe three years.

At least, that was the plan.

It started out interesting. I was brimming with youthful enthusiasm after going from temp job to temp job. Because some in-house development was needed, I picked up a book on my desk, and learned ASP from there. It wasn't too difficult for someone with a Visual Basic background.


I learned all my ASP from this!


The first year was filled with wonder. Friendships were forged, some of which are still ongoing today. I honed my web scripting skills, which, as it turned out, would prove invaluable down the road. In fact, as much as I eventually grew to hate the job, there's no denying that the experience hardened me. Whenever someone complains to me about user stupidity, I tend to go "You think that's stupid? I've seen worse. I spent six years in desktop support".

By the third year, my enthusiasm waned. There was only so much development I could do, and the other aspects of my job were less than thrilling. Networking was one of my least favorite subjects in school, and having hands-on experience with it didn't remove my distaste for it. And as for desktop support...

What can I say about desktop support that won't sound overly uncharitable? It involved moving PCs from location to location, setting up email accounts, tending to all the little problems that users seemed to encounter all the time. It wasn't exciting to begin with, but by the third year it had become positively tedious. There's only so much stupidity a man can take before he goes nuts.

Someone once described desktop support to me as "the IT equivalent of leading a man to the urinal and holding his dick while he takes a piss". He was being kind. It's way worse. Lack of computer savvy I could forgive. One gets those users all the time - without them, desktop support would not exist. And then there was the other kind of user - entitled, obnoxious and utterly inept. Special breeds of stupid who thought desktop support automatically extended to all things electronic such as microwave ovens, paper shredders and phones. Special strains of asshole who thought nothing of interrupting a man at his toilet break just because there was a printing problem. I was being ordered around by people who, in soccer parlance, weren't good enough to carry my boots.

I was a university graduate, dammit. I deserved better. Or so I thought.

The truth is, a man deserves exactly what he will accept. Each time my pay got raised or I received my annual bonus, I looked the other way and delayed moving on. And here's the thing about the annual bonus in that company - it was divided in two and each half was doled out at intervals of six months.  People who felt that the bonus was their own money and were entitled to it, would delay their departure by another half-year to avoid forfeiting it. It was genius. A brilliant maneuver to keep unambitious, unmotivated 9-to-5ers slaving away. Do I blame the company? In retrospect, no. They dangled that carrot; I was the fool who took it.

Next...

How I got out.

Saturday 22 November 2014

Sugar's Job Ad - Not So Sweet

Sugar Technologies released a job advertisement in September 2014, looking for a Lead Software Engineer.

Much has been said about the ad, and of Sugar Technologies, mostly uncomplimentary. I had meant to add my two cents last month, but I didn't have a blog then. Ah, but I do have a blog now.

The ad has been reworded slightly since then, so I point you to the exhibit below:

Click to enlarge!

Sugar Technologies has since released a clarification and one of its interns, Asyraf Aliman, has also released a post in defense.

Unlike many of the comments posted, I do not consider the ad discriminatory, nor do I necessarily think that Sugar Technologies would be a bad place to work, under the right circumstances. Yes, Sugar Technologies should not be judged by its job ad. That's akin to saying that a prospective employee should not be judged by his resume, an assertion I don't wholly disagree with either. From the picture painted by Sugar Technologies and its intern, Sugar Technologies seems to be a fun place to pick up valuable professional experience, and is not the draconian hotbed of slavery depicted by the job ad. I'm inclined to give them the benefit of the doubt.

However, the subject under discussion is not Sugar Technologies, nor am I attempting to judge them based on one job ad. My issue is with the job ad itself.

The author was obviously trying to be different and original. Quirky? Perhaps. Edgy? Debatable. I think a more appropriate term would be immature and unprofessional.

And utterly, appallingly stupid.

How else would one describe an ad which uses such a condescending tone which effectively alienates its target audience - the developers? Consider the excerpt below:


Who We Want:
  • You are ambitious, intense and entrepreneurial, and you dream of doing truly epic shit with your life. You recoil at the thought of having 1.15 kids, balloting for a flat, saving up for a Toyota and waiting to withdraw your CPF savings at 65 (or 70, or 80, or 120).
Who We Don't Want:
  • You are a shallow social climber whose dream is to work for Goldman Sachs because it "looks good on your CV". You went to an Ivy League university because it would "look good on your CV". But you couldn't get into Goldman Sachs (or Citibank, or HSBC) because you actually have no passion for finance, just like how you want to buy that Louis Vuitton bag (because it will "look good on your social CV") despite having no passion for design and craftsmanship. Guess what? If you were rejected by Goldman Sachs, you will be rejected by us too. For exactly the same reasons. Advice: try applying for a government job.
  • You are a social misfit. You like technology only because you can't relate to real people. You spend your weekends playing DOTA and in your sleep you dream about your hero reaching Level 38. At school, you were always the last to get picked on any project or sports team. Having a conversation with you is about as interesting as watching paint dry. Advice: go seek help from a mental health professional.

Perhaps the author felt that those turned off by this segment would be "shallow social climbers" whom the company doesn't really need. Surprise - I am pretty much the kind of person who should identify with the ad.
  • I like kids only when they're not my own.
  • I consider cars overrated.
  • I've toiled almost exclusively for small unglamorous startups that worked me more than 12 hours a day. And moving up that corporate or social ladder isn't my priority - improving as a developer is. Because I went through a lot to become a web developer - and you will take it only from my cold, dead hands.
  • I've rarely been in the position to push the blame to anyone. The companies I worked for were so small that I was the beginning, middle and end of the assembly line. I was the whole fucking assembly line.
  • And I don't game. My weekends are spent doing housework, playing with code and hitting the swimming pool. I'm willing to bet that my mental health is excellent, thanks very much.

But no. While I'm not responding with as much vitriol as some comments posted online, I'm not so much angry as disgusted.

Yes, I've worked long extra hours to get things done. Without thought of recognition or reward. Because the act, in itself, was a reward. Because I love what I do.

But my employer is not entitled to benefit from that love. My employer is only entitled to what he pays me to do, and anything beyond that is mine to give.

Yes, I think marriage is one of the most horrifying institutions known to mankind. And I think having a job that does not stretch me in the slightest, where I can just coast to the day I collect my pension, is long slow career suicide. And I feel that it's no way to live.

But I do not judge people who want those things. I do not call them "shallow social climbers" or "social misfits". Not anymore, at least.

People want what they want. That's all there is to it. On my part, I just want to code and be paid for it, and if you have a problem with that, do us all a favor and go jump off Benjamin Sheares Bridge or something.

The smug and condescending tone of the job ad rankles, and for good reason. I have had people, with wife and kids in tow, smugly pointing to their "success" and asking me when I'm ready to settle down. As though not wanting what they achieved somehow means I'm deficient in some way. And I have been equally snarky in the past, wondering aloud, to their faces, why they're so proud of the fact that they have a spouse and kids just like almost every other schmuck on this island.

I encountered arrogance, and I responded with arrogance. If it's something a Teochew is good at, it's being cocky. But that was immature of me. And precisely because I've been immature before, I recognize immaturity when I see it. That job ad screamed immaturity. In spades.

On their statement, Sugar Technologies had this to say:

Firstly, we fully understand and acknowledge that working at a tech start-up is not for everyone. The majority of job-seekers desire stability, security, structure and consistency, and like many tech start-ups, we are not able to provide this. Given the nature of what we do, we require our employees to be comfortable with a certain degree of chaos and uncertainty.

Then why, oh why, didn't they say this from the start instead of trying to be cute in their job ad? Sugar Technologies is a tech start-up. One of several hundreds (probably thousands) on this island. With one cool (and hopefully original or at least superior) Mobile App idea they're riding on. Don't put on airs. It's just silly.

To conclude, and to reiterate, Sugar Technologies is not being discriminatory with the job ad. Sugar Technologies is perfectly within their legal rights. Ethically, they are blameless. Someone just got a little carried with the fancy wording on their job ad, that's all.

Guess it's true what they say -  advert-sity breeds character!
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!