Actionscript


Un año más la gente de Subflash organiza unos Talleres abiertos de verano el 25 y 26 de Agosto, donde flasheros de todos los lugares de España y Latinoamérica se juntan para asistir a las ponencias, compartir experiencias, conocimientos y disfrutar del comer y beber del lugar. Tras Teruel, Madrid, Barcelona y Oviedo, este año toca Málaga.
Este evento sin ánimo de lucro está dirigido a todos los desarrolladores web. La convocatoria es abierta, con lo que cualquier persona podrá inscribirse en el sitio web para asistir a las ponencias, bien como oyente si se encuentra en Málaga, o bien mediante opción completa, con alojamiento y pensión completa.
Personalmente solo puedo escribir alabanzas hacia este evento, que… no sólo me ha servido en el plano profesional, sino también en el plano personal, forjando grandes amistades con muchos de los asistentes durante los cuatro años que llevo asistiendo al evento.
Este año no va a poder ser por temas académicos y no podré asistir. Solo les deseo que lo pasen tan bien como yo lo hice en los años anteriores, y animo a todo aquel que habite en el mundillo del desarrollo web y Flash a que se inscriba para este año. La experiencia es única!

Más información:
http://www.subflash.com/talleres/2007/

Un poco de madera, unas canicas y la gravedad es lo único que necesita este sujeto para explicar la manera en la que suma un computador. Muy didáctico para los que siempre se lo preguntaron.


[calculadora de bolsillo]


[ instinto felino ]

Por aquí dejo un prototipo de experimento que empecé hace como un año y medio. Se trata de un sistema de visualización gráfica en forma de árbol del rss del sitio web Actionscript.es. Para los que no lo conozcan, actionscript.es es un portal de enlaces y recursos del lenguaje de programación Actionscript para su plataforma Flash, donde podemos encontrar los sitios web de obligada visita para cualquier desarrollador y diseñador de esta plataforma, así como añadir nuevos enlaces al portal. Dicha página, pone a dominio público, un feed RSS de los enlaces de la misma, de manera que cualquiera (en este caso, yo) pueda acceder a los recursos que allí se brindan, y representarlos a su antojo.

La idea del experimento era presentar el directorio de enlaces del portal mediante un juguete visual y dar una vuelta de tuerca al árbol de datos de la web, además de servirme como “sparring” para el desarrollo de un conjunto de clases para el tratamiento de sistemas de representación de redes y datos complejos.

Es curioso, pero con muchos de mis experimentos personales, me pasa como con los pantalones de mi armario. Al principio, como son nuevos, los pongo casi todos los días (equivale a cuando se me ocurre alguna idea y me pongo a desarrollarla). Pero pasado un tiempo, los pantalones se van rompiendo y desgastando (problemas, bugs) , y cada vez me los pongo menos (dedico menos tiempo al desarrollo), me compro unos nuevos (nuevas ideas), y aquellos pantalones quedan olvidados en el fondo del armario (mi repositorio). De vez en cuando, me topo con ellos, y pienso para mí “cómo los voy a regalar, si todavía están nuevos…” (regalar= liberar ó publicar) y aquellos pantalones, aguantan una temporada más en el fondo del armario esperando para nada.
Hasta que por fin, un día, me armo de valor y lo publico, a medias, y dos años después de haberlo parido. Más vale un experimento a medias que un no-experimento, ¿no es así?

TuneGlue

Chaval, te han comido la merienda. Estoy seguro que es la frase que dirán los que me conocen y saben detrás de lo que ando después de leer este hilo.

Me explico. Hace tiempo descubrí last.fm, una red social para música en la que puedes descubrir artistas nuevos en base a parecidos musicales o estilos, conocer usuarios con criterios musicales similares a los tuyos, además tienen una radio estilo Pandora, un interfaz muy orientado a la participación… Para los profanos, la página es algo así como Myspace Music, pero sin los odiosos fondos cutres y horteras y con la información de los artistas y usuarios mucho más estructurada y relacionada.

