Contenido

Colección de editores enriquecidos del futuro

2 Feb

+ 2

SixRevisions publica una interesante recopilación de editores de texto enriquecidos que nos permiten reemplazar los tristes <textarea /> por completos editores que facilitan la visualización del resultado al usuario. Muy a tener en cuenta.

Código Konami en Javascript

1 Feb

+ 9

El Código Konami (Konami Code) es un truco que la gente de Konami integraba en muchos de sus juegos y que generalmente ofrecía acceso a una sección secreta.

↑ ↑ ↓ ↓ ← → ← → B A

Muchas son las aplicaciones web que integran este código, implementar este código en cualquier página web mediante Javascript es algo tan sencillo como esto:

<head>
 <script type="text/javascript">
   var $ = {
      enabled: false,
      tmp: Array(),
      _konamiCode: Array(65,66,39,37,39,37,40,40,38,38),
      init: function() {
        this.tmp = Array(65,66,39,37,39,37,40,40,38,38);
      },
      konamiCode: function(e) {
        if(!this.enabled) {
          var t = this.tmp.pop();
          if((e.keyCode-t) == 0) {
            if(this.tmp.length == 0) {
              this.enabled = true;
            }
          }
          else {
            this.init();
          }
        }
        else {
          this.action();
        }
      },
      // Cambiamos por nuestra funcionalidad.
      action: function() {
        alert("Konami Code Activated");
      }
    }
 </script>
</head>
<body onload="$.init()" onkeydown="$.konamiCode(event)">
</body>

Simplemente tendremos que añadir este código modificando el valor de action por el de la funcionalidad que deseemos ejecutar al completar el Konami Code.

Sigue la traza de tus script con printStackTrace()

1 Feb

+ 2

Hace unos meses Eric Wendelin publicó una implementación de printStackTrace(), un script que nos permite seguir una traza de ejecución de nuestros scripts ideal para detectar errores y detectar más fácilmente por donde ha pasado la ejecución de nuestro script.

Hace unos días, Eric actualizó el código integrando a Google Chrome entre los navegadores soportados por la función:

function foo() {
    var blah;
    bar("blah");
}

function bar(blah) {
    var stuff;
    thing();
}

function thing() {
    if (true) {
        var st = printStackTrace();
        alert(st.join("\n\n"));
    }
}

foo();

El resultado nos muestra por donde ha pasado la ejecución:

printStackTrace()@http://eriwen.com/js/common.4.js:53
thing()@http://eriwen.com/js/common.4.js:249
bar("blah")@http://eriwen.com/js/common.4.js:244
foo()@http://eriwen.com/js/common.4.js:239
@javascript:foo();:1

Si nos interesa, podemos ver el código del proyecto directamente desde GitHub.

Interprete de LOGO desarrollado en Javascript

27 Ene

+ 1

Los que nos iniciamos pronto en la informática recordamos LOGO. Aquel lenguaje de programación que nos enseñaron cuando estudiábamos y que mediante comandos muy claros podíamos mover por la pantalla un puntero (que llamabamos Tortuga) haciendo dibujos en la pantalla. En clase, lo usábamos para mover un coche teledirigido adaptado para recibir órdenes desde una interfaz con LOGO.

logo_javascript
(Ver Imagen)

Gracias a <canvas />, ha sido posible generar un interprete desarrollado en Javascript que nos permite disfrutar de este interesante lenguaje 😀

Ext Core disponible desde Google Ajax Libraries

18 Ene

+ 3

Hace ya un tiempo que Google ofrecío su infrastructura para alojar los frameworks Javascript más conocidos y hasta el momento, jQuery, jQuery UI, MooTools, Prototype, Script.aculo.us, Dojo,… tenían este privilegio permitiendo que estemos actualizados sin tener que cambiar nada y sin tener que preocuparnos de alojar el fichero JS en nuestro servidor.

Ahora Ext Core, tambien está disponible mediante este método, permitiéndonos usarlo de dos formas diferentes:

HTML

El formato HTML es el que nos permite usarlo mediante una llamada usando el tag <script /> a una URL que Google nos ofrece

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/ext-core/3.0.0/ext-core.js"></script>

