JMiur [E]

Una "rareza" del CSS es que tiene la posibilidad de manejar las imágenes como capas (layers) lo que permite que se "deslicen" unas sobre otras, creando efectos.

Algo de esto aparece en el artículo Sliding Doors de A List apart aplicado (y muy mal explicado) a la creación de un menú con pestañas.

La técnica no es una novedad, se viene usando para crear juegos desde tiempo inmemorial pero, su aplicación a las páginas web abre nuevas posibilidades.


Vayamos despacio, lo primero que debería quedar claro son las propiedades CSS que permiten controlar el fondo de un elemento:
background: color URL_imagen repetir attachment posición
es la forma rápida de establecer todas las propiedades simultáneamente. De todas ellas, la que nos va a interesar es la posición.

La propiedad background-position define la posición del fondo de un elemento. En CSS, la propiedad se establece con:
background-position: laPosicion
y en JavaScript:
objeto.style.backgroundPosition = laPosicion
donde laPosicion es una cadena de texto que contiene uno o dos valores que puede ser:

una longitud: un valor expresado en cm, mm, in, pt, pc, px, em o ex
un porcentaje: un valor entero, seguido por el signo % (porcentaje del ancho o la altura del elemento)
el alineamiento vertical: top, center, bottom
el alineamiento horizontal: left, center, right

El valor por defecto es 0% 0% (left top). Si sólo se establece un valor, se aplica a ambos alineamientos. El primer valor especifica la coordenada horizontal y el segundo, la vertical.

Imaginemos esto, dos imágenes cualquiera, una al lado de la otra y formando parte del mismo archivo:

 

Ahora, supongamos que tenemos un DIV al que le asignamos una propiedad background para que se vea un fondo y le damos un tamaño, exactamente igual a la mitad de la imagen:

background: transparent url(URL_imagen) no-repeat left top;

 

Como el elemento contenedor (DIV), es más angosto que la imagen de fondo, sólo se verá la mitad izquierda ¿Y si cambiáramos un poco la propiedad, podría verse la otra mitad?:

background: transparent url(URL_imagen) no-repeat right top;

 

Quiere decir que modificando la posición, con sólo un archivo, podemos mostrar dos imágenes:

  

¿Que ventaja tiene esta técnica? que la imagen sólo se carga una vez, por lo tanto, la hace ideal para utilizarla como efecto rollover:

 


El código es sencillo, definimos el DIV dándole el tamaño adecuado y la imagen de fondo correspondiente. Luego, mediante los eventos onmouseover y onmouseout, cambiamos la posición del fondo de manera dinámica:
<div style="width: 200px; height: 150px;
background: transparent url(URL_imagen) no-repeat left top;"
onmouseover="this.style.backgroundPosition='right top';"
onmouseout="this.style.backgroundPosition='left top';">
&#160;
</div>
Nada impide que haya más imágenes, por ejemplo, aquí hay tres. En este ejemplo, utilizamos el evento onclick:

 


El código base es el siguiente:
<div id="demo" style="width: 150px; height: 150px;
background: transparent url(URL_imagen) no-repeat left top;">
&#160;
</div>

<a href="javascript:void(0);"
onclick="getElementById('demo').style.backgroundPosition='left top';">
Rojo</a>
<a href="javascript:void(0);"
onclick="getElementById('demo').style.backgroundPosition='center top';">
Amarillo</a>
<a href="javascript:void(0);"
onclick="getElementById('demo').style.backgroundPosition='right top';">
Azul</a>
Y aquí hay cuatro, que es el máximo que podemos controlar utilizando sólo los valores de alineación: left right top bottom center:

 


Pero, si en lugar de utilizar las palabras claves de alineación, utilizamos longitudes, las posibilidades se tornan infinitas:

 



En este ejemplo tenemos una imagen modulada, los íconos de 32x32 se colocan, horizontalmente, uno a continuación del otro. De esta manera, una aritmética simple nos dice que, cada uno de ellos está a una distancia específica del borde izquierdo de la imagen: 0, 32, 64, 96, 128, 160, 192, 224, 256, 288 y 320 pixeles.




Así que, para hacer referencia a la imagen ubicada en el lugar, el evento onclick será algo así:

onclick="getElementById('demo').style.backgroundPosition='-192px 0px';

donde el valor es negativo porque la imagen se desliza hacia la izquierda:


Una posibilidad más avanzada sería crear una animación, desplazando la imagen pixel por pixel:

 


Ver/Ocultar Código Ejemplo [+]
<div id="demoani"
style="background: #FFFFFF url(URL_imagen) no-repeat left top;
width: 32px; height: 32px;">
 
</div>

<a href="javascript:void(0);" onclick="doLOOP()">INICIAR</a>
<a href="javascript:void(0);" onclick="stopLOOP()">DETENER</a>

<script>
var xPos = 0;
var tiempoIntervalo = "";

function doLOOP() {
tiempoIntervalo = window.setInterval("moverSE()",10);
}

function stopLOOP() {
window.clearInterval(tiempoIntervalo);
tiempoIntervalo = "";
}

function moverSE() {
xPos = xPos-1;
if(xPos==-320) {xPos=0;}
document.getElementById('demoani').style.backgroundPosition=xPos + "px 0px";
}
</script>

33 comentarios:

Nico  

Vi el Zelda y entré, a pesar de que no jugué mucho a ese :D

Interesante, es como sprites en CSS. Y no tan difícil. Tendré que verlo más.

Responder
JMiur  

Tenés razón, recién me doy cuenta que es una versión Zelda. La imagen esa era sólo decorativa, sorry, no quise hacer trampa.

Es exactamente eso, algo que vengo viendo que se está usando mucho en los botones rollover de muchas páginas. Claro, evita la demora de la carga de la imagen OVER que a veces hace que el efecto se pierda.

Este tipo de mapeo tiene muchas posibilidades, una de ellas será la segunda parte pero, debe haber mucho :D

Responder
Nico  

Sería bueno ver un ejemplo de algún juego simple. Buscaré a ver si encuentro algo. El efecto colisión sería jugando con las coordenadas (que geek... )

Responder
JMiur  

Imagínate jugando Tremulous en CSS !!!
¿intentarán echarte con un display:none? :D

Responder
Nico  

jajajaja, si es asi usaria el IE para no ser baneado! xD

Responder
Gem@  

Si no lo he entendido mal para hacer lo que explicas es necesario que todas las imágenes a mostrar sean una sola imagen ya que la url a añadir es única.
Normalmente yo uso un programa de imágenes no tendría problema, pero no todo el mundo suele usarlo ¿hay alguna otra forma de crear una imagen con varias?

Responder
JMiur  

Si la pregunta es si hay algún método que permita "sumar" imágenes sin un editor, la respuesta es no.

Cualquier editor, por muy sencillo que sea, permite crear una imagen nueva y pegar sectores (confieso que jamás he usado Paint pero incluso ese debe tener esa función).

Responder
Gem@  

Gracias J.Miur
Ya he probado con uno de los ejemplos y pinta bien ;)

Responder
Dios  

woaaaaaaa!!!!! cuanta data. que buen blog amigo. y yo que largue el .net para ver mas PHP y Java (me lo debo desde hace tiempo) ya te tengo en mis Marcadores...

Responder
JMiur  

¡Qué visita increible! espero que te diviertas :)

Responder
k_nelita  

Hola JMiur, otra vez yo buscando ayuda, ya me quedé bizca leyendo todo sobre las imagenes pero parece que no encuentro lo que busco, pero seguro que lo sabés, como lo sabés todo...
Mirá tengo una imagen, que es gif, necesité achicarla, no se manejar mas que el Paint y hasta por ahí nomás, el que saben hasta los chicos.
Al meterla en Paint para achicarla tengo que cambiarla a jpg sino la pixela y se deforma, bueno hasta ahí vamos bien, pero después que le pongo la medida que necesito me queda con fondo blanco, cuando la imagen original lo tenía transparente o no tenía fondo ninguno.
La imagen no es simétrica, sino la podría recortar y listo, pero no, no puedo, tiene una forma un tanto difícil de explicar.
Necesito algún código para que se funda el fondo con el color de la sidebar, no se si me explico, debe haberlo no?
Si no me entendés y tenés ganas pasate por mi blog y vas a ver las imagenes, porque son dos, que tienen un cuadrado blanco de fondo.
Ayudame porfi, ya no se a quien mas pedirle ayuda, nadie sabe... snif, snif
Y vos sos un GENIO!!!
Un saludo :)

Responder
JMiur  

k_nelita:

Las únicas imágenes transparentes que podés usar en una página web son en formato GIF, también sería posible en formato PNG pero Internet Explorer no las muestra transparentes, así que queda sólo el GIF como seguro.

Para eso, hay que indicarle al software de edición de imágenes que lo haga. Es largo de explicar pero, en general, uno indica que cierto color (blanco, por ejemplo) es transparente y ese, es un dato que guarda el archivo.

En resumen, si es un JPG, jamás será transparente.

El proceso lógico no es convertilas a JPG ya que este formato modifica los colores. Fijate: esta la he tomado de tu blog, y, como es un GIF, lo he hecho transparente, la otra, es JPG y al convertirla queda mal porque el blanco no es uniforme.

No recuerdo si Paint tiene estas opciones.

Resumo:

Podés tratar de buscar un software adecuado para editar imágenes, por ejemplo Paint.Net.

Podés intentar utilizar un editor online como Fauxto

Podés enviarme las dos imágenes por correo, decirme en que tamaño las querés redimensionar y las convierto, es algo muy sencillo pero se necesita tener el programa que lo haga.

Responder
k_nelita  

Gracias JMiur, una de las imagenes era esa, la que pusiste, y esas son las medidas, ahora te mando al correo la otra que es la redonda, pero en su tamaño original que es gif.
Lo del Paint.net no pude bajarmelo, no entiendo nada de ingles, y tendría que bajarlo en zip que es lo único que se abrir.
Y el Fauxto no funciona, o no se como es.
Yo te mando al correo la imagen, pero no es que quiera que hagas todo el trabajo solo explicame como bajar el Paint.net en zip, soy totalmente nula con el ingles, burra...

Un saludo y mil gracias!

Responder
k_nelita  

Hay no :(, JMiur, acabo de poner la imagen en el blog y, si podés mirala, se ven las letras rojas como el fondo y no se puede leer nada, queda fea, yo ya había obtenido el mismo resultado cuando la achiqué en gif.
Ya te mandé el mail, fijate si se te ocurre alguna otra cosa, con la imagen que te mandé creo que eso no pasa, pero la primera es diferente, no se porque... Si te fijas el original está en uno de los post que está en la primera pagina del blog.
Gracias igual.

Responder
JMiur  

Te había enviado un mail con la imagen pero, viendo este comentario, ya te he enviado un segundo mail con ambas imágenes corregidas.

Responder
k_nelita  

Gracias JMiur, ahora si quedaron bien, muchas gracias!
No, no voy a bajar el programa es muy pesado para mi poco espacio en el disco, 200 mg para mi es mucho.
Pero después voy a hacer una prueba y te cuento sobre un código para los gif, una pabada, pero si resulta te digo.
Otra vez graciaaaaasssss...

Responder
JMiur  

Me alegro que funcionara. Fijate en el Paint, debe haber alguna opcion para GIFS y las transparencias.

Responder
Shark_Bloody  

Hola JMiur, si se ejecuta mas de una vez la funcion doLoop, la funcion stopLoop no detiene el movimiento, ¿como hago para que sin importar cuantas veses se ejecute se detenga igual?, espero haberme expresado bien :$

Por las dudas te dejo un ejemplo practico de mi problema, fijate que si apretas iniciar mas de una vez, al apretar detener el movimiento sigue, bueno yo querria que se detuviese igual.

Todo esto referido al ultimo ejemplo de este post.

Responder
Shark_Bloody  

Ah una cosita mas, me gustaria agregar un boton extra para que la imagen vuelva al principio, si no es mucha molestia, intente hacerlo yo solo, pero cuando llamo a la funcion doLoop de nuevo, el movimiento no empieza desde el principio, empieza desde donde se quedo cuando detuve el moimiento.

Responder
JMiur  

El ejemplo es algo primitivo, habría que hacerle varios agregados. Por ejemplo, la lógica es deshabilitar el reinicio cuando se está ejecutando porque sino, pasará eso, habrá muchos loops simultáneamante. En realidad INCIAR/DETENER debería ser sólo un botón y no dos.

Imagino que para el reinicio, lo que te debe faltar es poner en cero el valor de xPos.

Responder
Turko  

Tengo una duda JMiur. En el elemento background url(imagen), existe algún parámetro para redimensionar la imagen?

La cosa está así: En mi blog tengo un widget con las ultimas entradas, justo debajo de la barra donde esta el link de "Inicio". Aparecen las imágenes del post, si no hay ninguna, aparece una imagen al azar previamente definida. El Gadget es este.

Lo que no me gusta, es que al redimensionar la imagen a 60 x 50, se desfigura. He visto en La Faviconera. que tienen un script mostrando por medio del Feed las ultimas entradas de algunos blogs. En ellas se muestra un thumbnail de la imagen que corresponde al post.

La diferencia es que, la imagen se redimensiona un poco, y después se corta, apareciendo una imagen más pequeña y mostrando solo una parte de toda la imagen completa. La mitad. Algo así.

Neceseitaria saber cual es el código normal, para despues arreglarmela en el archivo del script que es este.

Espero haber podido explicarlo. :P

Responder
JMiur  

Turko:
background no permite redimensionar las imágenes, sólo posicionarlas. una forma de posicionar es colocar algo así (eso lo centra):

background: transparent url(imagen) no-repeat 50% 50%;

El problema que tienes es que al usar width y height en la etiqueta IMG, lo que haces es, deformarlas ya que la proporción ancho/alto varia con respecto al original. El resultado, siempre será un poco aleatorio.

Responder
ANAHI  

Recién recién caigo en esta entrada... ¡¡de hace 2 años!! :P
JMiur, hace días que estoy intentando hacer esto de los sprites y no me sale: ya vi como ochenta tutoriales diferentes, en 35 idiomas diferentes, todos aplican 47 técnicas parecidas pero diferentes, y me conseguí como 7 programitas que fabrican la imagen y que funcionan diferente, de uso libre o trial... ahhhhhhhhhh (suspiro).
Lo quiero aplicar a varias imágenes "standard" del blog, x ej. el post-pager... y así, ¿me ayuda?
Le muestro:
http://pruebasdeanahi.blogspot.com/search?updated-max=2009-05-27T08%3A22%3A00-07%3A00&max-results=2
Las que aparecen son img indiv.
la de entradas recientes está puesta con el sprite.
Bueno, espero que esta carta se publique y le llegue, porque tardé un buen rato en escribirla. ¦)

