Powered By Blogger

sábado, 3 de noviembre de 2012

A Simple Parallax Scrolling Technique

Parallax scrolling is an interesting technique, where, as you scroll, the background images translate slower than the content in the foreground, creating the illusion of 3D depth. As I planned to re-design my personal website, my first goal was to write the shortest and simplest code to achieve maximum awesomeness! I’ll show you how I did it.

In this tutorial, I’ll teach you the simplest parallax scrolling technique you’ve ever came across, so let’s dig in!


Step 1: The Markup

This technique revolves around controlling the speed of background image. So let’s begin with the HTML markup, creating two sections along with the required attributes: "data-type" and "data-speed". Don’t worry; I’ll explain these later.

                  <section id="home" data-type="background" data-speed="10">                  </section>                  <section id="about" data-type="background" data-speed="10">                  </section>                    

I am using the <section> tag with the attributes data-type & data-speed, which were introduced in HTML5. This makes the HTML markup cleaner and easier to read.

According to the specification for Custom Data Attributes, any attribute that starts with data- will be treated as a storage area for private data. Additionally, this won’t affect the layout or presentation.

Since all we need to do is control the speed of the background images, we’ll use data-type="background" and data-speed="10" as key attributes to specify the necessary parameters.

I know what you’re thinking: you’re worried about IE. Never fear; I have a workaround for that too! We’ll discuss it momentarily.

Next, let’s add the content within the <article> tag inside each <section> .

                  <section id="home" data-type="background" data-speed="10" class="pages">                           <article>I am absolute positioned</article>                      </section>                  <section id="about" data-type="background" data-speed="10" class="pages">                           <article>Simple Parallax Scroll</article>                  </section>                    

What we’re attempting to do here is making the <section> background scroll slower than its content, i.e <article>. This will help us create a parallax illusion. Before moving on to the jQuery magic, let’s add the background images in our CSS for each <section>.

                  #home {                  background: url(home-bg.jpg) 50% 0 repeat fixed; min-height: 1000px;                  }                  #about {                  background: url(about-bg.jpg) 50% 0 no-repeat min-height: 1000px;                  }             

Upon adding backgrounds for both sections, it should look like:

image
image

Let’s add some more CSS to style and spice up the page!

                  #home {                    background: url(home-bg.jpg) 50% 0 repeat fixed; min-height: 1000px;                    height: 1000px;                    margin: 0 auto;                    width: 100%;                    max-width: 1920px;                    position: relative;                  }                  #home article {                    height: 458px;                    position: absolute;                    text-align: center;                    top: 150px;                    width: 100%;                  }                  #about {                    background: url(about-bg.jpg) 50% 0 repeat fixed; min-height: 1000px;                    height: 1000px;                    margin: 0 auto;                    width: 100%;                    max-width: 1920px;                    position: relative;                    -webkit-box-shadow: 0 0 50px rgba(0,0,0,0.8);                    box-shadow: 0 0 50px rgba(0,0,0,0.8);                  }                  #about article {                    height: 458px;                    position: absolute;                    text-align: center;                    top: 150px;                    width: 100%;                  }                    

Now it should look like this…

image

Step 2: The Magic Code

Yep, that’s right; this is where the magic begins! Using jQuery, we’ll begin with the standard document.ready() method to ensure that the page has loaded and is ready to be manipulated.

                  $(document).ready(function(){                  });                    

This technique revolves around controlling the speed of the background image that exists in both sections.