Javascript

Mediante Javascript, nos permite controlar cuando esté cargado y ejecutar código Ext Core cuando esté listo para usarlo.

<script src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
 // Cargamos el core
 google.load("ext-core", "3.0.0");

 // Cuando esté cargado
 google.setOnLoadCallback(function() {
 ....
 });
</script>

Ambas técnicas funcionan igual de bien, aunque dependemos de la disponibilidad de Google.

Actualización (18:29)

Corrigo el nombre Ext.js por el de Ext Core, ya que son productos diferentes con diferentes licencias. Steffen nos lo explica más detalladamente en su comentario.Gracias Steffen.

Pycript, el javascript con sabor a Python

15 Ene

+ 8

Si conoces Python habrás notado que la generación de código limpio es una norma muy inculcada en la filosofía del lenguaje. Esto ayuda sustancialmente a la creación de un código que prácticamente todo aquel que haya desarrollado alguna en Python podrá entender (aunque tambien se pueden hacer desastres :D).

Por el contrario, Javascript, es archiconocido por la filosofía de minimizar, hacer todo en el menor número de líneas posibles, esto tiene sentido ya que el lenguaje ha de viajar hasta el cliente y allí ejecutarse. De esta forma, todo lo que podamos bajar, son bytes de menos que enviar.

Aza Raskin se ha propuesto unir estas dos filosofías e implementar Pyscript, una implementación en Javascript que nos permite desarrollar en Javascript usando la sintaxis de Python [Ver Demo]

// Pyscript
function triangle(a,b):
  if a > 0 && b > 0:
    function sqroot(x):
      if x > 0:
        return Math.pow(x,.5)
      else:
        return 0
    return sqroot( a*a + b*b )
  else:
    return 0
// Javascript
function triangle(a,b){
  if(a > 0 && b > 0 ){
    function sqroot(x){
      if( x > 0 ){
        return Math.pow(x,.5);
      }
      else {
        return 0;
      }
    }
    return sqroot( a*a + b*b );
  }
  else {
    return 0;
  }
}


¿Como usarlo?

Se trata de un fichero .js que podemos descargar directamente desde aquí y que nos permitirá incluir código Pyscript en unos tags personalizados para dicho código.

<script src="pyscript.min.js"></script>

Una vez añadido este código, ya podremos generar nuestros bloques de código.

<script id="input" type="text/pyscript">
  var el = document.getElementById("string")
  for var i=0; i<5; i++: el.innerHTML += "hello! "

  var count = 0
  for var i=0; i<5; i++:
    count += 1
    if count==2:
      count *= 5

  document.getElementById("count").innerHTML = count;    

  function triangle(a,b):
    function sqroot(x): return Math.pow(x,.5)
    return sqroot( a*a + b*b )

  document.getElementById("triangle").innerHTML = triangle(3,4);
</script>

Como experimento es muy interesante, pero por el momento no debería tomarse más enserio debido a que la filosofía de Javascript (que hemos visto antes) es así por algo, las conexiones más lentas lo agradecerán 😀

jQuery 1.4 por fin vió la luz

15 Ene

+ 23

Hace ya tiempo que jQuery anunció la versión 1.4, primero fue en versión Alpha y posteriormente en Release Candidate, hoy oficialmente ha visto la luz la versión final, y para ello se ha creado un nuevo dominio http://www.jquery14.com destinado a mostrarnos lo que la que la nueva versión nos ofrece.

Rendimiento

4271691293_8e11e4666d_o
(Ver Imagen)

Como todas las versiones de jQuery, el rendimiento es algo que tiende a disminuirse. En esta versión, hay que destacar que las funcionalidades más comunes han mejorado sustancialmente sus tiempos de respuesta en comparación la versión 1.3.2.

4271691747_a8733f1b1f_o
(Ver Imagen)

Sobretodo las funciones que atacan al DOM han recibido una impresionante optimización. Y por fin, la generación de HTML mediante el método html() mejora hasta un 300% el tiempo de respuesta.

4271691147_ae533c2cd5_o
(Ver Imagen)

