mar 14 2011

Dibujando rutas en Google Maps

Dibujando rutas

Puedes consultar las partes anteriores del manual de Google Maps Api 3:
Primera parte del manual

Segunda parte del manual

Tercera parte del manual

Este servicio es interesante, a demás podemos usar coordenadas o direcciones directamente, ya que el servicio las traducirá por sí solo.
Las clases principales son: google.maps.DirectionsService que es la que ejecuta la peticion del servicio al servidor y nos devuelve los datos, y google.maps.DirectionsRenderer que es la encargada de mostrar la ruta en nuestro mapa.
El ejempo básico de inicialización es el siguiente:

directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer();

directionsDisplay.setMap(map);

La llamada a route tiene el formato “directionsService.route(request, function(result, status)”. Hay que generar un objeto request primero(DirectionRequest) que solo es necesario rellenar los campos que no sinteresan. Despues la funcion de callback es la que a partir del status tratamos los reultados.

var request = {
  origin:start,
  destination:end,
  travelMode: google.maps.DirectionsTravelMode.DRIVING
};

La llamada y el tratamiento del objeto result. Comprobamos que el status es OK, si no no hay nada que hacer, salvo mostrar el tipo de error.

directionsService.route(request, function(result, status) {
  if (status == google.maps.DirectionsStatus.OK) {
    directionsDisplay.setMap(map);
    var mystr="";
    for(var i in result.routes){
      var mylegs=result.routes[i].legs
      for(var j in mylegs){
        mystr += mylegs[j].distance.text;
        mystr += " " + mylegs[j].duration.text+ " <br/>";
      }
      mystr+="<br/>";
      $(“#infoRecorrido).html(mystr);
    }
    directionsDisplay.setDirections(result);
  }
});

Lo que realmente dibuja el mapa es ‘directionsDisplay.setDirections(result)’ ¿y todo lo demas? pues bien, google nos envia un objeto con bastante información. Los margenes en que se visualizará el mapa, las coordenadas de los puntos de incio y fin, y otras cosas entre ellas la distancia y tiempo de recorrido.
La distancia se encuentra en “result.routes[0..n-1].legs[0..n-1].duration”. Se puede visualizar en texto en tiempo ya tranformado en horas:minutos:segundos con ‘.text’ o directamente en el numero de segundos con ‘.value’.
La respuesta contiene bastante información y se le puede sacar mucho partido (ver: http://code.google.com/intl/es/apis/maps/documentation/directions/ )

bounds = new google.maps.LatLngBounds();
for(var l in markers){
  bounds.extend( markers[l].getPosition() );
}
map.fitBounds(bounds);

visto en: http://blog.shamess.info/2009/09/29/zoom-to-fit-all-markers-on-google-maps-api-v3/

Finalmente y por experiencia propia recomiendo re posicionar los margenes con cierto retardo con una función como esta:

function rebounds(){
  setTimeout(recReBounds,250,(6));
}

function recReBounds(veces)
  if(!veces){
    return false;
  }
  try{
    bounds = new google.maps.LatLngBounds();
    for(var l in markers){
    bounds.extend( markers[l].getPosition() );
  }
  map.fitBounds(bounds);
  }
  catch(e){
    setTimeout(recReBounds,250,(veces-1));
  }
}

rebounds();

A veces la velocidad del navegador que esté utilizando el cliente no carga las imágenes del mapa con mucha velocidad. Si ejecutamos el reajuste de margenes una vez recogidos los datos puede que se reajusten los margenes antes de pintar el mapa, con lo cual el reajuste no tiene efecto. Con un retardo de un cuarto de segundo el usuario siente interacción de la web y el reajuste tiene efecto.


mar 11 2011

Dibujar marcas en un mapa

Trabajando con los markers

Puedes consultar las partes anteriores del manual de Google Maps Api 3

primera parte del manual

segunda parte del manual

Para empezar vamos a trabajar con un vector de marcas que va a ser una variable global markers. Tan sencillo como:

var markers={};

setMarker hace algo más que posicionar un marker en el mapa. Seleciona el campo donde tenemos la localidad (o direccion), esto lo hace con la funcion dollar de jquery. Esta direccion la traduce a coordenadas LatLng con el servicio geocoder.
Despues invoca al método marker que es el que realmente inserta el marcador en el punto correcto del mapa.

function setMarker(id,addid){
  var dir = $("#"+id).val();
  geocoder.geocode( { 'address': dir}, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      marker(id, results[0].geometry.location);
    } else {
      marker(id,null);
    }
  });
}