Además de todo esto, lo que más me gustó de la misma, y su valor diferencial, son sus poderosos servicios web, que pueden, desde leer los tags de tu Winamp o iTunes para listar las canciones que más escuchas en tu espacio personal para establecer perfiles, estadísticas y similitudes entre artistas, hasta consultar vía xml casi toda la información que la web dispone.

Además, al tratarse de un servicio basado en la información que apporta la comunidad, la página está viva y se autoalimenta en base a las tendencias musicales que la sociedad descubre. Me gustaba todo menos la información tabular. Quiero decir, buscaba “soulwax” para encontrar artistas similares, y bien, me aparecían artistas para conocer, pero mostrados en una aburrida tabla o “grid” de datos.

Así que inspirado en las herramientas “Eye candy” de representación de datos complejos basadas en grafos se me ocurrió la idea de utilizar dichos servicios web para un juguete visual que además fuera útil; navegar por un grafo de tendencias musicales basadas en artistas alimentado por last.fm

Tras algunos esbozos para desarrollar un conjunto de clases de representación de este tipo de redes, mi pequeño proyecto se paró un año por trabajo y estudios. Ahora descubro con pesar, que literalmente me han comido la merienda. Me queda al menos el consuelo de que alguien, en otro lugar del mundo pensó en la misma idea que yo, la y la parió tal y como me la imaginaba.

TuneGlue° | Relationship Explorer

Soy la leche. Hago una clase que puede ser útil para la humanidad, y la tengo dos años y medio cogiendo polvo, y sin apenas usar en plan gollum ( tesoooro) en vez de soltarla, hasta que casi queda obsoleta. Así que, para que la mejoréis y para que la disfrutéis, por aquí suelto esta clase antes de que no la use ni yo.

Es una Clase que maneja precargas en serie en Actionscript 2.0, está implementada con LoadMovie para permitir cargar sonidos y demás. Es útil en galerías de imágenes donde las cargas en paralelo no son tan útiles porque hace falta ir mostrando el contenido según va cargando, en el orden de carga. Usa modelo de despachado de eventos, con lo que es muy fácil integrarla con otras clases.

