Živé náhledy alb s CSS3 a jQuery

Dnes vytvoříme skript pro náhled obsahu alba s animací podobnou slideshow. To lze použít ve fotogaleriích, online obchodech, profilových stránkách a dalších. Příklad je inspirován Facebookem, kde umístíte ukazatel myši na album a zobrazí se prezentace některých fotografií obsažených v něm.

Začněme s HTML.

HTML

Prvním krokem je položit základy HTML dnešního příkladu. Toto je standardní dokument HTML5:

index.php

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Album Previews with CSS3 and jQuery | Tutorialzine </title>

        <!-- Our stylesheet -->
        <link rel="stylesheet" href="assets/css/styles.css" />

    </head>
    <body>

        <div id="main">

                <a href="#" data-images="assets/img/thumbs/11.jpg|assets/img/thumbs/10.jpg"
                   class="album">
                   <img src="assets/img/thumbs/4.jpg" alt="People" />
                   <span class="preloader"></span>
                </a>

                <!-- More albums will go here -->

        </div>

        <!-- JavaScript Includes -->
        <script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
        <script src="assets/js/script.js"></script>
        <script src="assets/js/albumPreviews.js"></script>

    </body>
</html>

#hlavní div obsahuje označení alb:

<a href="#" data-images="assets/img/thumbs/11.jpg|assets/img/thumbs/10.jpg" class="album">
   <img src="assets/img/thumbs/4.jpg" alt="People" />
   <span class="preloader"></span>
</a>