Responder
JMiur  

A ver si puedo explicarlo.

En el ejemplo que tienes, hay un enlace A y una imagen en una etiqueta IMG. En realidad, la idea es no usar la imagen en una etiqueta IMG sino, dejar el enlace sin nada, vacio y colocar la imagen como fondo de la etiqueta A

Si normalmente hago eso, en realidad, no veré nada pero, ahí entra el CSS. Primero, convierto el enlace en un bloque, de esa manera, puedo dimensionarlo. Ya está convertido en bloque porque tiene una propiedad float:left;. Lo que me falta es darle medidas. Así que se las agrego:

blog-pager-newer-link {
float:left;
height:40px;
width:40px;
}

¿Por qué 40x40? porque voy a mostrar un pedacito de una imagen más grande y voy a posicionar el fondo de tal manera de ubicarlo en módulos de 40, hacia arriba, hacia abajo o hacia los lados. Es como tener un cuadradito de 40x40 e irlo ubicando en alguna parte de una hoja más grande. Así que a lo anterior, le agrego el fondo:

blog-pager-newer-link {
background: transparent url(http://img529.imageshack.us/img529/986/spritemad.png) no-repeat -40px 0;
float:left;
height:40px;
width:40px;
}

Muevo la imagen de fondo a la izquierda con -40px y veo la flecha hacia la izquierda.

Si pusiera:
background: transparent url(http://img529.imageshack.us/img529/986/spritemad.png) no-repeat 0 0;
veria la flecha hacia la derecha

Si pusiera:
background: transparent url(http://img529.imageshack.us/img529/986/spritemad.png) no-repeat -80px 0;
veria la casita de home (la muevo mucho más a la izquierda)

Lo que estoy moviendo es lo que está "debajo" El enlace siempre es el mismo, un cuadrado de 40x40 y desplazo el fondo para ubicarlo en alguna parte.

El resto de esa imagen tiene otras mediadas y no es de 40x40 así que si se quiere usar, hay que cambiar el tamaño del enlace, por ejemplo si es de 30x30:
background: transparent url(http://img529.imageshack.us/img529/986/spritemad.png) no-repeat 0 -40px;
muestra una flecha hacia abajo
y
background: transparent url(http://img529.imageshack.us/img529/986/spritemad.png) no-repeat -30px -40px;
una flecha hacia abajo

¿Se entiende algo?

Responder
Anahí  

Si mal no entendí, la idea en este caso es poner la imagen en el blog-pager en lugar de hacer una clase aparte, ¿no?
Ahora, las imágenes aparecen, pero se me amontonan en el medio :o
http://pruebasdeanahi.blogspot.com/search?updated-max=2009-05-27T08%3A22%3A00-07%3A00&max-results=2
(dejé las letras de guía xq si no me pierdo)

Responder
Anahí  

Ya lo solucioné con un transparent.gif y quedó pipí-cucú.
Saludos y gracias.

Responder
JMiur  

Entiendo. lo que has hecho. Está bien porque funciona pero, lo razonable es eliminar la etiqueta IM y colocar el background en el enlace:

#blog-pager-older-link {
background:transparent url(http://img529.imageshack.us/img529/986/spritemad.png) no-repeat scroll 0 0;
float:right;
height:40px;
width:40px;
}

<a id="blog-pager-older-link" class="blog-pager-older-link" title="xxxx" href="xxxx"></a>

Fijate que el enlace, está vacio, no tiene nada; de esa manera, optimizas todo al no tener que cargar una imagen transparente.

Los otros tres son iguales.

Responder
Anahí  

Había escrito un comentario pero no se publicó.
JMiur, no entiendo dos cosas: ¿qué va en "xxxx"?, y en el código de la plantilla ya hay esto -id="blog-pager-older-link" class="blog-pager-older-link"- , ¿lo repito, lo reemplazo?
Lo probé y se me descuajeringa.
Saludos y gracias.

Responder
JMiur  

A ver si puedo explciarlo de otro modo. El enlace queda como está, no hay que modificar nada, sólo quitar la etiqueta IMG y poner el background en #blog-pager-older-link

Así que, esta parte empieza con la etiqueta A

<a ... y aquí no tocamos nada, queda todo igual ... >
<img ... aquí está la imagen en una etiqueta que es lo que quitamos ... ></a>

Eso en negrita, que es donde ahoras has colocado una imagene transparente, es lo que quitamos. Poniendo el fondo en el enlace, no hace falta.

Queda así:

<a LO QUE HAYA ESTO NO LO CAMBIAMOS ></a>

Responder
Anahí  

Gracias por la paciencia, JMiur. Eso que me dice es lo que yo le entendí desde un principio, y así es cómo lo hice. Pero el caso es que se me amontonan las imágenes en el medio.
Saludos.

Responder
JMiur  

Sí. tienes un error, algo que sobra.

#blog-pager es el rectángulo general, va de lado a lado y es el que contiene todo lo demás. Las propiedades background, height y width se eliminan de allí; la única propiedad que debe tener es text-align:center:

#blog-pager {
text-align:center;
}

Apenas quites esas propiedades, verás que una flecha se coloca a un lado y la otra al otro.

Las definciones de #blog-pager-newer-link y #blog-pager-older-link son correctas.

Ahora, faltaría una más, la del HOME porque no está definida así que agrega esto:

a#home-link {
margin: 0pt auto;
width: 40px;
height: 40px;
display: block;
background:transparent url(http://img529.imageshack.us/img529/986/spritemad.png) no-repeat -80px 0;
}

Esta, no flota, debemos convertirla en bloque y centrarla.

Responder
Anahí  

Uhhhhhh, ahora sí, resultó!!!!! Gracias JMiur.
Un detalle: en vez de a#home- puse a.home- porque en el link dice class y con # no me aparecía, pero entonces me acordé de la diferencia entre uno y otra (la mejor forma de aprender es practicar, y preguntar, claro) :D
Saludos.

Responder
JMiur  

Perfecto Anahí. Es cierto eso de la clase :D Error mio :$

Responder

¿Quiere dejar un comentario?

recuerde que los comentarios están siendo moderados y serán publicados a la brevedad ...

Todos los archivos y demos alojados en Fileden han sido redireccionados y deberían estar funcionando correctamente.
De todos modos, también puede accederse a ellos a través de SkyDrive

Nota: sólo los miembros de este blog pueden publicar comentarios.

Si le gusta ir a lo seguro utilice este botón para abrir los comentarios en una ventana modal en esta misma pagina.

Si añora tiempos idos, use este enlace para agregar un comentario al viejo estilo ...

 
CERRAR