Wednesday, February 1, 2012

Lesson 3: Callbacks

Last time we spoke of stacking animations, that was fun. But what if you want to start doing something with another element when some animation is finished? Asynchronous programming comes in handy not only when calling server side. Let's see how callbacks work for jQuery animations.

Just a few lines of code and we have a MIDI-keyboardish thingie full of colored square keys to click: Yes, they are clickable!

Pretty much done already, could employ a couple of swell modern features though. What kind of a midi-keyboard cannot do anything on it's own? Playing sequences after just one touch is a must-have feature, time to code it! Pressing one key will start off a bunch of pitches, as if we pressed some of them sequentially. When launching an animation on a key, we need to know which one goes next. We'll link elements using their data field. Have a look at jQuery .data, nice one. Now that for each element we know who's next, we can enhance the animation function by adding a callback. Callback practice is over, enjoy the result of all this hard work :)

Source code links:

Move on to the next lesson!

Sunday, January 15, 2012

Lesson 4: Introducing classes

Suppose we have one state-of-the-art html content representing 5 colorful frogs sitting on a big leaf: Ok, the markup is bulky, but it still looks great, right?
We could select those divs and put them into variables like 'frog1', 'frog2' etc, but we're no kids anymore. Instead, we put them in one place, and use some cool techniques at the same time!

The first line enumerates the integer range [0..4] and for every n creates an id selector via string interpolation (yep, that #{n} in "#ani3_bar#{n}" puts in a value ). 5 query results are collected and stored to 'bars' variable. Lookup Loops and Comprehensions for more. Short and readable, but it makes 5 id queries instead of one. If we were obsessed with execution speed, that would be bad, so there's a line with a single query too.
Same form of iteration over an array to change every element's attributes. From now on I'm going to omit some usual stuff, like that line '$j=jQuery' at the beginning of every script, but you know it's there :)

Now we know how to define functions, let's be nice and provide our frogs with capability to jump around. Check out the four functions' different syntax, meaning totally the same. Pick the flavor that suits you at the moment. Good. Now unleash the frog!
Wow! It surely is enjoyable to see it frolick. But does it go the right way?
Our jumping functions are stackable, cause they accept and return jQuery objects. That's the good part. But the frog goes doesn't start with 'left down right' as somebody less experienced with operations priority concept may expect from our click handler code. The first effective call is on the right, the string should be read like this:

left(down(right(right(up(up(left(left(down(right(bars2[4]))))))))))

We just drop the brackets for the obvious reasons ( like because we can ).

Would be nice to have directed jump functions behaving like jQuery animate(), being able to append function calls next to each other and seeing them execute in the same order. For that we need them to return something that also has all four functions inside. ( Instance methods instantly come to my mind, what do you think? )

Normally, using just JavaScript, to get many objects behave uniformly we'd need to understand how JS prototypes work. Blessed are those who do. I still find that somewhat tricky. But today we can relax and do it the good old OOP way - define a class. And once again, we'll write less code for that!
CS classes documentation, just a friendly reminder :)

Ok, lets do it:

Wait, that's not cool. All we did is was wrapping functions code with a class declaration. Yes, we got something by this: now we can queue our jumps more naturally, like
frog.right().down().left() etc.
But that's just not cool enough. There are reasons to change it:

  • Code duplication. Four very similar lines of code, with the only defference in animate() arguments.
  • The main asset of every instance is created outside and gets inside as a constructor argument. But, unlike proper decorator implementations, class code relies on the assumption that animated objects are made just the way the class needs to work, without checking it. The class is unseparable from html outside - every time one is updated, the other has to be re-checked.
  • Methods could accept path length. Much gain easily with our new OOP powers.

To git rid of duplication, let's put all the repeated code in one method, say 'jump', that will accept direction as argument and use predefined arguments for animate(). A key-value map with 'r','l','u','d' for keys should do fine. Then we add another argument to the new jump methods and put animation logic in a loop. Then transform right,left, up and down into convenience methods, each of them now calls jump with proper direction argument. Done.

Next - the constructor. Let it accept what varies in those html lines declaring frogs' bodies and inject it into a static html line with string interpolation, then use jQuery to create new element from html, then append it to a container ( another div in our case - the square green leaf ) and store it as the only variable of the newly created class instance. Done. The whole block of html lines flattens to just one, letting us concentrate on frogs' color and position.

Looks a bit different:

Let's see if it works.

Not bad. Readable set of just 4 instructions for each unit, predictable result. In fact, they are so perfectly organized one may even think they are not free-minded lively frogs, but programmed robots!

On the other hand, to heck with direction-named methods, compact path strings are the best for a case like this. Look at this:

One character per jump - and still readable. Next would be programming in absolute code! (Just kidding)

Time to stop - it's a bit overdone already. Of course, we love these frisky little creatures, but now it's time to move on to the next adventure!

Source code links:

Friday, January 13, 2012

Lesson 2: Stacking jQuery animations

I feel like making it also a hands-on illustrated introduction to CoffeeScript. But don't forget to check the language overview and coding kickstarter at coffeescript.org, cause it's by far the best. jQuery lets you stack animation calls. So, when you want to perform sequential animations on the same page element, one by one, you have a neat interface right for the task!

Every animation call returns an object that also has 'animate' function. Append animation calls one after another, just the way you want them run. Here's the code:


Let's stack some more. Use more lines if required, don't forget indentation if you do:


CoffeeScript is a modern programming language, outdated programming techniques like code duplication should be avoided. Fortunately, keeping code slim is quite easy, let's define a function:


Find full sample code behind the link below, save it as html (or clone from github) and play around! (Be careful with auto-formatting in your editor - after inserting code, make sure indentation is preserved)

Source code links:

Move on to the next lesson!


Monday, January 2, 2012

Lesson 1: jQuery animations are simultaneous

Hi folks! Inspired by jQuery tutorials on the web, I started porting some of them to CoffeeScript, which is, of course, a great source of fun too. I left coffeescript uncompiled so you could easier browse the page code.
Here goes a lesson from Wayfarer's animation tutorial, mostly unchanged.

All animations you start run simultaneously by default, unless you choose to stack them.



Animation in this example is very smooth, because the elements being animated are simple. Be careful, quality is likely to degrade for complex elements.

jQuery.animate function calls usual form:
jQuery(selector).animate( properties, [ duration ], [ easing ], [ callback ] ) with properties in [ brackets ] being optional. Using coffeescript you can drop some of the syntax if you like:

Source code links:

Ok, that was too simple, we surely want more fun. Get to the next lesson!

technorati token D6DWZM9N6BXZ