در آموزشی امروز قصد داریم یک گالری اسلاید شو تمام صفحه با موزیک به کمک خصوصیت audio در HTML5 طراحی کنیم. گالری از تصاویرمختلف شهر نیویورک رو با صوت ترافیک شهر ادغام کردیم و یک گالری اسلاید شو زنده از صوت هیاهوی شهر به وجود آوردیم .

برای ایجاد کردن اسلاید شو و گالری تصاویر تمام صفحه از Vegas jQuery plugin استفاده می کنیم. المان صوت (Audio) توسط Buzz پلاگین جاوا اسکریپتی برای کنترل audio ، کنترل خواهد شد . درباره ی کارکرد هر دو پلاگین معرفی شده میتوانید در سایت Jay Salvat’s بیشتر مطالعه کنید. 

تصاویر بند انگشتی که کنترل اسلاید شو رو داردن با اسکرول سفارشی از کتابخونه ی jScrollPane و افکت های انیمیت easing از کتابخونه ی jQuery easing ادغام شدند تا حس بهتری در طراحی سایت به ما بدن.

عکاس Alessandro Artini است و پروفایل Flikr شون رو هم میتونید ببینید.

با کدهای HTML شروع میکنیم

در ابتدای طراحی یک Div برای تیتر هر عکس و متن توضیحی برای آن ایجاد میکنیم.

<div id="title">
    <h1>New York Gallery</h1>
    <p>Pictures by <a href="https://www.flickr.com/">Alessandro Artini</a></p>
</div>

عکس های بند انگشتی در آیتم های لیست قرار خواهند گرفت که هر آیتم به تصویر اسلاید شو تمام صفحه لینک خواهد شد که اطلاعاتی نظیر تیتر رو نیز به همراه خواهد داشت. در نظر داشته یاشید که یک data attribute تعریف کردیم به اسم data-valign که قرار است تراز عمودی هر تصویر رو توش تعریف کنیم تا اطمینان حاصل کنیم که قسمتی از عکس رو که میخوایم نمایش داده بشه و بریده نشه.

دو Div خالی ایجاد کردیم برای شبیه سازی افکت فلش دوربین برای زمانی که تصاویر عوض می شوند ومشخص کننده ی موقعیت کنونی اسلاید شو. 

<div id="flash"></div>
<div id="thumbnails">
  <ul>
    <li>
      <a href="01.jpg">
        <img src="01b.jpg" title="New York moving" data-valign="top">
      </a>
    </li>
    <li>
      <a href="02.jpg">
        <img src="02b.jpg" title="New York traffic" data-valign="bottom">
      </a>
    </li>
    <li>
      <a href="03.jpg">
        <img src="03b.jpg" title="Street dancers">
      </a>
    </li>
    ...
    </ul>
    <div id="pointer"></div>
</div>

دو المان لینک ایجاد کردیم برای کنترل اندازه موزیک و نگه داشتن اسلاید شو.

<div id="pause"><a href="#">Paused</a></div>

<div id="volume"><a href="#">Sounds</a></div>

استایل دهی با CSS

در ابتدا استایل های CSS مربوط به تیتر های هر عکس که در پایین صفحه با پس زمینه ی مشکی قرار خواهد گرفت رو مقدار دهی می کنیم. از rgba استفاده کردیم که میزان شفافیت (Opacity) آن را تعیین کنیم.  البته برای مرورگر های قدیمی تر از مقدار دهی استاندارد Hex آن یعنی #000 استفاده می کنیم.

فونت ها رو هم از Google fonts collection انتخاب کردیم: 

#title {
    background: #000;
    background: rgba(0, 0, 0, 0.8);
    bottom: 0px;
    font: 11px Arial, Helvetica, sans-serif;
    padding: 10px 20px;
    position: fixed;
    right: 0px;
    text-align: right;
    width: 100%;
}
    #title h1 {
        font: 30px 'Ultra', Arial, serif;
        margin: 0;
        padding: 0;
    }

