Pages

Sunday 20 March 2011

JavaScript - running man animation

The following blog post is intended to log my experience with implementing the “Running man” JavaScript application.

At its core the “running man” task involved the implementation of a JavaScript animation depicting a running man by stringing together a sequence of slightly different images. This task also involved the implementation of various features such as allowing the user to slow down or increase the speed of the animation and also the ability for the user to “throw” an obstacle at the running man.

Implementation

I have split up the project into 3 parts namely, HTML, CSS and JavaScript.

HTML

The HTML part of the project contains just the bare elements required for the JavaScript application.

container div – This is a global wrapper around all elements required for this task. I find it to be good practice to use a global container div whenever possible, this allows for more flexibility with styling especially with positioning as any internal elements even if positioned absolutely are still relative to this parent container div.

runningArea div – This div represents the area inside which the running man is actually running, by having this area explicitly dedicated for the running man I was able to detect boundaries inside which the animation has to take place, it also proved very handy for the onclick throwObstace() function which will be explained later when dealing with javascript.
This div also contains some other inner elements mainly the running man div “divMan” and the obstacle div “divObstacle”

controlPanel div – this div contains all the action buttons available for the user, the start, stop, slow, fast, jump and clear obstacle buttons, as you can se from the code below all buttons with the exception of the start button are disabled by default, these buttons will be enabled through JavaScript when their functionality is available.


CSS

Since the layout for this page is very simple I primarily made use of CSS id selectors to style it’s content, most styling attributes have been defaulted to represent the initial state of the page, these will obviously be altered during execution to output the illusion of a running man.

Below I have extracted some CSS from the project


The above CSS code effectively sets all elements on screen to the default position and font-family attributes shown above unless otherwise overridden.

The running Area has been styled with a background image, a specific height and a width of 100% (this is obviously 100% of the parent container and not of the page).


 The imgMan element simply positions the element absolutely aligning the element with the bottom of it’s parent div “runningArea”


 The divObstacle element represents the obstacle (soccer ball) on the screen, even though it’s positioned absolutely it’s position is still relative to it’s parent div and not to the page, initially the margin-top attribute is set to -1000 which would move the obstacle out of the viewable area of the screen, the z-index attribute is set to 2 which means that this element will be stacked on top of anything on the screen with a lower z-index.

 The above image shown the work done so far

JavaScript

The JavaScript section is the more complex section and where most of the work had to take place, I will split up the core functionality of the application into various segments to make this blog post more structured.

Main variables




Start animation - btnStartClick()



This function is the event handler for the Start button on the HTML page, it will first load all required images into the arrays defined in the previous section by executing a simple function loadImages() which populates the image arrays with the image URLs. It will then execute the animate() function which will call itself recursively to animate the application until terminated.


The animate function can be considered as the main “game loop” which will call itself recursively with a timed delay as defined by the speed variable to project the animation. The first portion of the code takes care of the sequencing of the image used to animate the “running man” as well as handle the direction. The “running man” will effectively change direction whenever either the left or right boundary of the running area is reached. The second portion of the code handles the horizontal positioning of the animation.


Stop/Pause animation - btnStopClick()


 The above code is fired whenever the stop button is clicked, it effectively stops the animation by calling the clearTimeout() function on the reference generated with the setTimeout() function in the animate() function, it also handled the enabling/disabling of on screen buttons as expected.


Slow down animation - btnSlowClick()


 The above code sets the speed (delay) value to 50 which will make the animation run in slow mode.


Speed up animation - btnFastClick()


 The above code sets the speed (delay) value to 50 which will make the animation run in fast mode.


Throw obstacle – throwObstacle(event)

 This function is fired whenever a mouse click event takes place on the runningArea div, the event object contains the x & y co-ordinates of where the actual mouse click took place, unfortunately this is relative to the browser window an not the runningArea div so some simple computation had to be done to compute this value using the .offsetLeft attribute of the container element. This function then calls the animateObstacle() function which will handle the animation (dropping effect of the obstacle).


 The above function will call itself recursively until the obstacle lands on the ground, the horizontal positioning of the obstacle depends on where the user clicks on the screen.


Jump - btnJumpClick()


 This function allows the user to make the running man Jump over the obstacle, the above code will disable the jump button while a jump is in progress.


 The animateJump() function will take care of the jumping animation by keeping track of the direction (up or down) as well as the vertical positioning of the “running man” animation.

