Efecto Retina tipo Apple con jQuery

Apple ha aplicado durante mucho tiempo una estrategia ganadora en marketing:crear productos bien diseñados, tener una base de fans dedicada y dejar que la publicidad se acumule antes del lanzamiento de cada producto.

Este es también el caso de la última versión de su iPhone. Pero lo que encontré interesante es el término que acuñaron:"pantalla Retina" y la imagen promocional que lo acompaña.

Lo que me hizo preguntarme es si era posible convertir esta imagen estática en un "efecto Retina" completamente funcional con solo jQuery y CSS. Esto es exactamente lo que estamos haciendo hoy. Así que tome los archivos de demostración del botón de arriba y siga leyendo.

Paso 1:XHMTL

El marcado para el efecto es bastante sencillo. Puede ver que solo tenemos una cantidad de divs y una imagen.

demostración.html

<div id="main">

    <div id="iphone">
        <div id="webpage">
            <img src="img/webpage.png" width="499" height="283" alt="Web Page" />
            <div id="retina"></div>
        </div>
    </div>

</div>

El #iphone div muestra el marco del iphone. En su interior se encuentra la #webpage div con la captura de pantalla de la página web. La captura de pantalla en realidad se muestra a la mitad de su tamaño original, ya que estamos usando la misma imagen tanto para la versión pequeña (que se muestra en el iPhone) como para la versión grande, que se muestra en la información sobre herramientas redondeada.

Por último, tenemos el div retina, que se redondea con CSS3 y muestra la versión grande de la captura de pantalla de la página web como fondo a medida que se mueve con el mouse.

Paso 2:CSS

Pasando a la parte CSS del tutorial. Vamos a darle estilo al iphone , página web y retina divs, por lo que hacemos posible el increíble efecto.

estilos.css

#iphone{
    /* The iphone frame div */
    width:750px;
    height:400px;
    background:url('img/iphone_4G.png') no-repeat center center;
}

#webpage{
    /* Contains the webpage screenshot */
    width:499px;
    height:283px;
    position:absolute;
    top:50%;
    left:50%;
    margin:-141px 0 0 -249px;
}

#retina{
    /* The Retina effect */
    background:url('img/webpage.png') no-repeat center center white;
    border:2px solid white;

    /* Positioned absolutely, so we can move it around */
    position:absolute;
    height:180px;
    width:180px;

    /* Hidden by default */
    display:none;

    /* A blank cursor, notice the default fallback */
    cursor:url('img/blank.cur'),default;

    /* CSS3 Box Shadow */
    -moz-box-shadow:0 0 5px #777, 0 0 10px #aaa inset;
    -webkit-box-shadow:0 0 5px #777;
    box-shadow:0 0 5px #777, 0 0 10px #aaa inset;

    /* CSS3 rounded corners */
    -moz-border-radius:90px;
    -webkit-border-radius:90px;
    border-radius:90px;
}

#retina.chrome{
    /* A special chrome version of the cursor */
    cursor:url('img/blank_google_chrome.cur'),default;
}

#main{
    /* The main div */
    margin:40px auto;
    position:relative;
    width:750px;
}

Al especificar un posicionamiento absoluto en el div de la página web, podemos aplicar la técnica de centrado vertical y horizontal, colocando efectivamente la captura de pantalla de la página web en el medio del marco del iPhone.

La retina div también tiene asignado un posicionamiento absoluto, por lo que es posible moverlo en la parte jQuery del tutorial simplemente especificando un desplazamiento superior e izquierdo. Este div también tiene la captura de pantalla de la página web como fondo (en su tamaño original). Compensar el fondo con el movimiento del div crea la ilusión de que amplía la pequeña captura de pantalla debajo.

El div retina también ha aplicado un radio de borde con un valor de exactamente la mitad de su ancho, lo que lo convierte en un círculo perfecto (al menos en los navegadores que admiten la propiedad border-radius CSS3:Chrome, Safari, Opera y Firefox).

Y, finalmente, ocultamos el puntero del mouse al proporcionar un archivo de cursor en blanco (Google Chrome no muestra los cursores completamente en blanco, por lo que proporcionamos un cursor blanco especial de 1 px; al menos es mejor que nada). El navegador Opera ignora por completo los cursores personalizados y no existen soluciones alternativas, por lo que es posible que los usuarios que utilicen este navegador no disfruten de la experiencia completa.

Paso 3:jQuery

Si recuerdas, hace unos meses hicimos un tutorial aquí en Tutorialzine, en el que usamos jQuery para crear un efecto de sesión de fotos. Esta vez estamos usando una técnica similar para hacer el "efecto retina", como se ve en el sitio web de Apple.

Y dado que tenemos todo el estilo en su lugar, se trata de un poco de codificación JavaScript con la ayuda de la biblioteca jQuery.

secuencia de comandos.js

$(document).ready(function(){

    /* This code is executed on the document ready event */

    var left    = 0,
        top     = 0,
        sizes   = { retina: { width:190, height:190 },
                webpage:{ width:500, height:283 } },
        webpage = $('#webpage'),
        offset  = { left: webpage.offset().left, top: webpage.offset().top },
        retina  = $('#retina');

    if(navigator.userAgent.indexOf('Chrome')!=-1)
    {
        /*  Applying a special chrome curosor,
            as it fails to render completely blank curosrs. */

        retina.addClass('chrome');
    }

    webpage.mousemove(function(e){

        left = (e.pageX-offset.left);
        top = (e.pageY-offset.top);

        if(retina.is(':not(:animated):hidden')){
            /* Fixes a bug where the retina div is not shown */
            webpage.trigger('mouseenter');
        }

        if(left<0 || top<0 || left > sizes.webpage.width ||
            top > sizes.webpage.height)
        {
            /*  If we are out of the bondaries of the
                webpage screenshot, hide the retina div */

            if(!retina.is(':animated')){
                webpage.trigger('mouseleave');
            }
            return false;
        }

        /*  Moving the retina div with the mouse
            (and scrolling the background) */

        retina.css({
            left                : left - sizes.retina.width/2,
            top                 : top - sizes.retina.height/2,
            backgroundPosition  : '-'+(1.6*left)+'px -'+(1.35*top)+'px'
        });

    }).mouseleave(function(){
        retina.stop(true,true).fadeOut('fast');
    }).mouseenter(function(){
        retina.stop(true,true).fadeIn('fast');
    });
});

En la función mousemove, las coordenadas actuales del mouse se pasan como e.pageX y e.pageY , pero son absolutos con relación al documento. Al restar el desplazamiento de posición del div del sitio web, obtenemos coordenadas relativas para el mouse, que luego se usan para colocar el div de la retina.

Esto, combinado con el cursor en blanco que configuramos en la parte CSS del tutorial, crea el efecto retina en JavaScript puro y CSS.

Conclusión

A medida que el debate sobre Flash/HTML5 se calentó recientemente, la gente comenzó a buscar formas de lograr el mismo nivel de funcionalidad que brinda flash, sin depender de un complemento externo. Esto es posible para interacciones simples, pero aún tenemos que asegurarnos de que la solución sea compatible con todos los navegadores, lo que a veces es bastante imposible (piense en IE aquí).

Con suerte, hoy creamos algo que rivalizaría fácilmente con una solución Flash equivalente.

¿Qué opinas? ¿Cómo mejorarías este efecto?