Každé album je odkaz, který by normálně ukazoval na celou stránku alba, kde by uživatel viděl všechny fotografie v albu (zde ukazuje na #). Album také obsahuje datový atribut, který obsahuje adresy URL obrázků v něm obsažených (je dobré ukazovat na miniatury a ne na celé obrázky). V části výukového programu jQuery získáme tyto adresy URL a připojíme je jako skutečné obrázky k odkazu na album a animujeme je.

Uvnitř odkazu je úvodní obrázek alba (který by se zobrazil, i když je JavaScript vypnutý). Tento obrázek by měl být jiný z těch, které jsou součástí atributu data. Poslední je preloader span, který zobrazí průhledný PNG, který je otočený pomocí CSS3. Rozhodl jsem se jít touto cestou místo použití GIF, protože formát PNG podporuje správnou průhlednost a vypadá lépe.

Bylo by však příliš práce psát HTML pro všechna alba ručně. Toto je ideální příležitost hodit nějaké PHP, aby se to automaticky vygenerovalo.

index.php

$albums = array(
    'People' => array(
                'assets/img/thumbs/4.jpg',
                'assets/img/thumbs/11.jpg',
                'assets/img/thumbs/10.jpg'),

   // More albums go here
);

foreach ($albums as $name => $a) {

    ?>

    <a href="#" data-images="<?php echo implode('|', array_slice($a,1))?>" class="album">
       <img src="<?php echo $a[0]?>" alt="<?php echo $name?>" />
       <span class="preloader"></span>
    </a>

    <?php

}

Můžete vidět, že při vytváření atributu data používám funkci array_slice, aby se výchozí obrázek neopakoval (jinak byste tentýž obrázek viděli v prezentaci dvakrát).

S tímto z cesty, pojďme napsat nějaký JavaScript!

JavaScript

Stejně jako u ostatních tutoriálů na webu používám knihovnu jQuery, abych usnadnil psaní JavaScriptu.

Hlavní funkce tohoto příkladu má podobu přenosného pluginu jQuery. Při události mouseenter plugin hledá atribut data-images, analyzuje jej a připojí obrázky k albu. Poté spustí prezentaci, která se automaticky zastaví při události mouseleave:

assets/js/albumPreviews.js

(function($) {

    $.fn.albumPreviews = function() {

        return this.each(function(){

            var album = $(this),
                loop = null, images = $();

            if(!album.data('images')){
                // The data-images attribute is missing. Skip this album.
                return true;
            }

            var sources = album.data("images").split('|');

            album.on('mouseenter', function(){

                if(!images.length){
                    // The images have not been loaded yet

                    $.each(sources,function(){
                        images = images.add('<img src="' + this + '" />');
                    });

                    // Start the animation after the first photo is loaded
                    images.first().load(function() {
                        album.trigger('startAnimation');
                    });

                    album
                        .append(images)
                        .addClass('loading');
                }
                else{
                    // Start the animation directly
                    album.trigger('startAnimation');
                }

            }).on('mouseleave', function(){
                album.trigger('stopAnimation');
            });

            // Custom events:

            album.on('startAnimation',function(){

                var iteration = 0;

                // Start looping through the photos
                (function animator(){

                    album.removeClass('loading');

                    // Hide the currently visible photo,
                    // and show the next one:

                    album.find('img').filter(function(){
                        return ($(this).css('opacity') == 1);
                    }).animate({
                        'opacity' : 0
                    }).nextFirst('img').animate({
                        'opacity' : 1
                    });

                    loop = setTimeout(animator, 1000);  // Once per second

                })();

            });

            album.on('stopAnimation',function(){

                album.removeClass('loading');
                // stop the animation
                clearTimeout(loop);
            });

        });

    };

    // This jQuery method will return the next
    // element of the specified type, or the
    // first one if it doesn't exist

    $.fn.nextFirst = function(e) {
        var next = this.nextAll(e).first();
        return (next.length) ? next : this.prevAll(e).last();
    };

})(jQuery);

K lepší organizaci mého kódu používám dvě vlastní události startAnimation a stopAnimation. Spouštějí se při zadání myši/podržení myši. O animaci se stará animátor funkce, která se volá jednou za sekundu s časovým limitem. Můžete si to vyladit podle svého.

A zde je návod, jak se používá:

assets/js/script.js

$(function() {

    // Initialize the plugin
    $('#main .album').albumPreviews();

});

Tím se plugin aktivuje a na prvcích se nastaví obslužné rutiny událostí mouseenter/mouseleave. Vše, co nyní musíme udělat, je přidat nějaké elegantní CSS, aby to vypadalo jako součást.

CSS

Zde uvedu pouze tu zajímavější část šablony stylů. Zbývající pravidla CSS můžete vidět v assets/css/styles.css .

Alba mají album třída. To usnadňuje jejich styling:

.album{
    width:140px;
    height:140px;
    margin: 15px 5px;
    position:relative;

    display:inline-block;
    border: 4px solid #F0F0F0;
    background-color: #F0F0F0;

    border-radius:12px;
    box-shadow:0 -2px 0 #616161;

    /* Reflections below the image */
    -webkit-box-reflect: below 0 -webkit-linear-gradient(rgba(255,255,255,0) 0%, rgba(255,255,255,0) 80%, rgba(255,255,255,0.1) 100%);
}

/* Showing a subtle shadow on the borders of the image */
.album:before{
    content: '';
    top: -1px;
    left: -1px;
    right: -1px;
    bottom: -1px;
    z-index:1000;
    position: absolute;
    box-shadow: 0 0 2px rgba(0, 0, 0, 0.4) inset;
    border:1px solid #fff;
}

/* The album photos (hidden by default) */
.album img{
    top:0;
    left:0;
    opacity:0;
    width:140px;
    height:140px;
    position:absolute;
}

/* The first (the default) thumbnail is visible */
.album img:first-child{
    opacity:1;
}

.album img,
.album:before{
    border-radius: 10px;
}

/* The preloader PNG. It is rotated with a CSS keyframe animation */

.album .preloader{
    display:none;
}

.album.loading .preloader{
    content:'';
    position:absolute;
    width:18px;
    height:18px;
    background:url('../img/preloader.png') center center;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin:auto;
    display:block;

    /* Configure a keyframe animation for Firefox */
    -moz-animation: rotate 1s linear infinite;

    /* Configure it for Chrome and Safari */
    -webkit-animation: rotate 1s linear infinite;
}

/* Webkit keyframe animation */
@-webkit-keyframes rotate{
    0%{     -webkit-transform:rotate(0deg);}
    100%{   -webkit-transform:rotate(360deg);}
}

/* Firefox Keyframe Animation */
@-moz-keyframes rotate{
    0%{     -moz-transform:rotate(0deg);}
    100%{   -moz-transform:rotate(360deg);}
}

Nástroj .preloader png se zobrazí při prvním najetí myší na album. Poté skript začne načítat obrázky. Pokud jste na rychlém připojení, možná to neuvidíte, ale je dobré mít, abyste uživatelům na pomalých sítích dali pocit, že se něco děje na pozadí. Preloader je animován pomocí animace klíčového snímku CSS, která se opakuje nekonečně mnohokrát.

Tímto je náš živý náhled alba dokončen!

Hotovo!

Tento příklad můžete použít ke zlepšení zážitku návštěvníků při používání vašich stránek. Efekt náhledu se může hodit při prezentaci velkého seznamu produktů (jako je výukový program pro vyhledávání produktů na Googlu, kde by bylo úhledné mít další fotografie produktů prezentované tímto způsobem), alb, videa, uživatelské profily a další.

Jediné, co musíte udělat, abyste mohli příklad použít na svých stránkách, je vygenerovat HTML označení alb a zahrnout plugin.