The above image shows the "running man" jumping over an obstacle, notice how all the buttons are enabled/disabled depending on the state of the page.

 Clear obstacle - btnClearObstacleClick()



The clear obstacle function just clears the obstacle off the screen.


Collision detection

I haven’t yet managed to implement the collision detection between the running man and the soccer ball. My idea would be to compare the current position of the running man to that of the obstacle to after every animate() execution only when the obstacle is placed on the ground by comparing the margins of both elements and if they overlap I could simply call the btnStopClick() function which would pause the animation and take care of all other functionality such as enabling/disabling of buttons just as if a user had clicked the stop button


Conclusion

Overall I believe the project turned out ok, considering I had never before worked with JavaScript before, it did take me significantly longer than I anticipated to complete mainly because I am used to statically typed languages such as Java. I’m sure you have noticed some tricks in JavaScript code above especially the *1 arithmetic operation to “trick” JavaScript to treat the value as a number and also the .replace(/px,*\)*/g,"") function which I used to remove the px characters to be able to treat such values as numbers.


Resources

Images

Running man image sequence –  The running man animation is made up of a total of 60 images, 30 going in each direction. I downloaded the original sprite sheet from http://www.thebest3d.com/pda/tutorials/array2animation/index2.html adter which I sliced it into individual images and flipped each image to go in the opposite direction.


Soccer ball – the soccer ball used as an obstacle was downloaded from http://www.iconarchive.com/show/sport-icons-by-icons-land/Soccer-Ball-icon.html


JavaScript references

w3schools.com – I mainly used this site as a reference to the core JavaScript functions and also for guidance when parsing the DOM.

Thursday 17 March 2011

JavaScript - Loan Calculator

For our first javascript exercise we worked on a loan calculator, the core functionality of the application was already in place but we were asked to perform the following tasks/modifications on the existing code.
 
1. Modify the HTML/CSS

With regards to the HTML I kept most of the original code, I wrapped the whole thing around a couple of <divs> to allow for easier manipulation through CSS and javascript. I also included some additional elements for the required javascript modifications, namely the inclusion of the discount checkbox and two other output fields to display the total number of payments and the loan end date.


 
As for CSS I mainly made use of direct id selectors to style and position the various elements as explained in the previous blog post.

2. Modify JavaScript

a. Show total number of payments

To show the total number of payments all we had to do was expose an already existing variable that was used internally in the calculation, in order to prevent fraction number of payment values I used the Math.ceil() javascript function which rounds up any number to the next integer value.
 
  

b. Show last payment date

To show the last payment date, I incremented the current date by x number of years, where x is the number of years keyed in by the user, to do this I created a new Date object which is automatically set to the current date, I extracted the year value from the date using the getFullYear() function and incremented this value by x. I then re-assigned this value back to my date object.


 
c. Show discount checkbox

To implement this feature I made use of the checkbox previously created (mentioned in the HTML/CSS section), I implemented the code in the existing calculate() function and then call this function on the onchange event of the checkbox to keep in line with the current functionality and also provide instant updates whenever the checkbox is toggled. The code check for the checked flag and if checked it overrides the interest value with the discounted one. The script also outputs the discounted interest rate to the user through the discountedLabel  <span> next to the interest rate textbox. This label is reset to spaces when the checkbox is not checked.

 
d. Add a new feature

As a new feature to the loan calculator I created a +/- toggle button on the left side of the calculator’s title-bar. 

 
The code to implement this is pretty straight forward, the toggleApplication() function is called whenever the toggle button (-/+) button is pressed. The function reads the calculator state directly from the button value to determine the state of the calculator. If the value is equal to minus (-) it means that the calculator is maximised and therefore should be minimised, the reverse happens when the value is equal to plus (+).  The concept of reading the value directly from the element instead of keeping an internal variable to identify the state of the form keeps the code cleaner as well as ensures that the correct action is always taken as the source is the page itself. 

 
















 On the whole I think the task turned out ok, I was planning on implementing the drag/drop functionality to allow the user to drag the <divs> around the screen just using the blue title bar, but since we were not allowed to use JavaScript frameworks like jQuery, I would have ended up using a lot of code snippets which would have been out of scope for this exercise.