Ver Mensaje Individual
  #16 (permalink)  
Antiguo 21/12/2011, 06:46
furoya
(Desactivado)
 
Fecha de Ingreso: noviembre-2002
Ubicación: Ciudad Autónoma de Buenos Aires
Mensajes: 2.367
Antigüedad: 22 años, 1 mes
Puntos: 317
Respuesta: Aplicar filtro o similar sobre un elemento SHAPE de una imagen

Retomo dos frases del mensaje #13

Cita:
...En fin, si alguien lo quiere mejorar, ahí se los dejo...
Cita:
...quizá sea más práctica como alternativa al filtro light de Microsoft...
Evidentemente nadie lo quiso mejorar, y el hecho de que sea un ejemplo incompatible con IE no me deja muy bien. Así que se me ocurrió probar alguna versión para ese navegador; y tuve demasiados problemas.

Como es mi costumbre voy a contar toda la historia, amén de postear todos los códigos que fui armando.
A quien no le interese el asunto: nos vemos en otro tema. A quién le interesen los filtros DX ... agua, resina y ajo, porque esto va para largo.


Lo primero que hice fue un ejemplo con

-ms-filter: "progid:DXImageTransform.Microsoft.Light()";

que en principio es la simulación de un spot, una "mancha de luz" proyectada sobre una imagen. Eligiendo el color, se puede ver cómo "ilumina" mezclándose con los colores de esa imagen (o texto, o lo que fuere que contenga la capa). Es más o menos lo que hace el canvas

globalCompositeOperation = "lighter";


pero al probarlo noté una diferencia harto evidente: los de máicrosof se tomaron muy en serio eso del "reflector", y no sólo le agregaron atributos para simular hasta el barrido de un cañón seguidor, sino que el spot propiamente dicho degrada hacia la total oscuridad, tal y como hace una luz real adonde no llega con su potencia.

Código:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<title>EJEMPLO FILTRO light addPoint.</title>

<style type="text/css">

#met {
-ms-filter: "progid:DXImageTransform.Microsoft.Light()";
filter: progid:DXImageTransform.Microsoft.Light();
position: relative;
width: 640px;
height: 480px;
}

</style>
</head>
<body>
<h1>Simula iluminación con filtro <code>light</code>. (IE)</h1>

<img src="http://img836.imageshack.us/img836/9695/metropolis03.jpg" id=met><br>

<script type="text/javascript">

var imagen=document.getElementById("met");
imagen.filters.item("DXImageTransform.Microsoft.Light").addPoint
(50,50, 1000, 255,170,170, 100)

function mueve(){
imagen.filters.item("DXImageTransform.Microsoft.Light").moveLight
(0, event.offsetX, event.offsetY, 200, 1)
}

imagen.onmousemove = mueve;

</script>
</body>
</html>
OK. Así como viene no nos sirve para emular el efecto del canvas.
Algo que también mencioné es el método con lógica XOR (eXclusive OR). Lo repito para que no tengan que buscarlo: lo que hace es mostrar en dos capas parcialmente superpuestas solamente las partes donde no se cruzan, quiero decir, que donde ocupan el mismo lugar se crea una especie de máscara transparente que deja ver lo que hay detrás. Porque o muestra una o muestra la otra, pero las dos juntas, no.

Hablando en otro tema de círculos que siguen al puntero sobre una capa, mostrando otra capa que tienen detrás como si fueran un "agujero", me acordé que en IE ya había hecho algo así con el filtro chroma, que es la versión DirectX del chroma-k o "pantalla azul" para hacer efectos de video. Si aplico el filtro en una capa que tenga algo en color azul (o verde, o rojo, o el que configure) éste se vuelve transparente, y permite ver lo que hay detrás.
Como otra cosa que mencioné es el efecto de "rayos X" donde transparento una parte de (p.e.) la imagen de una persona, y por allí se ve otra igual, en las mismas coordenadas, pero editada con su esqueleto; se me ocurrió combinar un

filter: progid:DXImageTransform.Microsoft.Light(enabled=tr ue);