Now I need your attention here. The first thing happening below is that we’re iterating over each <section> in the page, which has the atrribute data-type="background".

                  $(document).ready(function(){                      $('section[data-type="background"]').each(function(){                        var $bgobj = $(this); // assigning the object                      });                  });                    

Add another function, .scroll(), inside .each(), which is invoked as the user begins scrolling.

                  $(window).scroll(function() {                  });                    

We need to determine how much the user scrolled up, and then divide the value by the data-speed value, mentioned in the markup.

                  var yPos = -($window.scrollTop() / $bgobj.data('speed'));                    

$window.scrollTop(): we are getting the current scroll value from the top. This basically determines how much the user has scrolled up. $bgobj.data('speed') refers to the data-speed assigned in the markup, and yPos is the final value that we need to apply for scrolling. However, it will be a negative value, because we have to move the background in the opposite direction of the user’s scroll.

Let’s investigate a bit more with an example:

image

In the above image, data-speed is 10, and let’s assume that the browser window has scrolled 57px. This means 57px divided by 10 = 5.7px.

                  // Put together our final background position                  var coords = '50% '+ yPos + 'px';                  // Move the background                  $bgobj.css({ backgroundPosition: coords });                    

The last thing that we need to do is put together our final background position into a variable. In order to keep the horizontal position of the background as static, we’ve assigned 50% as its xPosition. Then, we added yPos as the yPosition, and, finally, assigned the background coordinates to our <section> background: $bgobj.css({ backgroundPosition: coords });.

Your final code might look like:

  $(document).ready(function(){      $('section[data-type="background"]').each(function(){          var $bgobj = $(this); // assigning the object          $(window).scroll(function() {              var yPos = -($window.scrollTop() / $bgobj.data('speed'));              // Put together our final background position              var coords = '50% '+ yPos + 'px';              // Move the background              $bgobj.css({ backgroundPosition: coords });          });      });  });  

Yay, we’ve done it! Try it out for yourself.


IE Fix

There’s one last fix: older IE can’t render the <section> and <article> tags. That’s easy to fix, though; we’ll use the standard solution of creating the elements, which makes the browser magically recognize the HTML5 tags.

                      // Create HTML5 elements for IE                      document.createElement("article");                      document.createElement("section");                    

Additionally, we need to use a basic CSS reset file in order to make all the browsers play nicely. Luckily, tools, like HTML5 Boilerplate take care of the brunt of the work for us, when it comes to cross-browser normalizing.


That does it for this lesson! Any questions or notes that you’d like to add? Let me know below!



El ajedrez versión «singularidad»

Singularity-Chess

Hay miles de variantes del ajedrez; esta me pareció especialmente curiosa: Singularity Chess, que se juega con las mismas piezas sobre un tablero con singularidades, que a modo de agujeros negros hacen que las piezas giren, vayan y vuelvan con movimientos realmente inusuales.

Los movimientos son un tanto psicodélicos y distorsionados; además de eso algunas piezas «dan la vuelta» por los bordes del tablero, y en ocasiones pueden amenazar una misma casilla del tablero en dos sentidos diferentes (!) Tan extraño es el concepto que cuando los alfiles atraviesan el centro del tablero, donde está la singularidad, salen de él por «diagonales» de diferente color a por las que entraron.

# Enlace Permanente y Comentarios



Despe e Siga - Os Primos [1996]


   Formada en Portugal desde 1994 con los mismos miembros de otra banda importante de ése país como lo son Peste & Sida, unos rockeros que desde el 87' se han mantenido activos hasta la actualidad. Despe e Siga fué un proyecto que mantenía en su repertorio las influencias del Rock y el Punk que tenían de su banda raíz de los ochenta, pero si se acercaba tambien un poco a los sonidos del Ska, sobre todo en éste 2do trabajo llamado ''Os Primos'', destacando el tema ''Sempre em Pé''( Version en portugués de ''Monkey Man'') . Inmediatamente reconocemos la portada de éste LP, recordando aquél reportaje que les hicieron en los 90's, el entrañable Rude Boy Latin Skazine que éra producido por importantes personajes de la movida en Caricuao como Hector ''Cadillacs'' Rodriguez e Ivan Perez Salaya

1-Ma Circulacao
2-O Mundo E Teu
3-Sempre Em Pé
4-Tou Bom
5-Misirlou
6-Quero que va tudo para o Inferno
7-Os Primos
8-Rude Boy (Loop)
9-TV Ska
10-Familia Virtual
11-La Botella
12-Valsa Das Bonecas

https://rapidshare.com/files/550481407/Despe%20E%20Siga%20-%20Os%20Primos%20(1996).rar


Quick Tip: The OOP Principle of Cohesion

This entry is part 2 of 2 in the series Beginner's Guide to OOP

In the first post of this series, we discussed why object-oriented programming (OOP) was helpful for game development, and learned how to identify objects, their states, and their behaviors. In this article, we’ll look at the specific OOP principle of cohesion and how it applies to games.

Note: Although this tutorial is written using Java, you should be able to use the same techniques and concepts in almost any game development environment.


What Is Cohesion?

Cohesion is the principle of being or doing one thing well. In other words, cohesion means grouping together code that contributes to a single task.

A great non-programming example of this principle was covered in one of the first Gamedevtuts+ articles which talked about the Covert Action Rule:

Don’t try to do too many games in one package … Individually, those each could have been good games. Together, they fought with each other.

The same rule applies to object-oriented programming. Each object should only have one responsibility. Every behavior of that object should only do one task. Any more than that and you’ll have a much harder time making changes to the code.


Why Is It Helpful?

Code that is organized by functionality and does only one task is said to have high cohesion. Highly cohesive code is reusable, simple, and easy to understand. It also creates objects that are small and focused.

Code that is organized arbitrarily and has multiple tasks is said to have low cohesion. Such code is difficult to understand, maintain, and reuse, and is often complex. It also creates objects that are large and unfocused.

Having high cohesion is generally good, while having low cohesion is generally bad. When writing code, always strive to write highly cohesive code.


How to Apply It

So how do we apply this to object-oriented programming? Well for starters, organizing code into objects helps increase cohesion of the game in general. However, each individual object should also have high cohesion. Let’s refer back to our three examples to see how this works.

Asteroids

Recall from the last article that we defined the ship object as having behaviors of turning, moving, and firing.

If we were to write a single piece of code that did all three behaviors at once, it would get pretty messy. Instead, we should separate each behavior into what are known as functions. Functions allow us to separate functionality and group similar code together, thus helping to create highly cohesive code.

In programming, an object is defined by creating a class. In Java, a class is coded as follows:

  /**  * The Ship Class  */  public class Ship {    /**     * Function – performs the behavior (task) of turning the Ship     */    public void rotate() {      // Code that turns the ship    }    /**     * Function – performs the behavior (task) of moving the Ship     */    public void move() {      // Code that moves the ship    }    /**     * Function – performs the behavior (task) of firing the Ship's gun     */    public void fire() {      // Code that makes the ship fire a bullet    }  }  

As you can see, each behavior gets its own function, and the code is pretty well organized just in this skeleton structure.

Don’t worry too much about the exact syntax just yet; we’ll discuss it in more detail as we get further along in the series.

Tetris

For Tetris, recall that the behaviors of a tetromino were falling, moving (sideways), and rotating. The basic class structure is as follows:

  /**  * The Tetromino Class  */  public class Tetromino {    /**     * Function – update a Tetromino's position     */    public void fall() {      // Code that updates the Tetromino's position    }    /**     * Function - move a Tetromino     */    public void move() {      // Code that moves the Tetromino sideways    }    /**     * Function – rotate a Tetromino     */    public void rotate() {      // Code that rotates the Tetromino by 90 degrees    }  }  

Again, the behaviors are separated into their own functions. For the fall method, though, notice that the task is to update the tetromino’s position. This is because the tetromino is always falling, so we can’t just make the task “cause the tetromino to fall”.

Instead, a falling tetromino just moves down the screen a certain number of rows at a time – so we have to update the position of the tetromino to reflect this falling speed.

Pac-Man

For the ghost object with behaviors of moving and changing state, we have to do a bit more work to get it to be highly cohesive.

  /**  * The Ghost Class  */  public class Ghost {    /**     * Function – moves the Ghost     */    public void move() {      // Code that moves the ghost in the current direction    }    /**     * Function - change Ghost direction     */    public void changeDirection() {      // Code that changes the Ghost's direction    }    /**     * Function – change Ghost speed     */    public void changeSpeed() {      // Code that changes the Ghost's speed    }    /**     * Function – change Ghost color     */    public void changeColor() {      // Code that changes the Ghost's color    }    /**     * Function – change Ghost state     */    public void changeState() {      // Code that changes the Ghost's state      // This function also will call the three functions of changeDirection, changeSpeed, and changeColor    }  }  

The Ghost state has three extra functions added to it: changeDirection, changeColor, and changeSpeed. These weren’t in our original behavior list because they aren’t behaviors. Instead, these functions are what are known as helper functions and are there to help us maintain high cohesion.

The behavior of changing state (what happens when Pac-Man eats a power pellet) requires three different tasks to be performed: turn deep blue, reverse direction, and move more slowly. To maintain cohesion, we don’t want one function to do all three of these tasks, so we divide them up into three subtasks that the function will call upon to complete its one main task.

The use of the word and when describing what a behavior/function does usually means we should create more than one function.


Conclusion

Cohesion is the principle of grouping like code together and ensure each function performs only a single task. Cohesion helps to create code that is maintainable and reusable.

In the next Quick Tip, we’ll discuss the principle of coupling and how it relates to cohesion. Follow us on Twitter, Facebook, or Google+ to keep up to date with the latest posts.



Científicos descubren forma de diagnosticar la esquizofrenia con un simple examen ocular

Un conjunto de investigadores de la Universidad de Aberdeen ha descubierto un método cercano al 100% de precisión para detectar si una persona tiene esquizofrenia a través de una simple prueba ocular. Un hallazgo que podría acelerar la detección de la enfermedad.

Esquizofrenia

Todo gracias al deterioro de los ojos y su implicación con la enfermedad. El estudio informa de un modelo de prueba que demuestra con un 98% de precisión en la distinción entre las personas con y sin esquizofrenia.

Pruebas oculares simples con la que los investigadores exploran en el movimiento de los ojos si se sufre o no la enfermedad. Los resultados de la investigación mostraron que las personas con esquizofrenia tenían déficits en la capacidad de rastrear objetos en movimiento, de la misma forma, también les resultaba más difícil mantener la mirada firme.

El estudio fue dirigido por los doctores Philip Benson y David Clair y consistía en una serie de exámenes de vista donde a los voluntarios se les pedía que rastrearan objetos en movimiento lentos con sus ojos a la vez que debían mantener la mirada fija sobre un solo objetivo. Según el doctor Benson:

Se ha sabido desde hace más de cien años que las personas con enfermedades psicóticas tienen una variedad de movimientos anormales del ojo, pero hasta nuestro estudio, nadie pensaba que las deficiencias eran lo suficientemente sensibles como para ser utilizadas como potenciales biomarcadores de diagnóstico clínico.

En seguimiento lento, las personas con esquizofrenia tienen un déficit en la capacidad para realizar este tipo de seguimiento en objetos. Sus movimientos de los ojos tienden a caer detrás del objeto en movimiento para luego pasar a una serie de movimientos oculares rápidos.

Para constatar el estudio se utilizaron varios métodos que modelaban los datos. La combinación de todos ellos dio como resultado un modelo con una efectividad del 98%. Según el doctor Clair:

Las evaluaciones actuales neuropsicológicas son lentas, costosas y requieren personal capacitado para su uso. En comparación, nuestros exámenes oculares son simples, baratos y toman solo unos minutos para llevarse a cabo. Esto significa que un modelo productivo con tal precisión podría ser incorporado en las clínicas y hospitales para ayudar a los médicos en los sistemas de diagnóstico tradicionales.

Una investigación pionera que podría ahorrar costes a la vez que hallar si un individuo tiene esquizofrenia con una serie de pruebas sencillas oculares.





La web de MEGA comienza a dar sus primeros pasos

Uno de los estrenos más esperados del invierno es, sin duda alguna, Mega y Megabox, el nuevo proyecto de Kim Dotcom con el que, cual ave fénix, regresará a la red para marcar un punto de inflexión de la misma forma que lo hizo con Megaupload (hasta que fue cerrado por el FBI). Poco a poco, el propio Dotcom va mostrando pequeñas dosis de lo que será su servicio de música (Megabox) y el nuevo sistema de almacenamiento en la nube (Mega) y siguiendo esta senda, hoy Dotcom ha anunciado que la web de Mega ya está activa (aunque el servicio aún lo está) y su dominio definitivo será Me.ga.

MEGA

El anuncio, que se ha realizado a través de Twitter, nos invita a visitar la que será la página de Mega aunque, por ahora, ésta se redirige hacia kim.com/mega. ¿Y qué podremos encontrar ahí? Lógicamente el servicio aún no está activo pero sí que podemos comenzar a explorar algunos detalles sobre el mismo además de apuntarnos a una lista de correo para recibir notificaciones sobre las novedades que se produzcan.

ANNOUNCEMENT: The new #Mega domain is me.ga - Check it out. RT!!

— Kim Dotcom (@KimDotcom) noviembre 1, 2012

El 19 de enero es la fecha elegida para el estreno de Mega y, para ir arrancando motores, la web nos muestra algunos detalles relativos a cómo será el servicio. Sabíamos que Mega iba a poner el foco en la privacidad y, por tanto, en el cifrado de la información; un hecho que queda patente en la web en la que se comenta que esta nueva plataforma en la nube estará cifrada, lo cual redundará en la privacidad de los usuarios y también permitirá distribuir la infraestructura en múltiples centros de datos (en un esquema similar a la nueva arquitectura de The Pirate Bay).

Por otro lado, Mega aspira a ofrecer a los usuarios un servicio en la nube con el que puedan compartir fácilmente archivos y carpetas de sus equipos, pudiendo montar las “unidades en la nube” como si fuesen discos duros físicos de nuestro sistema o carpetas locales (facilitando así el acceso a la información y simplificando cómo compartir archivos con otros usuarios).

Un proyecto tan ambicioso, como es lógico, necesita el respaldo de partners y con esa idea Dotcom ha habilitado en la web apartados orientados a proveedores de hosting que quieran colaborar en el proyecto (y aumentar la infraestructura en la nube del servicio) así como inversores que quieran inyectar capital en el proyecto y, por tanto, alargar el período en el que el uso será gratuito. Además, para completar el círculo de usuarios-inversores-infraestructuras, Mega también tendrá un API para los desarrolladores que quieran trabajar en aplicaciones que usen el servicio y hacer crecer así un ecosistema alrededor de este servicio de almacenamiento en la nube (un API al que ya tienen acceso algunos desarrolladores).

La fecha del 19 de enero de 2013, sin duda, es un día a marcar en nuestro calendario porque, por los datos que se van conociendo, Mega va a ser un servicio que dará mucho que hablar.





Tablets sin profesores para niños en Etiopía demuestran el aprendizaje por sí mismos

Alguna vez os hemos hablado del proyecto One Laptop Per Child, una idea que trata de acercar la tecnología actual a aquellos niños que no tienen acceso a la educación en el mundo. Una de las acciones desarrolladas tuvo lugar en dos aldeas de Etiopía con unos resultados increíbles. La propuesta: dejar un conjunto de tabletas con programas precargados y ver qué ocurría.

OLPC

El objetivo era ver si los niños, todos analfabetos y sin exposición previa a las palabras escritas, podían aprender a leer por sí mismos, mediante la experimentación con la tableta y el software precargado que incluía juegos sobre el alfabeto, libros electrónicos, películas, programas para dibujar…

Los primeros resultados no han podido ser más esperanzadores según contó en la conferencia del MIT la semana pasada Nicholas Negroponte, fundador de OLPC. Los dispositivos que se les dieron a los niños eran tablets Motorola Xoom que llevaban incorporadas un sistema de carga solar que los trabajadores de OLPC habían enseñado a utilizar a los adultos de las aldeas.

Luego, una vez por semana se pasaba un trabajador del proyecto para observar los avances que tenían los jóvenes y el uso que se les había dado a las tablets. Tras varios meses, los niños de ambos pueblos ya habían adoptado el uso y recarga de las máquinas, también sabían recitar la “canción del alfabeto” e incluso deletrear palabras. Uno de los niños expuesto a los juegos de alfabetización con imágenes de animales llegó a abrir un programa de dibujo y escribir la palabra “león”.

Un experimento que se realizó en dos aldeas rurales con 20 niños de cada pueblo. Ninguno de ellos había visto previamente materiales impresos. Así contaba Negroponte el increíble desarrollo vivido en las aldeas:

Nuestros trabajadores dejaron cajas cerradas que contenían las tablets, cerradas, sin ninguna instrucción. Al principio los niños jugaban con las cajas. A los cuatro minutos, un niño no sólo abrió la caja, sino que encontró el interruptor de encendido y apagado … llegando a encenderlo. A los cinco días, estaban utilizando 47 aplicaciones al día por niño. Después de dos semanas, cantaban canciones del abecedario en el pueblo, y después de cinco meses, habían hackeado el sistema operativo Android. Alguien en nuestra organización o en el Media Lab había deshabilitado la cámara sin darse cuenta, ellos la descubrieron y la habilitaron, habían hackeado Android.

Durante la conferencia le tocó el turno de palabra a Ed McNierney, director de tecnología de OLPC, quién explicó parte del “hack”:

Los niños habían conseguido acceder a la configuración del escritorio. Los chicos habían personalizado completamente el escritorio, de manera que cada tableta de cada niño se veía diferente. Habíamos instalado software para evitar que lo hicieran. La manera en la que trabajaban a su alrededor era claramente el tipo de creatividad, el tipo de investigación, el tipo de descubrimiento que creemos que es esencial para el aprendizaje. Si ellos pueden aprender a leer, entonces pueden leer para aprender.

Unos resultados prometedores que aún así necesitarán de nuevos proyectos similares para constatar que los niños pueden aprender a leer de esta manera. Negroponte acabó la conferencia con una pregunta para la comunidad:

¿Qué podemos hacer con los 100 millones de niños en el mundo que no van a la escuela? Quizá ofrecerles las herramientas para que lean y aprendan, sin necesidad de proporcionar escuelas, profesores o libros de texto.





miércoles, 31 de octubre de 2012

Building a Scalable App With Backbone.js

Backbone.js is a small library (~5kb minified) that allows you to build single page web applications. Unlike many of its peers, Backbone is not very opinionated about the way you use it. Aside from some basic concepts, the design of your application is left widely up to you.

This tutorial will offer some insight on one of the popular patterns that the community has started to embrace: the Backbone Boilerplate. We will use this boilerplate to create a simple library of books, which you could easily extend into a much more robust application.


A Quick Overview of Libraries

It’s very flexible and incredibly lightweight.

Backbone.js is a JavaScript framework that allows us to easily create single page web applications. It’s very flexible and incredibly lightweight, which is why it has become one of the most popular JavaScript frameworks available.

Require.js is a module loader (leveraging the AMD design pattern) that allows you to asynchronously load your JavaScript modules and their dependencies.

Underscore.js a library that provides a set of utility functions you would come to expect when working with a programming language. Among other things, it gives you the ability to iterate over collections, to test if code is a function, and has a templating language built-in.


What is Backbone Boilerplate?

The Backbone Boilerplate is simply a set of best practices and utilities for building Backbone web applications. It is not an additional library, but it merges together a few libraries to encourage some structure when creating Backbone projects.

The Backbone Boilerplate is not an additional library.

There are a couple of ways to install the Backbone Boilerplate. The easiest (and preferred) method is the grunt-bbb plugin. However, that requires the use of Node.js and NPM, which is out of the scope of this tutorial. We will be doing a manual install instead.

To get started, head on over to the Github repository and download a copy of the code (you should see the .zip icon near the top). The copy you are downloading has been modified from the original with a lot the example code removed. There are a bunch of very useful comments in the example code (from the original boilerplate) – feel free to read over them in your spare time.

That’s it! We can get starting with creating our application.


Your First Module, the Book!

When you are working with the Backbone Boilerplate (or any project using AMD/Require.js), you will be grouping functionality into modules, and generally putting each module in its own file. This creates a “separation of concerns” and allows you (and anyone else who reads your code) to easily understand what the code should be doing.

To create your first module, simply put the following code into the file app/modules/book.js.

  define([    "namespace",    "use!backbone"  ],  function(namespace, Backbone) {    var Book = namespace.module();    // Router    Book.Router = Backbone.Router.extend({      routes: {        "book/:p"   : "details"      },      details: function(hash){        var view = new Book.Views.Details({model: Library.get(hash)});        view.render(function(el){          $("#main").html(el);        });      }    });    // Instantiate Router    var router = new Book.Router();    // Book Model    Book.Model = Backbone.Model.extend({});    // Book Collection    Book.Collection = Backbone.Collection.extend({      model: Book.Model    });    // This will fetch the book template and render it.    Book.Views.Details = Backbone.View.extend({      template: "app/templates/books/details.html",      render: function(done) {        var view = this;        // Fetch the template, render it to the View element and call done.        namespace.fetchTemplate(this.template, function(tmpl) {          view.el.innerHTML = tmpl(view.model.toJSON());          if (_.isFunction(done)) {            done(view.el);          }        });      }    });    // This will fetch the book list template and render it.    Book.Views.List = Backbone.View.extend({      template: "app/templates/books/list.html",      render: function(done){        var view = this;        namespace.fetchTemplate(this.template, function(tmpl){          view.el.innerHTML = tmpl({books: view.collection.toJSON()});          if (_.isFunction(done)){            done(view.el);          }        });      }    });    // Required, return the module for AMD compliance    return Book;  });  

This might look like a lot, but it is really quite simple. Let’s break it down below:

The AMD Module Definition

  define([    "namespace",    "use!backbone"  ], function(namespace, Backbone){    var Book = namespace.module();    return Book;  });  

This is the standard format for any AMD module definition. You are telling the module loader that this module needs access to your namespace and backbone, which are defined in app/config.js. Inside the callback function, you are registering your module, and returning it at the end (which follows AMD compliance).

The Module’s Router

  Book.Router = Backbone.Router.extend({});  var router = new Book.Router();  

Whenever the browser is directed to a route in the routes hash, the associated function is called. This is usually where you instantiate the view and call its render function. We instantiate the router so Backbone knows to start picking up the associated routes.

The Module’s Data

  Book.Model = Backbone.Model.extend({});  Book.Collection = Backbone.Collection.extend({    model: Book.Model  });  

This is where your book data and business logic is defined. You will create new instances of your Book.Model to store each book and its attributes (title, author, etc). Book.Collection is associated with Book.Model, and it is how you represent your models as grouped entities. In other words, a library has many books, and a collection is a lot like a library.

These are pretty bare, but you can place any of your business logic in the objects that are passed to the extend methods. If, for instance, you wanted to create a function that would filter books from the collection based on the author, you would do something like the following:

  Book.Collection = Backbone.Collection.extend({    model: Book.Model,    filterByAuthor: function(author){      return this.filter(function(book){        return book.get('author') === author;      });    }  });  

“Underscore functions can be called directly on a Backbone collection.”

This is leveraging the Underscore filter function, which (like most of the Underscore functions) can be called directly on the collection itself. Feel free to read the Backbone documentation for more information on what Underscore functions you can call on your collections.

The same idea applies to your models. You should ideally push all of your business logic to the model. This might be something like adding the ability for your users to set up a book as a ‘favorite.’ For now, you can remove the filterByAuthor method from your collection, as we won’t be using that in this tutorial.

The Module’s Views

  Book.Views.Details = Backbone.View.extend({    template: "app/templates/books/details.html",    render: function(done) {      var view = this;      // Fetch the template, render it to the View element and call done.      namespace.fetchTemplate(this.template, function(tmpl) {        view.el.innerHTML = tmpl(view.model.toJSON());        if (_.isFunction(done)) {          done(view.el);        }      });    }  });  

Your module will contain multiple views. In our example, we have a list view and a details view. Each of these has its own template, and a render function which calls fetchTemplate (defined in namespace.js), sets the result to the views innerHTML, and calls the associated callback function (done). One thing to notice, the list view is passing a collection to its template function, while the details view is passing the model to its template function. In both cases, we are calling toJSON() on the parameter. This helps us ensure that we are simply dealing with data at the template level.


Templates, With Little to No Logic

In app/templates/books/list.html

  <h1>Listing of Books</h1>  <ul>    <% _.each(books, function(book){ %>      <li><a href="book/<%= book.id %>"><%= book.title %></a></li>    <% }); %>  </ul>  

In app/templates/books/details.html

  <h1><%= title %></h1>  <ul>    <li><b>Author: </b><%= author %></li>    <li><b>Year Published: </b><%= published %></li>  </ul>  <a href="/">Back to List</a>  

Since we have a details view and a list view, we will need a template for each of them. In the list view, we will iterate over our collection and render a link to each book’s details view. In our details view, we display individual pieces of data pertaining to the book that was clicked. We are able to use the properties directly because we are passing the data into the template function with their toJSON() methods, which converts standard models/collections to their JSON representations.

Notice the fact that we didn’t have to call preventDefault() for any of the links that were on the page? That is because of the code at the bottom of app/main.js. We are saying any link on the page without data-bypass="true" will automatically invoke preventDefault(), using our Backbone routes instead of default link behaviour.


Bootstrapping Your Data and Setting Your Default Route

At the top of main.js, replace the code with the following:

  require([    "namespace",    // Libs    "jquery",    "use!backbone",    // Modules    "modules/book"  ],  function(namespace, $, Backbone, Book) {    window.Library = new Book.Collection([      { id: 1, title: "A Tale of Two Cities", author: "Charles Dickens", published: 1859 },      { id: 2, title: "The Lord of the Rings", author: "J. R. R. Tolkien", published: 1954 },      { id: 3, title: "The Hobbit", author: "J. R. R. Tolkien", published: 1937 },      { id: 4, title: "And Then There Were None", author: "Agatha Christie", published: 1939 }    ]);    // Defining the application router, you can attach sub routers here.    var Router = Backbone.Router.extend({      routes: {        "":   "index"      },      index: function(){        var view = new Book.Views.List({collection: Library});        view.render(function(el){          $("#main").html(el);        })      }    });    // Everything after the Router stays the same  });  

Typically, your server side component would pass data to your Backbone application through its API (you set these up in your Collections and Models). However, in this tutorial we are simply bootstrapping your views with a few static books, and creating the default route, which passes the Library to the Book list view as its collection.

The only other thing that has to change is the fact that you are passing your module into the module loader (notice the require instead of the define at the top of main.js). By doing this, you are telling your application to load the file and passing it into the callback function so you have access to all of the Book properties.


Wrapping Up

There are a number of other pieces to truly having a scalable web application.

You might be thinking that this looks very similar to every other Backbone tutorial you have read, so what makes this one different? Well, the key to this is the fact that all functionality relating to the Book is stored in one module, which is in its own file. Let’s say you decided to start sharing your movie collection on this site as well. It would be as simple as creating app/modules/movie.js, the associated templates, and telling main.js to load modules/movie.

There are a number of other pieces to truly having a scalable web application, the biggest of which is a robust API on the server. However, if you remember to create a separation of concerns when dealing with different modules in your application, you will find it much easier to maintain, optimize, and grow your code without running into too many issues as a result of unruly spaghetti code.

Additional Backbone learning on Nettuts+.



Ver Star Wars en ASCII desde la consola

¿Siempre pensaron que la consola era aburrida con esas letritas de colores? Quiero contarles que no todo es así, también la pueden usar para ver Star Wars en ASCII (?).

Para hacerlo sólo tienen que abrir un terminal y pegar lo siguiente y disfrutar de la “película”:

  telnet towel.blinkenlights.nl  

Visto en OSX Daily