Actionscript:
  1.  
  2. import com.gskinner.events.GDispatcher;
  3. import mx.utils.Delegate;
  4. /**
  5. * @author Alejandro Sánchez Marcos
  6. * http://www.electroduendes.com/
  7. * @version 1.1
  8. * @usage  Clase para cargar Jpgs o swfs en un contenedor en serie (una detrás
  9. * de otra). Suele ser útil para galerías de imágenes.
  10. *
  11. * listeners:
  12. *      - onLoadProgress; devuelve un objeto del tipo:
  13. *      {type:"onLoadProgress", mc:MovieClip, progress:Number, total:Number, percent:Number};
  14. *      
  15. *      - onLoadActualStart; devuelve un objeto del tipo:
  16. *      {type:"onLoadActualStart", mc:MovieClip}
  17. *      
  18. *      - onLoadActualComplete; devuelve un objeto del tipo:
  19. *  {type:"onLoadActualComplete", mc:MovieClip}
  20. *      
  21. *      - onLoadAllComplete; devuelve un objeto del tipo:
  22. *      {type:"onLoadAllComplete"}
  23. *      
  24. * <code>
  25. *           import com.electroduendes.precarga.PrecargaSerie;
  26. *           import mx.utils.Delegate;
  27. *           
  28. *           var precarga:PrecargaSerie = new PrecargaSerie();
  29. *           var urls:Array = new Array("1.jpg", "2.jpg", "3.jpg", "4.jpg");
  30. *           var clips:Array = new Array(_root.uno,
  31. *                _root.dos, _root.tres, _root.cuatro);
  32. *           precarga.addEventListener("onLoadProgress",
  33. *                Delegate.create(this, progreso));
  34. *           precarga.addEventListener("onLoadActualComplete",
  35. *                Delegate.create(this, fincarga));
  36. *           precarga.addEventListener("onLoadAllComplete",
  37. *                Delegate.create(this, fintodo));
  38. *           precarga.addEventListener("onLoadActualStart",
  39. *                Delegate.create(this, inicioCarga));
  40. *           precarga.loadClips(urls, clips);
  41. *           
  42. *           function progreso(obj) {
  43. *                trace("progreso despachado para mc "+obj.mc+ " al : "+obj.percent+"%");
  44. *           }
  45. *           function inicioCarga(obj){
  46. *                trace("inicio de carga para el mc"+obj.mc);
  47. *           }
  48. *           function fincarga(obj) {
  49. *                trace("fincarga despachada para movieclip: "+obj.mc);
  50. *           }
  51. *           
  52. *           function fintodo() {
  53. *                trace("fintodo despachado");
  54. *           }   
  55. * </code>
  56. */
  57. class com.electroduendes.precarga.PrecargaSerie {
  58.  
  59.         private var numCargados:Number = 0;
  60.         // número de objetos que ya están cargados
  61.         private var actualProgress:Number = 0;
  62.         // almacena el progreso de carga
  63.         private var actualTotal:Number = 0;
  64.         private var actualPercent:Number = 0;
  65.         private var actualTarget:MovieClip = null;
  66.         private var urlArray : Array;
  67.         private var targetArray : Array;
  68.         private var interval:Number = 0;
  69.         var dispatchEvent:Function;
  70.         var addEventListener:Function;
  71.         var removeEventListener:Function;
  72.         function PrecargaSerie(){
  73.                 GDispatcher.initialize(this);
  74.         }
  75.         /*
  76.          * inicia el proceso de carga
  77.          * @param urlArray el arrray de películas a cargar
  78.          * @param targetArray el array de contenedores (movieclips)
  79.          */
  80.         function loadClips(urlArray:Array, targetArray:Array, type:String) {
  81.                        
  82.                         this.urlArray = urlArray;
  83.                         this.targetArray = targetArray;
  84.                         load();
  85.         }
  86.         /**
  87.         * efectua el loadMovie.
  88.         * se va a ejecutar 'n veces' tantas como numCargados.
  89.         */
  90.         private function load():Void {
  91.                 targetArray[numCargados].loadMovie(urlArray[numCargados]);
  92.                 // con el setInterval, nos aseguramos de que actualProgress sea> 0
  93.                 // guardamos la referencia actual en el atributo actualTarget
  94.                 actualTarget = targetArray[numCargados];
  95.                 interval = setInterval(Delegate.create(this, loadStart), 50);
  96.         }
  97.         /**
  98.         * permite saber si la carga está iniciada
  99.         * se usa porque la carga no devuelve 0 hasta que no se comienza a cargar
  100.         */
  101.         private function loadStart():Void {
  102.                 actualProgress = targetArray[numCargados].getBytesLoaded();
  103.                 // si ya ha empezado a cargar...
  104.                 if (actualProgress>=0) {
  105.                         // limpiamos esta funcion
  106.                         clearInterval(interval);
  107.                         onLoadActualStart();
  108.                         // con esto conseguimos que actualProgress siempre esté actualizado
  109.                         interval = setInterval(Delegate.create(this,onLoadProgress), 50);
  110.                 }
  111.         }
  112.         /**
  113.         * permite escuchar el porcentaje de la carga
  114.         * actualiza las propiedades tales como actualProgress, actualPercent.
  115.         */
  116.         private function onLoadProgress():Void {
  117.                 actualProgress = actualTarget.getBytesLoaded();
  118.                 actualTotal = actualTarget.getBytesTotal();
  119.                 actualPercent = Math.round((actualProgress*100)/actualTotal);
  120.                
  121.                 var eventObj:Object = { type:"onLoadProgress",
  122.                                         mc:MovieClip,
  123.                                         progress:Number,
  124.                                         total:Number,
  125.                                         percent:Number
  126.                                         };
  127.                 eventObj.mc = actualTarget;
  128.                 eventObj.progress = actualProgress;
  129.                 eventObj.total = actualTotal;
  130.                 eventObj.percent = actualPercent;
  131.                
  132.                 //despacho evento para los preloaders
  133.                 dispatchEvent(eventObj);
  134.                 if (actualPercent>=100) {
  135.                         clearInterval(interval);
  136.                         actualProgress = 0;
  137.                         numCargados++;
  138.                         onLoadActualComplete(actualTarget);
  139.                         if (numCargados<targetArray.length) {
  140.                                 load();
  141.                         } else {
  142.                                 //acabamos!
  143.                                 onLoadAllComplete();
  144.                         }
  145.                 }
  146.         }
  147.         /**
  148.         * función que se ejecutará cuando empiece la precarga de
  149.         * algún objeto
  150.         * @param ref
  151.         * una referencia del objeto que se ha cargado
  152.         */
  153.         public function onLoadActualStart():Void {
  154.                 var eventObj:Object = {type:"onLoadActualStart", mc:MovieClip};
  155.                 eventObj.mc = actualTarget;
  156.                 dispatchEvent(eventObj);
  157.         }
  158.         /**
  159.         *
  160.         * @usage función que se ejecutará cuando termine la precarga de
  161.         * algún objeto
  162.         * @param ref
  163.         * una referencia del objeto que se ha cargado
  164.         */
  165.         private function onLoadActualComplete(ref:Object):Void {
  166.                 var eventObj:Object = {type:"onLoadActualComplete", mc:Object};
  167.                 //despacho evento
  168.                 eventObj.mc = actualTarget;
  169.                 dispatchEvent(eventObj);           
  170.         }
  171.         /**
  172.         *
  173.         * @usage función que se ejecutará cuando termine la precarga de
  174.         * de el último objeto a cargar
  175.         */
  176.         private function onLoadAllComplete():Void {     
  177.                 var eventObj:Object = {type:"onLoadAllComplete"};
  178.                 //despacho evento
  179.                 dispatchEvent(eventObj);
  180.         }
  181.         /**
  182.         * @usage getter target array
  183.         * los contenidos
  184.         * @return un array de clips
  185.         */
  186.         public function getTargetArray():Array {
  187.                 return targetArray.slice();
  188.         }
  189. }
  190.  
  191.  