con un

filter:progid:DXImageTransform.Microsoft.Chroma(co lor='red');

y entonces mover un círculo "transparentado" con croma-key sobre la imagen principal, para que en su lugar deje ver otra imagen detrás, pero que tiene aplicada en toda su superficie el filtro light para virarla al rojo o al verde, según corresponda. (Y no, no iba a hacer otra imagen editada.)

Código:
<html xmlns:v="urn:schemas-microsoft-com:vml">

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<TITLE>VML CHROMA.</TITLE>
 
<style>
BODY {}

v\:* { behavior: url(#default#VML); }
</style>
<script>
var X = 0;
var Y = 0;
var cursor = "move";
var destino ="#";
var titulo = "";

function colorea() {
document.getElementById("capaFondo").filters.item
("DXImageTransform.Microsoft.Light").addAmbient(255, 150, 150, 100);
}

function mueve(evento){
var alfa = document.getElementById("caja");
var bravo = document.getElementById("spot");
var eco = document.getElementById("capaFondo");

//var distX = alfa.offsetLeft;
//var distY = alfa.offsetTop;

document.title = X+" "+Y /*+" "+distX+" "+distY*/ ;

X = evento.x /*- distX*/ ;
Y = evento.y /*- distY*/ ;

if ((X>305 && Y>160) && (X<340 && Y<220)){
cursor = "pointer";
destino = 
"http://img195.imageshack.us/i/metropolis01a.jpg"; 
titulo = "Cabeza."
eco.filters.item
("DXImageTransform.Microsoft.Light").changeColor(0, 0, 255, 0, 1)

}

else {
cursor = "move";
destino = 
"http://img710.imageshack.us/slideshow/webplayer.php?id=antoniosegui.jpg"
titulo = "A Colección."
eco.filters.item
("DXImageTransform.Microsoft.Light").changeColor(0, 255, 150, 150, 1)
}

bravo.style.left = X - 50 + "px";
bravo.style.top = Y - 50 + "px";



alfa.style.cursor = cursor;
alfa.title = titulo;

}

function lleva(){
window.location = destino;
}


</script>
</HEAD> 
<BODY>
<h1>Efecto <em>spot</em> con filtros <code>chroma</code> y 
<code>light</code>. (IE)</h1>
<div style="position: relative; width:640px; height:480px; "
onclick="lleva()" onmousemove="mueve(event)" id="caja">
<img style="position: absolute; width:640px; height:480px; 
-ms-filter: 
progid:DXImageTransform.Microsoft.Light(enabled=true);
filter: progid:DXImageTransform.Microsoft.Light(enabled=true); " 
src="http://img195.imageshack.us/img195/2089/metropolis01a.jpg" 
onload="colorea()" id="capaFondo">

<div style="position: absolute; width:640px; height:480px; 
-ms-filter:progid:DXImageTransform.Microsoft.Chroma(color='red');  
filter:progid:DXImageTransform.Microsoft.Chroma(color='red'); background-image: url(http://img195.imageshack.us/img195/2089/metropolis01a.jpg); ">

<v:oval style="position: absolute; width:100px; height:100px; 
background-color: transparent; " id="spot" fillcolor="red"
stroke="true" strokecolor="black" strokeweight="0" />

</div>
</div>

<p style="font-size: 110%">El efecto está hecho con una capa que 
tiene la imagen como fondo y aplicado un filtro 
<code>chroma</code>, que "borra" el dibujo circular del 
<code>VML</code> que simula el <em>spot</em>. <br>
Una segunda capa (<code>capaFondo</code>) es una imagen 
detrás de la anterior, y tiene aplicado un filtro 
<code>light</code> que la vira al verde o al rojo según el 
puntero se encuentre o no en el área activa, y es la que 
se ve a través del círculo. </p>
</body>
</html>
Esto es algo muy parecido a lo que se vio en los ejemplos de post anteriores, la diferencia es que en esos casos el recorte era con un clip rectangular, y acá se usa un shape VML.