Marker en realidad es una funcion muy sencilla. Si existe el marcador añade una nueva posición, si no existe lo crea indicandole el mapa y la posicion donde irá.
La unica complejidad en cuanto a configuracion del maker es indicarle que no sea arrastrable (draggable) ni que se pueda pinchar (clickable).

function marker(id, location){
  if(markers[id]){
    markers[id].setPosition(location);
  }
  else{
    markers[id] = new google.maps.Marker({
      map: map
      ,position: location
      ,markerOptions:{
        draggable:false
        ,clickable:false
      }
    });
  }

  map.setZoom(10);
}

Otras opciones posibles son hacer zoom y centrar el mapa en el marcador (en este caso está comentado) pero son opciones del mapa, no del marcador.

Borrar un marker

Para borrar un marker es tan sencillo como añadirle una posicion nula. Como en nuestro caso tenemos un objeto global donde están todos nuestros markers nos podemos hacer las funciones hideMarker y hideAllMarkers:

function hideAllMarkers(){
  for(var m in markers){
    markers[m].setPosition(null);
  }
}

function hideMarker(id){
  if(id && id != "" && markers[id]){
    markers[id].setPosition(null);
    return true;
  }
  return false;
}

*Cuidado si se usan otras propiedades de los markers como el texto que despliegan al clickarlos. Si volvemos a ponerle una posicion al marker esas propiedaden persisten. Suponemos que en esta aplicacion no añadimos informacion extra y que los markers no son clickables. En otro caso para más seguridad hay que hacer un new cada vez para chafar las propiedades anteriores, o cambiarlas una por una.


mar 5 2011

Introducción a Google Maps Api 3

Google Maps api3 con ejemplos

Esta es la primera parte de un manual sobre el Api 3 de google maps. Simplemente es una primera guia para cómo, a partir de pocas lineas de código, poder implementar una aplicación interesante en tu web.

Aportar información geolocalizada está hoy a la orden del día, yo voy a basarme en los ejemplos que proporciona google añadiendo variaciones que amplian su funcionamiento. Para hacerlo de forma más comoda voy a utilizar jQuery 1.4.2 en algunos casos.

Ejemplo ligeramente modificado con jquery:
-muestra un mapa. se puede insertar longitud y latitud numerica y actualizar el mapa. Despues una lista de las propiedades de google.maps

<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="./jquery.1.4.2.js"></script>
<script type="text/javascript">
var myOptions, latlng, map;