از ترفند طراحی فوق برای تصاویر بند انگشتی نیز استفاده می کنیم. المان های لیست به صورت افقی نمایش داده خواهند شد.

#thumbnails {
    background: #000;
    background: rgba(0, 0, 0, 0.8);
    height: 90px;
    left: 0;
    overflow: hidden;
    position: fixed;
    top: 0;
    width: 100%;
}
    #thumbnails ul {
        margin: 0;
        padding: 0;
    }
    #thumbnails li {
        float: left;
        list-style: none;
        margin: 5px;
        padding: 0;
    }
    #thumbnails a {
        outline: none;
    }
    #thumbnails img {
        width: 112px;
    }

اشاره کننده ایی که مشخص کردن تصویر در حال نمایش در اسلاید شو رو به عهده داره ، در ابتدا از بیرون تصویر وارد میشه و با یک افکت انیمیت ، تصویری که در حال نمایش هست رو مشخص میکنه.

#pointer {
    border: 2px solid #F30;
    cursor: pointer;
    height: 75px;
    left: -100px;
    margin: 3px;
    position: absolute;
    width: 112px;
}

افکت فلش دوربین عکاسی با یک Div با پس زمینه ی سفید روی تمام صفحه قرار خواهد گرفت:

#flash {
    background: #FFF;
    display: none;
    height: 100%;
    position: fixed;
    width: 100%;
}

ترفند مشابهی برای کلمه ی pause به کار بردیم که البته در ابتدا نمایش داده نخواهند شد.

#pause {
    display: none;
    font: 100px 'Ultra', arial, serif;
    height: 100%;
    opacity: 0.4;
    position: absolute;
    text-align: center;
    text-shadow: 0 0 5px #000;
    width: 100%;
}
    #pause a {
        color: #FFF;
        height: 100px;
        left: 50%;
        margin: -50px 0 0 -250px;
        position: absolute;
        text-transform: uppercase;
        top: 50%;
        width: 500px;
    }

برای طراحی آیکون کنترل میزان صدای موزیک از سه کلاس مختلف که هر کدوم وضعیت خاصی رو کنترل خواهد کرد از سه آیکون مختلف استفاده کردیم. از ترفند sprites technique برای کم کردن تعداد تصاویر png استفاده کردیم .

حتما راجع به CSS image replacement و CSS sprites technique مطالعه کنید 🙂

#volume {
    left: 10px;
    opacity: 0.8;
    position: absolute;
    top: 100px;
}
    #volume a {
    	background: transparent url(../img/icons.png) no-repeat;
    	display: block;
    	height: 30px;
    	text-indent: -9999px;
    	width: 30px;
    }
    #volume.all a {
        background-position: 0 0;
    }
    #volume.some a {
        background-position: -30px 0;
    }
    #volume.none a {
        background-position: -60px 0;
    }

بعضی از استایل های پلاگین Vegas رو که داریم استفاده می کنیم تغییر میدیم.

.vegas-loading {
    top: auto;
    bottom: 40px;
    left: 40px;
}
.vegas-overlay {
    background-image: url(../js/vegas/overlays/02.png);
}

و البته یه مقدار هم استایل های پلاگین jScrollPane رو تغییر می دیم که بیشتر به سبک اسلاید شو ما بخوره.

.jspHorizontalBar {
    height: 5px;
}
    .jspHorizontalBar .jspTrack {
         background: #333;
    }
    .jspHorizontalBar .jspDrag {
         background: #666;
         cursor: ew-resize;
    }
#thumbnails:hover .jspHorizontalBar .jspDrag {
    background: #F30;
}

شروع به نوشتن JavaScript می کنیم.

رسیدیم به بخش اصلی، جاوا اسکریپت . با کش کردن بعضی از المان ها شروع می کنیم. آرایه ایی برای تصاویر درست کردیم که تصاویر ، تیتر و موقعیت تراز عمودیشون رو ذخیره خواهیم کرد :