Si no conocéis todavía la peli de terror "pulse" que se estrenará a principios del año que viene, me agrada presentarlos la que para mí es una de las piezas interactivas del año en España, quieroverunfantasma. Bajo el sello de Cp-interactive, la web de pulse consigue la mejor experiencia de terror que he visto hasta el momento en internet desde los trailers de The ring y de el proyecto de la bruja de blair.
El mecanismo de difusión clásico de "recomienda a tu amigo" también es digno de resaltar. De la mano de Flash 8 y Flash Media Server, la pieza, permite grabar en vídeo por tu webcam y enviar tu mensaje de miedo a tus colegas. De ese modo, ellos verán aparecer tu vídeo intercalado en el spot. Parece que los juegos con webcams y Flash Media Server tienen mucho jugo para las agencias.

Ya tengo un poco de tiempo para mí y mis agobios de trabajo empiezan a bajar, supongo que se empezará a notar porque saco más tiempo en escribir. :D
Pues estaba yo haciéndome eco de la noticia con la que he comido, la de un pavo que usaba un virus para grabar por webcam... resulta que el programador era español... y madre mía la que le va a caer... pero bueno, eso no es el motivo del post. El caso es que estaba leyendo en news.com la historia, y... oh! sorpresa! me sale una aplicación de la gente de liveplasma, de los que ya hemos hablado anteriormente. Pues se han currado lo mismo, pero para las noticias de news.com. Un ejemplo de que las aplicaciones "Eye candy" a veces no son tanto. ¿Alguien con datos para saber si esas aplicaciones dan pasta? :D

Podéis verlo en la página de la noticia, aparece un banner a la derecha, en el que hay un grafo de noticias relacionadas.

Liveplasma.com+news.com

La antigua comunidad de desarrollo esmmug cambia de nombre y de dominio. Con un impresionante nuevo interface estilo workspace de Dreamweaver nos comentan el por qué del cambio, y nos prometen suculentas novedades.

Mi favorito. Marcos Weskamp, reinventa la manera de navegar en flickr mediante un grafo interactivo que muestra las relaciones entre los usuarios de flickr, además de permitir visualizar las fotografías de cada usuario. Simplemente introduce tu nombre de usuario de flickr y disfruta!

http://www.marumushi.com/apps/flickrgraph/

Next Page »