Al igual que los métodos attr() y css() (mejora un 200%) que mejoran sustancialmente frente a la versión anterior del framework.

Setters mejorados

Los setters son aquellos métodos que nos permiten modificar los atributos, estilos o valores de los elementos jQuery. En esta nueva versión se han replanteado para facilitar su funcionamiento. Para ello nos permiten pasar funciones como parámetros que contendrán el valor actual del elemento, ideal para realizar modificaciones sobre el valor actual.

// Buscamos todos los &amp; y los añadimos a un span
$('a').html(function(i,html){
 return html.replace(/&amp;/gi,'<span>&amp;</span>');
});

// Añadimos información al title de los enlaces externos
$('a[target]').attr("title", function(i,title){
 return title + " (Opens in External Window)";
});

Creación sencilla de elementos

Crear elementos mediante jQuery será tan sencillo como esto:

jQuery("<div/>", {
 id: "foo",
 css: {
 height: "50px",
 width: "50px",
 color: "blue",
 backgroundColor: "#ccc"
 },
 click: function() {
 $(this).css("backgroundColor", "red");
 }
}).appendTo("body");

Ideal para generar elemento que no necesariamente deben añadirse al DOM nada más ser creados.

eq(-N) y get(-N)

Imagina que quieres obtener los dos últimos elementos de una lista, con esta nueva funcionalidad será más sencillo todavía conseguirlo.

$("#listado").get(-2);

Eventos

Los eventos también han sido optimizados y replanteados, además de que todos los eventos para ser live() (excepto ready(), focus() y blur()) aunque usemos bind(), nos permitirá encadenar varios en la misma llamada.

$("div.test").bind({
 click: function(){
 $(this).addClass("active");
 },
 mouseenter: function(){
 $(this).addClass("inside");
 },
 mouseleave: function(){
 $(this).removeClass("inside");
 }
});

jQuery.proxy()

Esta función nos permitirá solventar el problema del contexto entre funciones, con ella será sencillo reutilizar código:

var app = {
 config: {
 clickMessage: 'Hi!'
 },
 clickHandler: function() {
 alert(this.config.clickMessage);
 }
};

// jQuery 1.3.2
jQuery('a').bind('click', app.clickHandler);  // Esto produce un error al llamar a this dentro de jQuery

// jQuery 1.4
jQuery('a').bind(
 'click',
 jQuery.proxy(app, 'clickHandler')
);

delay()

Se trata de una implementación más limpia de setTimeout() que nos permitirá pausar nuestros scripts.

$("div").fadeIn().delay(4000).fadeOut();

Descargar

SVG-edit, un completo paint en tu navegador

14 Ene

+ 4

svg-edit, es un editor de gráficos desarrollado sobre nuestro navegador mediante Javascript que se encarga de usar SVG. El editor, que funciona en todos los navegadores modernos nos permite obtener un interfaz muy agradable y completo sobre cualquier navegador (incluido IE6+ con el plugin de Google Chrome).

svg-edit
(Ver Imagen)

Como podemos ver, las opciones disponibles no son pocas (la imagen es así de fea por que no sabía que hacer ante un lienzo en blanco :D, hay gente que se ha currado cosas más chulas), desde dibujar a mano alzada hasta la inclusión de imágenes externas, pasando por la herramienta de texto, la degeneración de polígonos o la inclusión de capas.

Disponemos de 3 formatos de los que descargar y lo podemos probar online directamente en esta demo:

  1. Plugin para Firefox
  2. Widget Opera
  3. Código fuente

Los desarrolladores, además disponemos de una API con la que podemos ir haciendo algunos añadidos más al proyecto.

Añade subtítulos a tus videos con Javascript

14 Ene

+ 7

El tag <video /> del nuevo estándar HTML5 cada día nos sorprende más y es que aunque se detectaron problemas a la hora de interpretar el estandar en los diferentes navegadores, cada nueva noticia sobre él aporta una idea interesante.

Bruce Lawson, gurú de HTML5, nos ofrece una interesante implementación que nos ofrece subtítulos a nuestros videos mediante Javascript.

HTML