var pictures = [],
    $pointer = $( '#pointer' ),
    $thumbnails = $( '#thumbnails' ),
    $title = $( '#title' ),
    $pause = $( '#pause' ),
    $flash = $( '#flash' ),
    $volume = $( '#volume' );

با استفاده از پلاگین Buzz صداهایی که برای اسلاید شو مون انتخاب کردیم رو تعریف میکنیم . میدونیم که اکثر مرورگرها HTML5 audio رو ساپورت میکنن. فایل های صوتی بدون نیاز به نصب پلاگین Flash اجرا می شوند، اما هیچ توافقی بر سر فرمت فایل های صوتی در مرورگر ها نیست . MP3 میتونست گزینه ی مناسبی باشه که البته Firefox ساپورت نمیکنه . پس باید فابل های صوتی مون رو به فرمت های مختلفی تبدیل کنیم . بهترین انتخاب فرمت OGG و MP3 می تونه باشه .برای تبدیل فایل های صوتی از سایت Online convertor استفاده میکنیم.

اگه مرورگری HTML5 audio رو ساپورت نکنه Buzz به راحتی بی خیال میشه و ما آیکون کنترل صدا رو نمایش نمی دیم.

صدای ترافیک شهر به محض اینکه لود بشه شروع میشه و تکرار میشه.

buzz.defaults.formats = [ 'ogg', 'mp3' ];

var trafficSound = new buzz.sound( 'sounds/traffic' ),
    clickSound = new buzz.sound( 'sounds/click' ),
    focusSound = new buzz.sound( 'sounds/focus' ),
    rewindSound = new buzz.sound( 'sounds/rewind' ),
    cameraSounds = new buzz.group( clickSound, focusSound, rewindSound );

if ( !buzz.isSupported() ) {
    $volume.hide();
}
trafficSound.loop().play().fadeIn( 5000 );

کار کردن باهاش خیلی آسونه 😉

عرض بخش تصاویر بند انگشتی رو باید مشخص کنیم تا اطمینان داشته باشیم داخل یک سطر میمونن .

$thumbnails.find( 'ul' ).width( function() {
    var totalWidth = 0;
    $( this ).find( 'li' ).each( function() {
        totalWidth += $( this ).outerWidth( true );
    });
    return totalWidth;
});

پلاگین jScrollPane رو برای اسکرول افقی راه اندازی میکنیم . این پلاگین اجازه میده به آسونی با API  ی که داره کار کنیم . میخوایم از این استفاده کنیم تا اسکرول مناسبی بعد از تغییر اندازه ی صفحه ی مرورگر نیز تولید کنیم.

$thumbnails.jScrollPane();

var jScrollPaneApi = $thumbnails.data( 'jsp' );

$( window ).bind( 'resize', function() {
    jScrollPaneApi.reinitialise();
});

پلاگین Vegas رو هم راه اندازی می کنیم. آرایه ایی که برای تصاویر ایجاد کرده بودیم رو با دریافت اطلاعات از لینک هایی که در HTML مون برای thumbnail ها معرفی کرده بودیم ، پر می کنیم و به vegas منتقل میکنیم. بین هر تصویر گالری اسلاید شو 4 ثانیه مکث مشخص کردیم :

$thumbnails.find( 'a' ).each( function() {
    pictures.push({
        src: $( this ).attr( 'href' ),
        title: $( this ).find( 'img' ).attr( 'title' ),
        valign: $( this ).find( 'img' ).data( 'valign' )
    });
})

$.vegas( 'slideshow', {
    backgrounds: pictures,
    delay: 4000
 })( 'overlay' );

Vegas رویداد های مختلفی رو میتونه هندل کنه . رویدادی که ما اینجا نیاز داریم ، زمانی که یک تصویر در اسلاید شو به نمایش در میاد یا به اصطلاح لود میشه . با توجه به تصویری که لود میشه میتونیم متوجه بشیم کدوم عکس در حال نمایش هست و البته صدایی رو پخش می کنیم .

