Posts Tagged ‘html’

Hagalo usted mismo: Efecto marquesina con Javascript

May 30th, 2009

Recientemente m313n45 me pidio ayuda para hacer un efecto de marquesina con unas imágenes y al dar click sobre alguna de ellas se viera la versión completa, todo esto sin usar flash.

Lo realice obviamente con Javascript + JQuery y a continuacion veremos paso a paso como lograrlo.

Tambien pueden ver el ejemplo completo aquí

Las imágenes para las marquesina son 6, iniciamos con el markup de las imágenes.

1
2
3
4
5
6
7
8
9
10
<div id="container">
	<img src="01.png" alt="1"/>
	<img src="02.png" alt="2"/>
	<img src="03.png" alt="3"/>
	<img src="04.png" alt="4"/>
	<img src="05.png" alt="5"/>
	<img src="06.png" alt="6"/>
</div>
<div id="viewport">
</div>

Además ocupamos darle estilo:

1
2
3
4
5
6
7
8
9
10
11
12
13
#container
{
	overflow: hidden;
	width: 400px;
	height: 64px;
	border-style: solid;
}
#container img
{
	position: relative;
	width: 60px;
	height: 64px;	
}

overflow: hidden; hace que las imágenes que no quepan en el contenedor esten ocultas en ves de causar scrolling o un efecto similar, además hacemos las imágenes mas pequeñas y asignamos su posicion como relativa, lo cual sera útil a realizar la animación.

Hasta el momento esto se ve así:

123456

Notece que una de las imágenes se encuentra oculta de momento, debido a que no se alcanza a mostrar en el contenedor.

Después iniciamos con la animacion, requerimos a JQuery para facilitarnos las cosas, tendrán que agregar la referencia a la libreria en su header además de agregar el código de animación:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var deltaX = 5;
var deltaT = 42;	
 
$(document).ready (function ()
{
	setTimeout("animate()", deltaT); //start animation
});
 
function animate ()
{
	var left = parseInt ($("#container img").css("left"));
	left -= deltaX;
 
	$("#container img").css("left", left + "px");
 
	setTimeout ("animate()", deltaT); //continue animation
}

Donde deltaT define cada cuantos milisegundos ocurrira la animacion y deltaX indica el desplazamiento cada intervalo de deltaT milisegundos. La animación la realizamos modificando la propiedad left del css. Ahora esto se ve así:

123456

Pero para el momento en que ustedes lleguen a leerlo todas las imágenes habrán desaparecido hacia la izquierda, así que recarguen la pagina por favor y bajen rápidamente hasta este punto para ver la animación.

Eso ocurre por que ocupamos hacer que la marquesina sea giratoria, para lograr el efecto debemos de quitar la primer imagen cuando esta ya no sea visible y ponerla después de la ultima imagen. La primer imagen no es visible cuando su atributo css left tenga un valor de -LongitudImagen, en este caso, -60px.

Como quitaremos la imagen, ocupamos volver a ajustar el desplazamiento a la izquierda aumentando el atributo css left con la longitud de la imagen que quitamos, es decir 60px. El script queda entonces:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var deltaX = 5;
var deltaT = 42;	
var imageWidth = 60;
 
$(document).ready (function ()
{
	setTimeout("animate()", deltaT); //start animation
});
 
function animate ()
{
	var left = parseInt ($("#container img").css("left"));
	left -= deltaX;
 
	if (left <= -imageWidth) //if first image is no longer visible
	{
		left += imageWidth;
		$("#container img:first")
                	.remove ()
                	.insertAfter("#container img:last");
	}
 
	$("#container img").css("left", left + "px");
 
	setTimeout ("animate()", deltaT); //continue animation
}

Y ya podemos ver la animación circular:

123456

Por ultimo requerimos que al dar click en una imagen la mostremos en su tamaño original, para dar el efecto de vinculo debemos de cambiar el css de las imágenes para que aparezca la “manita” cuando pongamos el puntero sobre la imagen, el css queda entonces:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#container
{
	overflow: hidden;
	width: 400px;
	height: 64px;
	border-style: solid;
}
#container img
{
	position: relative;
	width: 60px;
	height: 64px;	
	cursor: pointer;
}

Solo nos falta el script, pero debemos de tener cuidado, por que cuando quitamos la imagen para ponerla al final de la lista perdemos la asociación del evento y tenemos que volverla agregar,por lo que el script final queda:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var deltaX = 5;
var deltaT = 42;	
var imageWidth = 60;
 
$(document).ready (function ()
{
	$("#container img").click (changeViewportImage);
	setTimeout("animate()", deltaT); //start animation
});
 
function changeViewportImage ()
{
	$("#viewport img").remove ();
	$("#viewport").append ($(this).clone ());
}
 