La principal ventaja que nos ofrece esta técnica es que nos permite tener elementos HTML con el texto del video en nuestra página, que aunque nos hará páginas más largas y pesadas, nos permite ofrecer a usuarios sin capacidad de reproducir videos una solución alternativa (aunque no completa) de saber de que vá el video.

<video width=600 src="leverage-a-synergy.ogv" ontimeupdate="timeupdate()"
 style="background:black" autobuffer controls>
 <p>This page is to demonstrate open HTML5 video, so if you're not using a
 browser that can display the open Ogg Theora codec, there's not  much to see. Sorry!</p>
 </video>
 <div id="transcript">
 <h3>Transcript</h3>
 <p>
 <span data-begin=1 data-end=6>Hi, my name's Dr Archimedes Einstein and I'm a Doctor of Science at the University of Science</span>
 <span data-begin=6 data-end=9>in a very famous town that you're too stupid to have heard of.</span>
 <span data-begin=9.5 data-end=11.5>Anyway, today we're going to talk about "synergies".</span>
 <span data-begin=12 data-end=15>A lot of people are worried about synergies, but I can tell you that</span>
 <!-- ... -->
 </p>
 </div>

Como podemos ver, se trata de una estructura bastante lógica, un video y una serie de líneas con el texto que compone la transcripción de dicho video. Hay que destacar la función timeupdate() que se ejecutará en el evento ontimeupdate del elemento <video /> (que vemos en negrita), ya que es la encargada de hacer mágia y convertir ese texto en los subtítulos del video.

Por otro lado, en el texto podemos ver que los <span /> ofrecen información sobre cuando deben empezar y terminar cada línea, vinculando los data-begin y data-end al tiempo de reproducción del video medianante los atributos data disponibles en el estandar.

Javascript

Ahora necesitamos que el texto y el video se entrelazen y ofrezcan el resultado que estamos buscando, para ello primero hemos de cargarlo y posteriormente ir actualizando el texto a medida que el video va reproduciendose.

var captions = [];
window.onload = function() {
  var caption = document.createElement('div');
  caption.id = 'caption';
  // Cargamos el primer elemento
  var ref = document.getElementsByTagName('video')[0];
  ref.parentNode.insertBefore(caption, ref.nextSibling);

  // Cargamos todos los subtítulos
  var nodes = document.querySelectorAll('#transcript span');
  for (var i = 0; i < nodes.length; i++) {
    // Generamos un objeto con la información de cada línea
    var c = {'start': parseFloat(nodes[i].getAttribute('data-begin')),
             'end': parseFloat(nodes[i].getAttribute('data-end')),
             'text': nodes[i].textContent};
    captions.push(c);
  }
}
// Función que actualizar el texto dependiendo del tiempo
function timeupdate() {
  var v = document.querySelector('video');
  var now = v.currentTime;
  var text = "";
  for (var i = 0; i < captions.length; i++) {
    if (now >= captions[i].start && now <= captions[i].end)
    {
      text = captions[i].text;
      break;
    }
  }
  document.getElementById('caption').innerHTML = text;
}
// Ocultamos los subtítulos
document.write('<style>#transcript{display:none}</style>');

Al terminar de cargar la página, recogemos los textos y los almacenamos en una variable global en un formato más cómodo para trabajar con él. En la función timeupdate(), que recordemos usamos en el evento ontimeupdate del tag <video /> nos irá comprobando los cambios y actualizando el mensaje visible a medida que va transcurriendo el tiempo de reproducción.

Para terminar, ocultamos el texto mediante Javascript ya que en caso de no estar disponible, además de no aplicar ninguna de las funcionalidades anteriores nos permitirá visualizar el texto perfectamente.

CSS

Los estilos nos permiten ubicar los subtítulos en el video, y además podremos especificar el tamaño, color y fuente de ellos.

#caption {
 position: absolute;
 width: 100%;
 bottom: 0;
 bottom:30px; /* space for the video controls */
 left: 0;
 text-align: center;
 font-family: sans-serif;
 font-weight: bold;
 color: white;
 text-shadow: black 1px 1px 3px;
 padding-bottom: .5em;
}
#transcript span {display:table-row;}

Básicamente, lo que estamos haciendo es ubicar el texto al pie del video, dejando espacio para los controles.