$( 'body' ).bind( 'vegasload', function( e, img ) {
    var src = $( img ).attr( 'src' ),
        idx = $( 'a[href="' + src + '"]' ).parent( 'li' ).index();
    focusSound.play();

    // ...
});

تیترها رو با افکت fade-out/fade-in نمایش خواهیم داد.

    $title.fadeOut( function() {
        $( this ).find( 'h1' ).text( pictures[ idx ].title );
        $( this ).fadeIn();
    });

و افکت فلش دوربین عکاسی :

    $flash.show().fadeOut( 1000 );

مشخص کننده ی تصویری که در حال نمایش است روی تصاویر بند انگشتی حرکت میکند . و اگر خارج از تصویر قرارگیرد با استفاده از jScrollPane موقعیت اسکرول رو تغییر می دهیم.

    var pointerPosition = $thumbnails.find( 'li' ).eq( idx ).position().left;

    $pointer.animate({
        left: pointerPosition
    }, 500, 'easeInOutBack' );

    if ( ( pointerPosition > $thumbnails.width()
        || pointerPosition < jScrollPaneApi.getContentPositionX() )
        && !$thumbnails.is( ':hover' ) ) {
            jScrollPaneApi.scrollToX( pointerPosition, true );
    }

    $pointer.click( function() {
        $thumbnails.find( 'a' ).eq( idx ).click()
    });

به محض کلیک بر روی آیکون کنترل صدا کلاسی که به آن داده شده را تغییر می دهیم تا با کمک از این وضعیت صدای در حال پخش رو بررسی کنیم .

$volume.click( function() {
    if ( $( this ).hasClass( 'all' ) ) {
        cameraSounds.unmute();
        trafficSound.mute();

        $( this ).removeClass( 'all' ).addClass( 'some' );
    } else if ( $( this ).hasClass( 'some' ) ) {
        cameraSounds.mute();
        trafficSound.mute();

        $( this ).removeClass( 'some' ).addClass( 'none' );
    } else {
        cameraSounds.unmute();
        trafficSound.unmute();

        $( this ).removeClass( 'none' ).addClass( 'all' );
    }
    return false;
});

تقریبا کار گالری اسلاید شو ما به پایان رسید. حالا میخوایم با کلیک شدن روی تصاویر بند انگشتی ، تصویر اسلاید شو رو تغییر بدیم و هم چنین گالری رو در وضعیت paused یا ایست قرار بدیم. مشخص کننده روی این تصویر بند انگشتی قرار بگیره . با این اوضاف میتونیم اسلاید شو رو از جایی که هستیم ادامه بدیم .

همه ی المان های صفحه ناپیدا میشن و فقط تصویر اسلاید شو و کلمه ی paused :

$thumbnails.find( 'a' ).click( function() {
    $pause.show();
    $pointer.hide();

    $volume.animate( { top: '20px' });
    $thumbnails.animate( { top: '-90px' });
    $title.animate( { bottom: '-90px' });    

    var idx = $( this ).parent( 'li' ).index();
    $.vegas( 'slideshow', { step: idx } )( 'pause' );

    rewindSound.play();

    return false;
});

کلیک روی paused گالری اسلاید شو رو به حالت قبل بر میگردونه.

$pause.click( function() {
    $pause.hide();
    $pointer.show();

    $volume.animate( { top:'100px' });
    $title.animate( { bottom:'0px' });
    $thumbnails.animate( { top:'0px' });

    $.vegas( 'slideshow' );

    clickSound.play();

    return false;
});

امیدواریم از آموزش طراحی گالری اسلاید شو تمام صفحه ی صوتی لذت برده باشید 🙂

میتونید کامنت بذارید و سوالاتتون رو بپرسید 😉