function animate ()
{
	var left = parseInt ($("#container img").css("left"));
	left -= deltaX;
 
	if (left <= -imageWidth) //if first image is no longer visible
	{
		left += imageWidth;
		$("#container img:first")
		    .remove ()
		    .insertAfter("#container img:last")
		    .click (changeViewportImage);
	}
 
	$("#container img").css("left", left + "px");
 
	setTimeout ("animate()", deltaT); //continue animation
}

Y queda finalmente así (recuerden dar click sobre alguna imagen):

123456

Tambien pueden ver el ejemplo completo aquí

Parsing de HTML con HtmlAgilityPack

February 5th, 2009

La web esta llena de información, todo tipo de información, desde el vídeo divertido mas irrelevante hasta noticias o documentos de verdadera importancia. Hay un mundo de información a la cual tu computadora esta unida por el cordón umbilical de tu cable de red, dispuesta a ser accesada y mostrada en tu pantalla a la mas mínima orden tuya.

Pero tiene un problema.

Toda esta valiosa información se encuentra ofuscada en HTML, un lenguaje el cual a sido seriamente abusado durante el transcurso de los años, debido a que su especificación indica que los navegadores deben hacer lo mejor posible para corregir errores en el formateo de un documento, por lo que los usuarios terminaron en volverse descuidados, olvidando una etiqueta de cierre aquí y halla, al fin y al cabos el resultado es el mismo, ¿no?, los navegadores hacen todo lo posible por mostrar incluso los documentos mas mal formados.

Eso hace que hacer un programa para extraer información de un documento HTML pueda llegar a ser un poco complicado en ocasiones.

HtmlAgilityPack to the rescue!

HtmlAgilityPack es una librería para .NET que nos brinda un parser de HTML que nos permite leer, escribir y manipular documentos HTML y soporta Xpath, el cual discutí hace tiempo. Y lo que lo hace realmente especial es que es increíblemente permisivo, soportando los documentos mas perversamente malformados que te puedes encontrar en tu navegación día a día.

HtmlAgilityPack combinado con Firebug nos permite extraer hasta la ultima gota de información requerida, y para no hacérselas larga pondré un par de ejemplos en el resto del post.

Quiero obtener la lista de títulos del blog del AlbertEin

1
2
3
4
5
6
7
8
9
10
11
static void Main(string[] args)
{
    var client = new System.Net.WebClient();
    client.Encoding = System.Text.Encoding.UTF8;
    var document = new HtmlAgilityPack.HtmlDocument();
    document.LoadHtml(client.DownloadString("http://albertein.gamersla.net"));
 
    foreach (HtmlAgilityPack.HtmlNode node in 
        document.DocumentNode.SelectNodes("//a[@class='title']"))
            Console.WriteLine(node.InnerHtml);
}

Quiero obtener la lista de palabras listada en una web de un diccionario

1
2
3
4
5
6
7
8
9
10
11
12
static void Main(string[] args)
{
    var url = "http://diccionario.babylon.com/Humanidades/Mitolog%C3%ADa/A/1/";
    var client = new System.Net.WebClient();
    client.Encoding = System.Text.Encoding.UTF8;
    var document = new HtmlAgilityPack.HtmlDocument();
    document.LoadHtml(client.DownloadString(url));
 
    foreach (HtmlAgilityPack.HtmlNode node in
        document.DocumentNode.SelectNodes("//a[@class='words']"))
            Console.WriteLine(node.InnerHtml);
}

Quiero bajar todos los malditos comics de Penny Arcade

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
static void Main(string[] args)
{
    var url = "http://www.penny-arcade.com/comic/1998/11/18/";
    var baseUrl = "http://www.penny-arcade.com";
    bool lastStrip = false;
    var client = new System.Net.WebClient();
    client.Encoding = System.Text.Encoding.UTF8;
 
    while (!lastStrip)
    {
        var document = new HtmlAgilityPack.HtmlDocument();
        document.LoadHtml(client.DownloadString(url));
 
        var imageQuery = "/html/body/div[2]/div[3]/div/div[2]/img";
        var nextButtonQuery = "/html/body/div[2]/div[3]/div/div[3]/a[4]";
 
        var imageUrl = document.DocumentNode.
            SelectSingleNode(imageQuery).Attributes["src"].Value;
 
        //Aquí iria el codigo para descargar la imagen que se encuentra en
        //baseUrl + imageUrl
 
        //Obtenemos la dirección del próximo comic
 
        url = baseUrl + document.DocumentNode.
            SelectSingleNode (nextButtonQuery).Attributes ["href"].Value; 
 
        lastStrip = url == baseUrl; // Llegamos al ultimo comic?
    }
}

Podría seguir así todo el día, pero supongo que con eso es suficiente para que capten la idea.

¿Y tu, como lo has usado?