Bruce, además incluye unos estilos que nos inserta información extra para ciertos usuarios al mostrar mediante CSS información del tiempo de inicio y fin de los textos leyendo directamente de los atributos.

#transcript [data-begin]:before{
  content: " [" attr(data-begin) "s-" attr(data-end)"s]   ";
  font-size:80%;
  display:table-cell;
  padding-right:1em;
}

Resultado

video-span
(Ver Imagen)

El resultado es realmente sorprendente ya que no tiene nada que envidiarle (a este nivel) a los reproductores de escritorio.

Actualización (17:00)

Nukeador me muestra otro sistema, también basado en Javascript que además de permitir conseguir el mismo efecto nos permitirá usar los ficheros .srt que tenemos disponibles por Internet.

video-srt
(Ver Imagen)

Un sistema basado en la lectura mediante Ajax de ficheros .srt (SubRip) y de un posterior parseo para obtener el tiempo y el texto que mostraremos como subtítulo.

Fichero srt

Si alguna vez has necesitado ver una película con subtítulos, te habrás encontrado con que has tenido que descargar un fichero .srt para poder verla. Eso es por que existen una gran cantidad de herramientas que permiten la edición de subtítulos fácilmente con la obtención de este tipo de ficheros. Además, es soportado por la mayoría de todos los reproductores multimédia.

...
5
00:00:07,100 --> 00:00:09,000
Tiene subtitulos son en Español

6
00:00:09,100 --> 00:00:10,500
Gracias a las nuevas technologias

7
00:00:10,500 --> 00:00:20,000
<img src="foo.png"/><img src="foo.png"/><img src="foo.png"/> Gracias! <img src="foo.png"/><img src="foo.png"/><img src="foo.png"/>
....

El formato de un fichero .srt nos permite generar estructuras como las que vemos. Como podemos ver, se trata de un sistema muy cómodo y a mi entender más correcto que el presentado por Bruce.

jai, jugando con audio desde Javascript

13 Ene

+ 1

La llegada de HTML5 nos mostró el elemento <audio /> que nos permite hacer que el navegador se convierta en un reproductor de audio con Javascript como controlador. Aprovechando esta nueva característica del lenguaje aparece jai que nos permite generar listados gráficos de las canciones encontradas en nuestra página.

<!-- HTML -->
<div id="jai">
  <canvas id="jai-transport" width="320" height="20"></canvas>
  <ul>
   <li><a href="@F1LT3R - Cryogenic Unrest.ogg" title="Play">F1LT3R - Cryogenic Unrest<span title="Download"></span></a><audio src="@F1LT3R - Cryogenic Unrest.ogg">Your browser does not support the <code>audio</code> element. Get <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.5</a>.</audio></li>
   <li><a href="@F1LT3R - Ghosts in HyperSpace.ogg">F1LT3R - Ghosts in HyperSpace</a><audio src="@F1LT3R - Ghosts in HyperSpace.ogg">Your browser does not support the <code>audio</code> element. Get <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.5</a></audio></li>
   <li><a href="@F1LT3R - SOS Distress.ogg">F1LT3R - SOS Distress</a><audio src="@F1LT3R - SOS Distress.ogg">Your browser does not support the <code>audio</code> element. Get <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.5</a></audio></li>
   <li><a href="@F1LT3R - Disturbed Orbit.ogg">F1LT3R - Disturbed Orbit</a><audio src="@F1LT3R - Disturbed Orbit.ogg">Your browser does not support the <code>audio</code> element. Get <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.5</a></audio></li>
   <li><a href="@F1LT3R - Binary Lovers.ogg">F1LT3R - Binary Lovers</a><audio src="@F1LT3R - Binary Lovers.ogg">Your browser does not support the <code>audio</code> element. Get <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.5</a></audio></li>
  </ul>
</div>

El script es muy limitado en cuanto a configuración se refiere, ya que nos obliga a usar una estructura similar a la mostrada arriba, pero se encarga de renderizar mediante un elemento <canvas /> el listado de elementos <audio /> detectados en la página permitiendo disponer de un reproductor avazando en nuestra aplicación.