function initialize() {
  latlng = new google.maps.LatLng(-34.397, 150.644);
  myOptions = {
    zoom: 8,
    center: latlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}

$(document).ready(function(){
  $("#buttonver").click(function(){
    var latVar,lonVar;
    latVar = $("#lat").val();
    lonVar = $("#lon").val();
    latlng = new google.maps.LatLng(latVar, lonVar);
    myOptions.center=latlng;
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
  });
});
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:400px; height:400px"></div>
<label for="lat">latitud</label><input type="text" id="lat" name="lat" value="38.5"/>
<label for="lon">longitud</label><input type="text" id="lon" name="lon" value="-0.5"/>
<input type="button" id="buttonver" value="ver" />
</body>
</html>

Añadimos evento cuando haga click para que muestre la longitud y latitud:
*MEJORA: no hacemos un new Map cuando cambiamos las coordenadas. Usamos el método map.setCenter(latlng)

<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="./jquery.1.4.2.js"></script>
<script type="text/javascript">
var myOptions, latlng, map;

function initialize() {
  latlng = new google.maps.LatLng(-34.397, 150.644);
  myOptions = {
    zoom: 8,
    center: latlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
  google.maps.event.addListener(map, 'click', function(event) {
    alert(event.latLng);
  });
}

$(document).ready(function(){
  $("#buttonver").click(function(){
    var latVar,lonVar;
    latVar = $("#lat").val();
    lonVar = $("#lon").val();
    latlng = new google.maps.LatLng(latVar, lonVar);
    myOptions.center=latlng;
    map.setCenter(latlng);
  });
});
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:400px; height:400px"></div>
<label for="lat">latitud</label><input type="text" id="lat" name="lat" value="38.5"/>
<label for="lon">longitud</label><input type="text" id="lon" name="lon" value="-0.5"/>
<input type="button" id="buttonver" value="ver" />
</body>
</html>

Reseña sobre los eventos posibles:

- ‘click’
- ‘dblclick’
- ‘mouseup’ -> no me va
- ‘mousedown’ -> no me va
- ‘mouseover’
- ’mouseout’

En estos eventos se les pasa un event a la funcion calback que contiene una variable latLng.

- ‘zoom_change’ -> el callback no recibe parámetros
- ‘bounds_changed’
- ‘center_changed’

Enlaces de referencia:

-Tutorial:
http://code.google.com/intl/es/apis/maps/documentation/javascript/tutorial.html

-Referencia:
http://code.google.com/intl/es/apis/maps/documentation/javascript/reference.html

-Ejemplos:
http://code.google.com/intl/es/apis/maps/documentation/javascript/examples/


ene 16 2011

La funcion Dolar

Si llevas tocando JavaScript poco tiempo quizá aun no la hayas usado, pero por poco que lleves usando algun framework (biblioteca/libreria) seguro que te suena.
La función $ viene siendo de las más usadas o ampliamente implementadas en cualquier libreria JS para el manejo del DOM.

Que hay del DOM

DOM son las siglas de Document Object Model. La página html que estás viendo se estructura en el navegador como un árbol, en el que cada uno de los nodos del árbol es un objeto. El hecho de que se el navegador controle la página como un grupo de nodos Objeto beneficia al programador que quiere trabajar con esos objetos. Tratando cada elemento como un objeto le podemos asignar propiedades, eliminarlo o crear nuevos dinámicamente.

Cuando modificas un objeto visible del DOM los cambios se ven reflejados en el navegador. Si quieres ver más cosas sobre el DOM puedes ver la gran documentación de Mozilla de cómo Gecko (Motor de renderizado del a fundación Mozilla) implementa el DOM (DOM Gecko). Si cuando hayas terminado con esto te apetece profundizar más y tienes la posibilidad de poner el ‘Modo Dios’ de lectura puedes pelearte con la docu del w3c, que son los que dicen como tiene que ser el DOM (w3c DOM).

Tocando los nodos del DOM

Visto lo visto, si queremos que la página cambie sin recargar nos va a tocar modificar los elementos del DOM en el lado del cliente. Para acceder a un elemento que queremos modificar tenemos que acceder a el como a un objeto que es. Todos los objetos tienen un padre, y el padre de todos (la raíz del árbol) es el documento en si, es decir, el objeto document.

Para acceder al árbol existen distintas funciones. Estas nos permiten acceder al primer hijo, al último o a la lista de hijos y seleccionar el que queremos mediante corchetes:

result = document.firstChild.childNodes.length;//2
result = document.firstChild.childNodes[0];// [object HTMLHeadElement]
result = document.firstChild.childNodes[1];// [object HTMLBodyElement]
result = document.firstChild.childNodes[1].childNodes[n];//[object HTMLDivElement]

Acceder así a los elementos es bastante arido, por eso hay otras funciones que nos acortan el trabajo

Funciones que devuelven un HTMLCollection.

La definicion en IDL es:
interface HTMLCollection {
readonly attribute unsigned long length;
Node item(in unsigned long index);
Node namedItem(in DOMString name);
};

result = document.getElementsByTagName("div");//[object HTMLCollection]
result = document.getElementsByName("nombre");//[object HTMLCollection]
result = document.getElementsByClassName("nombreDeLaClase");//[object HTMLCollection]

Seleccionar por identificador a veces es más comodo porque el id debe de ser único

result = document.getElementById("identificador");// [object HTMLDivElement] porque hemos dado ese id a un div

Si tenemos más de un elemento con el mismo identificador (cosa que no debe ocurrir) hay que tener cuidado. La funcion ‘getElementById’ devuelve un solo Element (de ahi su nombre en singular) así que nos devolverá la primera ocurrencia solamente.

Los corchetes[] molan

La definición en del objeto HTMLColection nos da una interfaz para seleccionar un elemento concreto ya sea por nombre o por identificador, pero los corchetes facilitan mucho la vida del programador. Se puede invocar por nombre, identificador o numero de orden del elemento de la colección que queramos:

var result = document.getElementsByClassName("nombreDeLaClase");
result.namedItem("nombre") === result["nombre"];// true
result.item("identificador") === result["identificador"];// true
result.item(0) === result[0];// true
result.length;// 1

Para acceder a un elemento que esté en la página usamos a la estrella de las funciones de manejo del DOM:

var miElemento = document.getElementById("identificador");

Así tenemos en la variable ‘miElemento’ el elemento/objeto del DOM con id “identificador”. No tenemos que sabernos la ruta completa.

Y una vez seleccionado el elemento que queramos podemos acceder a su contenido en formato HTML. Con innerHTML podemos leer y escribir su contenido directamente. Este método no es un estándar de la especificación del lenguaje ECMAScript, pero todos los navegadores lo implementan. Lo inventó microsoft para una de sus primeras versiones del explorer y al extenderse su uso por comodidad, todos los browsers lo impementaron. Tan sencillo como:

result = document.getElementById("identificador").innerHTML;//a

Con todo esto manejamos el DOM a nuestro gusto, pero ¿me estoy saliendo del tema? no. Como hemos visto se puede acceder de distintas formas a los elementos de nuestra página. Por nombre, id, clase o posición en el árbol, pero escribir estas funciones con un nombre tan largo, con nombres tan parecidos para hacer lo mismo y obtener una tipo de objeto un tanto extraño no es muy cómodo para desarrollar.
La función dolar tiene que ver mucho con el manejo del DOM, y es que esta función surge a raíz de esta problemática.

PrototypeJS

En Prototype la funcion $ es la forma acortada de ‘document.getElementById’. En realidad tiene algo más de potencia ya que si le pasamos varios argumentos nos devolverá un vector con esos elementos seleccionados.
Así que devuelve o un elemento o un array con elementos. Ojo, si los elementos no existen en el árbol nos devolverá un array vacio.

Para seleccionar elementos del DOM Prototype viene con el metodo $F que viene a hacer lo mismo que $ pero dirigido a formularios. Como ellos dicen “es un alias comodo de Form.Element.getValue”.

Pero la funcion que realmente aporta ahorro al desarrollador es la funcion doble dolar $$(). El parámetro pasado a esta funcion debe ser un string que contenga el elemento o elementos a seleccionar, pero aqui viene lo bueno, acepta sintaxis CSS. Es decir que si quemos selecciona un elemento que tenga class con valor “miElemento” introducirmos : $$(“.miElemento”). Hasta aquí poca novedad, pero y si queremos seleccionear los elementos de una lista que tnegan class “miElemento”, pues la llamada será así: $$(“li.miElemento”) y así con todo tipo de selectores css http://www.w3.org/TR/css3-selectors/
A diferencia de $, $$ devolverá siempre un vector de Element.

MooTools

En Mootoos encontramos algo parecido en cuanto a funciones dolar se refiere. La funcion dolar está orientada a identificadores y encontramos los selectores CSS en la doble dolar. Contiene los selectores CSS3.
El selector CSS de MooTools se llama Slick. Lo sacaron para la version 1.3 de la librería y mejora en un 50% el selector de la version 1.2. A demás Slick es más rapido que el selector CSS de Prototype en un porcentaje variable pero en todos los navegadores.
Tambien le podemos pasár a la funcion $$ uno o más objetos Element, y devolverá una instancia de Element que los contenga.
Como vemos Dollars de MooTools añade algo más de funcionalidad que el Dollars de Prototype. En MooTools obtendremos de $$ una instancia del objeto Element de MooTools (como en Prototype) pero la mejora está en que acepta no solo cadenas con selectores si no también elementos propios.

jQuery

jQuery es una libreria orientada al DOM, de hecho la funcion $ es un alias de la funcion jQuery. La funcion $ nos devolverá un objeto jQuery que es la que contiene toda las funciones de la librería. Es la forma de trabajar en jQuery, al objeto que tenemos le hacemos lo que queremos.
Pero a la hora de pasarle parámetros, el $ de jQuery es el más versatil.
Acepta selectores CSS, elementos del DOM o arrays de elementos. A demás con los selectores podemos indicarle un contexto en el que seleccionarlo, si es que sabemos donde está lo que buscamos y no queremos que nos devuelva partes que estén más allá de ese ambito.
El selector jQuery es el más rápido de las tres librerías. Pero no solo de selectores vive el hombre. $ de jQuery acepta codigo HTML a pelo. ¿Y para qué? para generarlo dinamicamente. Esto nos permitirá crear partes de la pagina al vuelo para insertarlas donde queramos.
Por si fuera poco $ en jQuery también es un alias del metodo “$(document).ready” (que es como asignar un metodo en “document.onload”). Así que si le pasamos como parámetro una funcion, esta será ejecutada tras la carga completa del documento.
Sin duda es la función Dollar más versátil. Esta librería está orientada a usar el $ y a usar el DOM, de esta manera ahorra muchas lineas de código a los programadores que solo utilicen JavaScript para manejar el DOM, que son la mayoría, por eso está teniendo tanto exito.

Está claro que el $ no da la felicidad, por eso cada cual se lo implementa a su manera. Es el nombre de función más representativo que existe, corto y poco común. Por corto le proporciona ahorro de tiempo en la programación, y lo poco común le proporciona ahorro de tiempo en la lectura del código.
Como en definitiva para una gran proporcion de programadores vienen usando JavaScript para manejar el DOM sin incluir mucha más logica en las aplicaciones JS, el seleccionar elementos (sea estilo CSS o no) el mejor alias para un selector es el caracter Dolar.
Sinceramente, aunque sea para acortar la funcion “document.getElementById” ya es útil. Si como hemos visto le añadimos algunas funcionalidades extra mejor que mejor.


ene 5 2011

Metodos de instancia y de clase

En JavaScript no existen clases, se simulan las clases con objetos funcion que hacen las veces de constructor. Pero a pesar de ello a los desarrolladores backend les sigue gustando usar clases. En general a todo el mundo que venga de otro lenguaje OO le gusta seguir utilizando clases, o algo que las simule, para instanciar los objetos que van a utilizar.
En la documentacion de Prototype JS clasifican los métodos de una “clase” en dos categorías: métodos de instancia () y métodos de clase (). Por ejemplo la clase Element que se usa para trabajar con el DOM.

El caso de jQuery es bastante distinto. JQuery es un único objeto (lo que seria una clase para Prototype) con distintas propiedades. Cuando usamos el selector $, este nos devuelve un objeto instancia de jQuery, que referencia al elemento del DOM que le hallamos indicado. Este objeto instanciado, tiene propiedades comunes al objeto jQuery pero otras muy variadas. Esto es así porque en el objeto instanciado puede contener un array de elementos del DOM, todo el documento (con $(document)… ) o un div creado al vuelo y que no cuelga de ninguna rama del DOM aun; en general cualquier cosa, por eso tiene propiedades varias para trabajar con cualquier elemento posible.

La documentación de jQuery muestra los metodos de dos formas dependiendo de si son de instancia o de clase. Los métodos de clase aparecen con las nomenclatura “jQuery.metodo()” y los de instancia aparecen empezando por un punto: “.metodo()” que son los que normalmente para trabajar de forma ágil se usan del modo: “$(“#id”).metodo()“.

Documentación jQuery Prototype Style

Me preguntaba como sería ver la documentación de jQuery al estilo de la docu de PrototypeJS. En definitiva aparecería una sola clase (jQuery en si) seria algo parecido a lo que sigue:

Propiedades de jQuery: Class Method

prototype fn extend noConflict isReady ready bindReady isFunction
isArray isPlainObject isEmptyObject error parseJSON noop globalEval nodeName
each trim makeArray inArray merge grep map guid
proxy uaMatch browser support props cache expando noData
data removeData queue dequeue attrFn attr event Event
find expr unique text isXMLDoc contains filter dir
nth sibling fragments clean cleanData style css curCSS
swap get getScript getJSON post ajaxSetup ajaxSettings lastModified
etag ajax handleError active httpSuccess httpNotModified httpData param
speed easing timers fx offset

Propiedades del prototipo de jQuery (objeto jQuery): Instance Methods

init selector jquery length size toArray get pushStack
each ready eq first last slice map end
push sort splice extend data removeData queue dequeue
delay clearQueue attr removeAttr addClass removeClass toggleClass hasClass
val bind one unbind delegate undelegate trigger triggerHandler
toggle hover live die blur focus focusin focusout
load resize scroll unload click dblclick mousedown mouseup
mousemove mouseover mouseout mouseenter mouseleave change select submit
keydown keypress keyup error find has not filter
is closest index add andSelf parent parents parentsUntil
next prev nextAll prevAll nextUntil prevUntil siblings children
contents text wrapAll wrapInner wrap unwrap append prepend
before after remove empty clone html replaceWith detach
domManip appendTo prependTo insertBefore insertAfter replaceAll css serialize
serializeArray ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend show
hide _toggle fadeTo animate stop slideDown slideUp slideToggle
fadeIn fadeOut offset position offsetParent scrollLeft scrollTop innerHeight
outerHeight height innerWidth outerWidth width
*si el objeto es un elemento del DOM también aparecerá en esta lista la propiedad ‘context’.

Propiedades Comunes de jQuery y de su prototipo.

En general los métodos de instancia y de clase comunes son los siguientes:

extend ready error each map data removeData queue
dequeue attr find text filter css get offset

En este articulo no me voy a meter con la diferencia entre una librería y otra, eso ya quedaría para otro momento. Pero en cuanto a documentaciones se refiere me gusta bastante el estilo claro de la de Prototype. Aunque ya hace tiempo que me acostumbré a buscar en la documentación de jQuery, veo que no pueden hacer toda la documentación en una sola página. Su documentación sigue la misma filosofía que la librería pero puede ser confuso para quienes empiezan a trabajar con ella, y todo viene de que hay que cambiar la forma de pensar cuando se cambia de lenguaje. JavaScript is diferent. XD


dic 14 2010

Zepto un mini jQuery

ZeptoJSPensando en que los móviles no tienen mucha capacidad de computo (todo es cuestionable) ni tanto ancho de banda (esto ya suele ser más normal) que los ordenadores personales, ha surgido la idea de minimizar el tamaño de la libreria (biblioteca) más popular de javascript y su nombre es Zepto.
Como jQuery pero en aerogel. Esa es su filosofía, y la verdad es que la parte ajax de la biblioteca la dejan an 39 lineas de código.
Que se reducen sus funcionalidades es algo lógico y normal, pero en realidad las principales y muchos selectores CSS siguen estando.
Las cosas que cambian y con motivo son por ejemplo la detección de UserAgent que la implementa de la siguiente manera:

android = ua.match(/(Android)\s+([\d.]+)/),
iphone = ua.match(/(iPhone\sOS)\s([\d_]+)/),
ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
webos = ua.match(/(webOS)\/([\d.]+)/);

Como veis aunque está pensado para dispositivos móviles está orientado hacia el uso de un navegador con webkit. De hecho todo el apartado de FX de la librería lo solucionan con las directivas de webkit.

$.fn.anim = function(props, dur, ease){
var transforms = [], opacity, k;
for (k in props) k === 'opacity' ? opacity=props[k] : transforms.push(k+'('+props[k]+')');
return this.css({ '-webkit-transition': 'all '+(dur||0.5)+'s '+(ease||''),
'-webkit-transform': transforms.join(' '), opacity: opacity });
}

Me gusta la iniciativa de una versión ‘mini’ o ‘movil’ de jQuery, de hecho en muchas ocasiones no se utiliza la librería en todo su esplendor, cosa que es normal. Pero en el caso de Zepto, que aun va por la versión 0.2 se podria tener en cuenta el resto de navegadores para moviles (como opera mini).