09 de Septiembre de 2010

Notas Espacio Programación

galería de imágenesvideo
AUTOR: Andrés Fernández
FECHA: 15/8/2009
LECTURAS:2767
Buscar Notas
volver
Coordenadas del ratón relativas al elemento que dispara un evento

Lupa sencilla en javascript

Veremos cómo crear una lupa sencilla usando las propiedades layerX y layerY, soportadas por los navegadores estándar, y sus equivalentes para Explorer
Las propiedades layerX y layerY del objeto event proporcionan las coordenadas x e y del ratón, relativas al elemento que dispara el evento. Dichas propiedades son soportadas por todos los navegadores modernos, salvo por Explorer que, como bien sabemos, maneja los eventos a su manera. En este caso, ese fantástico navegador utiliza las propiedades offsetX y offsetY, que son equivalentes a las anteriores.
Veamos un ejemplo de cómo obtener las coordenadas del ratón relativas a una imagen:


Como podemos apreciar, las coordenadas son relativas a la imagen y no al área de visualización de la página o viewport, como ocurriría si utilizáramos en su lugar las propiedades clientX y clientY del objeto event, complementadas con self.pageXOffset y self.pageYOffset y sus equivalentes para Explorer (document.body.scrollLeft/scrollTop o document.documentElement.scrollLeft/scrollTop, según el compatMode que usemos) para añadir el desplazamieno del scroll.
El código utilizado es el siguiente:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>coordenadas imagen</title>
<style>
*{ margin:0; padding:0; font-size:10px; color#666; font-family:Verdana, Arial, Helvetica, sans-serif}
img{cursor:crosshair}
</style>
<script>
function 
getPos(e){
    var 
ev=|| window.event;
    var 
obj=ev.target || ev.srcElement;
    
obj.style.position='relative'
    
posX=ev.layerX || ev.offsetX || 0;
    
posY=ev.layerY || ev.offsetY || 0;
    return {
x:posX,y:posY}

</
script>  
</head>

<body>
<img src="img/38.jpg" width="400" height="400" onmousemove="var pos=getPos(event);document.getElementById('log').innerHTML='x: '+pos.x+', y: '+pos.y" />
<div id="log">pase el mouse sobre la imagen</div>
</body>

</html>



Si tomamos ese código como base y agregamos algunos estilos css y regla de tres simple, podemos fácilmente conseguir un efecto lupa semejante a este:


El código que utilizamos para lograrlo es el siguiente:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Lupa Sencilla</title>
<style>
*{ margin:0; padding:0; font-size:10px; color#666; font-family:Verdana, Arial, Helvetica, sans-serif}
#lupa{width:167px;height:167px;position:absolute;border:1px solid #000;overflow:hidden;left: 258px;top:0px;background-color:#999}
#im{position: relative; left:0;top:0}
#im0{cursor:crosshair}
</style>
<script>
function 
t(id){return document.getElementById(id);}
function 
addEvent(obj,fun,type){
    if(
obj.addEventListener){
        
obj.addEventListener(type,fun,false);
    }else if(
obj.attachEvent){
        var 
f=function(){
            
fun.call(obj,window.event);
        }
        
obj.attachEvent('on'+type,f);
        
obj[fun.toString()+type]=f;
    }else{
        
obj['on'+type]=fun;
    }

function 
getPos(e){
    var 
ev=|| window.event;
    var 
obj=ev.target || ev.srcElement;
    
obj.style.position='relative'
    
posX=ev.layerX || ev.offsetX || 0;
    
posY=ev.layerY || ev.offsetY || 0;
    return {
x:posX,y:posY}

function 
css(id,prop){
    if(
window.getComputedStyle){
        return 
document.defaultView.getComputedStyle(t(id),null).getPropertyValue(prop);
    }else{
        var 
re = /(-([a-z]){1})/g;
        if (
prop == 'float'prop 'styleFloat';
        if (
re.test(prop)) {
            
prop prop.replace(re, function () {
                return 
arguments[2].toUpperCase();
            });
        }
        return 
t(id).currentStyle[prop] ? t(id).currentStyle[prop] : null;
    }

function 
cambiar(pos,rel,e,a,a2,w,h){
    var 
al=parseInt(a);
    var 
al2=parseInt(a2);
    if(
pos.x<(al/2)/rel)
        
pos.x=(al/2)/rel;
    if(
pos.y<(al2/2)/rel)
        
pos.y=(al2/2)/rel;
    if(
pos.x>(w)-(al/2)/rel)
        
pos.x=(w)-(al/2)/rel;
    if(
pos.y>(h)-(al2/2)/rel)
        
pos.y=(h)-(al2/2)/rel;
    
t('im').style.left=-(rel*pos.x)+(al/2)+'px';
    
t('im').style.top=-(rel*pos.y)+(al2/2)+'px';
}
onload=function(){
    
addEvent(
        
t('im0'),
        function(
e){
            var 
al2=css('lupa','height');
            var 
al=css('lupa','width');
            var 
pos=getPos(e);
            
cambiar(pos,(t('im').width)/this.width,e,al,al2,this.width,this.height);
        },
        
'mousemove'
    
);
}
</
script>  
</head>

<body>
<img id="im0" src="img/18.jpg" width="250" height="167" />
<div id="lupa"><img  id="im" src="img/18.jpg" width="500" /></div>
<div>recorra con el mouse la primera imagen</div>

</body>
</html>



El truco consiste en enmascarar la imagen a tamaño completo con una capa con overflow hidden, y desplazarla (seguimos hablando de la imagen), en sentido inverso al movimiento del mouse, la misma distancia en pixeles respecto de su ubicación inicial en las coordenadas 0,0 de la capa, obtenida con layerX y layerY (y sus análogas para Explorer) durante el evento onmousemove, pero recalculada en función a la diferencia de proporción entre la imagen pequeña y la ampliada.
Adicionalmente, debemos frenar el movimiento al llegar a los límites de la imagen pequeña, para no mostrar blancos en la visualización de la ampliación.
Home - Quiénes Somos - Portfolio - Espacio Diseño - Espacio Programación - Capacitación - Contacto - RSS - XHTML 1.0