Showing posts with label Slideshow. Show all posts
Showing posts with label Slideshow. Show all posts

Plugin Feed Rotator untuk Blogger

Image of Blogger Feed Rotator plugin demo

Plugin ini pada dasarnya merupakan perpaduan antara Basic JQuery Image Rotator dengan yang kemudian Saya jadikan sebagai semacam slideshow dengan konten yang akan diperbaharui secara otomatis berdasarkan posting yang sudah terbit. Saya memutuskan untuk membuat ini karena ada beberapa orang yang menanyakan melalui email mengenai bagaimana cara memadukan plugin Image Rotator dengan JSON Blogger.

Plugin JQuery Image Rotator ini juga sudah dimodifikasi hampir secara keseluruhan, khusus untuk diaplikasikan pada widget ini. Beberapa hal yang Saya tambahkan diantaranya adalah navigasi, efek animasi kontainer dan dukungan fungsi callback yang dapat dijalankan pada sesi-sesi tertentu.

Implementasi Dasar

Berikut ini adalah contoh implementasi paling mendasar yang bisa Anda lakukan untuk mengaktifkan plugin:

<link rel="stylesheet" type="text/css" href="http://blogger-json-experiment.googlecode.com/svn/resources/blogger-feed-rotator-plugin/default-style.min.css"/>
<div id="slider-rotator" class="slider-rotator loading"></div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="http://blogger-json-experiment.googlecode.com/svn/resources/blogger-feed-rotator-plugin/blogger-feed-rotator.min.js"></script>
<script type="text/javascript">
makeSlider({
url: "http://nama_blog.blogspot.com" // URL blog Anda
});
</script>

Susun file CSS dan plugin Blogger Feed Rotator sesuai dengan urutan yang Saya perlihatkan di atas. Tambahkan juga elemen HTML yang berfungsi untuk menampilkan slideshow sebelum plugin. Setelah itu aktifkan fungsi makeSlider() dengan parameter berupa objek tunggal url yang diisi dengan URL blog Anda. Salin dan tempelkan di dalam formulir elemen halaman HTML/JavaScript. Dengan ini maka Anda sudah bisa menampilkan sebuah slideshow sederhana seperti yang terlihat pada halaman demo di atas.

Daftar Opsi Konfigurasi Dasar

Konfigurasi dasar Saya batasi pada opsi-opsi yang berhubungan dengan pengaturan posting:

{
url: "http://www.dte.web.id", // Your blog URL
numPost: 5, // Number of posts to display
newTabLink: false, // `true` to automatically open link in new window tab
labelName: null, // Show posts in specific label. Specify name of the post label, or `null` to show all posts
showDetail: true, // `false` to hide the blog post title & description
summaryLength: 60, // Length of post summary
titleLength: "auto", // Length of the post title. "auto" by default, or specify number to crop the post title characters and truncate it with `...`
showThumb: true, // `false` to hide the post thumbnails
thumbWidth: 250, // Width of post thumbnail in pixels
squareThumb: true, // Thumbnail mode: Square mode or use the scaled thumbnail with original width and height ratio
noThumb: "images/grey.png", // Fallback thumbnail for no picture posts
showNav: true, // `true` to show both next/prev navigation and navigation number, "next/prev" to show next/prev navigation only, "number" to show navigation number only, `false` to hide the navigation
navText: {
prev: "&lt;", // Label of the previous navigation
next: "&gt;" // Label of the next navigation
},
containerId: "slider-rotator" // HTML element ID that is used to display the slideshow/rotator
}
OpsiKeterangan
urlIsi dengan URL halaman muka blog Anda
numPostDigunakan untuk menentukan jumlah posting yang akan ditampilkan
newTabLinkUbah nilainya menjadi true untuk membuat tautan-tautan di dalam widget ini terbuka di jendela/tab baru saat diklik
labelNameDigunakan untuk menampilkan daftar posting dengan label/kategori tertentu. Nilai null berarti menampilkan semua posting terbaru. Ganti nilainya menjadi nama label untuk menampilkan posting dengan label tertentu. Misalnya labelName:"Foto" untuk menampilkan semua posting yang memiliki label Foto - Contoh
showDetailUbah nilainya menjadi false untuk menyembunyikan judul dan ringkasan posting. Berguna untuk membuat slideshow foto/gambar tanpa tulisan - Contoh
summaryLengthDigunakan untuk membatasi panjang ringkasan posting. Akhir pemotongan ringkasan posting akan digantikan dengan simbol “…”
titleLengthDigunakan untuk membatasi panjang judul posting. Secara normal bernilai "auto". Ubah nilainya dengan angka tertentu untuk memotong panjang judul jika Anda merasa judul posting yang tampil terlalu panjang. Akhir pemotongan judul posting akan digantikan dengan simbol “…”
showThumbUbah nilainya menjadi false untuk menyembunyikan gambar posting. Berguna untuk membuat slideshow teks - Contoh
thumbWidthDigunakan untuk menentukan lebar thumbnail posting dan juga sekaligus menentukan lebar slideshow
squareThumbOpsi untuk memilih mode thumbnail. true untuk menampilkan gambar dengan resolusi /sN-c, false untuk menampilkan gambar dengan resolusi /sN
noThumbIsi dengan URL gambar. Gambar ini akan digunakan sebagai cadangan jika posting yang tampil tidak memiliki gambar
showNavOpsi untuk menampilkan atau menyembunyikan navigasi slideshow. Ubah nilainya menjadi false untuk menyembunyikan navigasi. "number" untuk menampilkan navigasi angka saja. "next/prev" untuk menampilkan navigasi next/prev saja. true untuk menampilkan keduanya
navTextOpsi untuk menentukan label navigasi Next dan Previous
containerIdDigunakan untuk menentukan di mana slideshow akan ditampilkan. Isi dengan ID elemen HTML. Dan jangan lupa untuk menyertakan elemen HTML tersebut sebelum eksekusi plugin.

Pengaturan Animasi

Pengaturan animasi Saya batasi pada opsi-opsi yang berhubungan dengan animasi plugin:

{
interval: 6000, // Slideshow interval
speed: 1000, // Slideshow animation speed
hoverPause: true, // `false` to make the slideshow/rotator keep running on mouse-over
crossFade: false, // `true` if you want to make the slide change effect occurs simultaneously between disappearance and appearance
autoHeight: false, // Animate the rotator to adjust the height of the displayed item
autoSlide: true // `false` to run the slideshow manually (with navigation)
}
OpsiKeterangan
intervalDigunakan untuk menentukan rentang waktu perpindahan setiap item slide dalam satuan milidetik
speedDigunakan untuk menentukan kecepatan animasi dalam satuan milidetik
hoverPauseJika bernilai true maka slideshow akan berhenti bergerak saat pointer mouse berada di atasnya
crossFadeDigunakan untuk menentukan apakah efek penghilangan dan pemunculan slide dilakukan secara bergantian atau bersamaan dalam waktu yang sama tanpa ada jeda
autoHeightJika bernilai true, maka tinggi slideshow akan menyesuaikan diri berdasarkan tinggi item slide yang tampil dengan efek animasi - Contoh
autoSlideUbah nilainya menjadi false untuk membuat slideshow berjalan secara manual melalui aksi klik navigasi

Konfigurasi Lanjutan

Bagian ini Saya khususkan untuk menjelaskan fungsi-fungsi callback dan implementasi lanjutan, khususnya dalam hal modifikasi:

{
onInit: function() {}, // Callback function that will be executed when slideshow is starting
onHide: function(index) {}, // Callback function that will be executed when slideshow is start hiding the slide item
onShow: function(index) {} // Callback function that will be executed after the slideshow showing the slide item
}

onInit

Fungsi ini akan dijalankan pada saat pertama kali slideshow terbentuk. Saat slideshow tampil, maka fungsi ini akan langsung dieksekusi. Contoh penerapan:

makeSlider({
url: "http://nama_blog.blogspot.com",
onInit: function() {
alert('Slideshow ready!');
}
});

Kode di atas akan menampilkan pesan “Slideshow ready!” segera setelah slideshow tampil.

onHide

Fungsi ini akan dijalankan setiap kali item slide mulai menghilang. Saat item slide menghilang, maka fungsi ini akan tereksekusi. Contoh penerapan:

makeSlider({
url: "http://nama_blog.blogspot.com",
onHide: function() {
alert('Mengganti slide...');
}
});

Kode di atas akan menampilkan pesan “Mengganti slide...” setiap kali slide mulai berganti.

onShow

Fungsi ini akan dijalankan setiap kali item slide tampil. Saat item slide tampil, maka fungsi ini akan tereksekusi. Contoh penerapan:

makeSlider({
url: "http://nama_blog.blogspot.com",
onShow: function(index) {
alert('Slide ke ' + index + ' berhasil tampil.');
}
});

Kode di atas akan menampilkan pesan “Slide ke {nomor urut slide yang tampil} berhasil tampil.” setiap kali slide ditampilkan.

Parameter `index`

Parameter index hanya berlaku untuk onHide dan onShow. Parameter ini akan menampilkan indeks slide yang aktif:

makeSlider({
url: "http://nama_blog.blogspot.com",
onInit: function() {
console.log('Slideshow dimulai...');
},
onHide: function(index) {
console.log('Menyembunyikan slide ke ' + index);
},
onShow: function(index) {
console.log('Menampilkan slide ke ' + index);
}
});

Beberapa Contoh Modifikasi Dasar

Mengubah Tampilan

Dengan mengubah ukuran lebar pada gambar dan slideshow, ukuran tinggi pada slideshow dan mengubah tampilan deskripsi/detail posting sebagai caption, maka Anda bisa semakin memperkuat status plugin ini sebagai “slideshow”:

CSS

<link rel="stylesheet" type="text/css" href="http://blogger-json-experiment.googlecode.com/svn/resources/blogger-feed-rotator-plugin/default-style.min.css"/>
<style type="text/css">

/* Custom CSS... */

.slider-rotator {
width:600px;
height:240px;
padding:0 0;
background-color:white;
font:italic normal 12px/1.4 Georgia,Serif;
color:white;
border:1px solid black;
}

.slider-rotator .slider-item {
background-color:white;
height:240px; /* Same with `.slider-rotator` height */
padding:0 0;
}

.slider-rotator h4 {margin-top:0}
.slider-rotator p {margin:2px 0 0}

/* Slider details as caption */
.slider-rotator .detail-wrapper {
position:absolute;
top:auto;
right:0;
bottom:0;
left:0;
background-color:black;
background-color:rgba(0,0,0,.9);
padding:.5em 1em;
z-index:4;
}

</style>

JavaScript

makeSlider({
url: "http://nama_blog.blogspot.com", // Your blog URL
thumbWidth: 600 // Thumbnail width in pixels (same with slideshow width)
});

Memanfaatkan Fungsi Callback untuk Menganimasikan Caption

Dengan memanfaatkan parameter index pada onHide dan onShow, Anda bisa memberikan efek animasi pada caption slide yang aktif setiap kali slide berganti:

makeSlider({
url: "http://nama_blog.blogspot.com", // Your blog URL
thumbWidth: 600, // Thumbnail width in pixels (same with slideshow width)
containerId: "slider-rotator",
// Hide all captions on initiation...
onInit: function() {
$('#' + this.containerId).find('.detail-wrapper').hide();
},
// Hide the caption with `.slideUp()` effect when the slide item hides
onHide: function() {
$('#' + this.containerId).find('.detail-wrapper').slideUp();
},
// Show the caption with `.slideDown()` effect when the slide item appears
onShow: function(index) {
$('#' + this.containerId).children().eq(index).find('.detail-wrapper').slideDown();
}
});

Menampilkan Beberapa Slideshow Sekaligus

Karena eksekusi plugin ini dilakukan di luar, maka ini memungkinkan Anda untuk menampilkan beberapa slideshow sekaligus dalam satu halaman. Pertama-tama buatlah beberapa elemen HTML yang dibutuhkan untuk memuat slideshow:

<div id="container-1" class="slider-rotator loading"></div>
<div id="container-2" class="slider-rotator loading"></div>
<div id="container-3" class="slider-rotator loading"></div>

Kemudian jalankan fungsi makeSlider() sebanyak jumlah kontainer yang dibuat. Tentukan juga konfigurasi containerId yang berbeda-beda berdasarkan ID kontainer:

makeSlider({
url: "http://nama_blog-1.blogspot.com",
containerId: "container-1"
});
makeSlider({
url: "http://nama_blog-2.blogspot.com",
containerId: "container-2"
});
makeSlider({
url: "http://nama_blog-3.blogspot.com",
containerId: "container-3"
});

Mengatur Plugin dan Melihat Demo Secara Langsung

Saya sudah menyertakan halaman konfigurasi plugin yang bisa Anda gunakan untuk melakukan pengaturan dan melihat hasilnya secara langsung di sini:

Daftar Contoh

  1. Demo 1: Basic
  2. Demo 2: Show Posts under Category “Widget”
  3. Demo 3: About Thumbnails
  4. Demo 4: Thumbnail Only
  5. Demo 5: Text Only
  6. Demo 6: Multiple Feed Loading
  7. Demo 7: Casual Slideshow
  8. Demo 8: Example Callback Function to Animate the Slideshow Caption (1)
  9. Demo 9: Example Callback Function to Animate the Slideshow Caption (2)

Membangun Layout Paralaks dengan JQuery

JQuery Parallax layout

Membuat layout paralaks, jika Anda masih kesulitan untuk memahami bagaimana cara kerja dan cara membuatnya, di sini Saya akan menjelaskannya dengan rinci mengenai bagaimana layout tersebut tercipta. Pada dasarnya, sebuah layout paralaks hanyalah elemen HTML dengan beberapa tumpukan layer di dalamnya, dimana setiap layer tersebut akan dianimasikan posisinya dengan kecepatan yang sama namun dengan jarak yang berbeda untuk menciptakan efek tiga dimensi saat layer-layer tersebut bergerak.

Membuat Latar Paralaks

Kita mulai dengan elemen HTML seperti ini:

<div id="parallax-wrapper" class="parallax-wrapper">
<div class="layer layer-1"></div>
<div class="layer layer-2"></div>
<div class="layer layer-3"></div>
...
...
</div>

Saya membuat sebuah elemen HTML sebagai kontainer dengan beberapa layer di dalamnya. Elemen utamanya adalah #parallax-wrapper. Elemen ini berfungsi sebagai wadah dari semua elemen paralaks di dalamnya. Sedangkan elemen-elemen .layer nantinya akan kita gunakan sebagai penampil latar. Kita akan memposisikan layer-layer tersebut menjadi bertumpukan layaknya tumpukan kaca. Jadi kita memerlukan ini untuk mengatur dimensi paralaks yang kita buat:

.parallax-wrapper {
border:1px solid black;
height:200px; /* Tentukan tinggi area paralaks, ukuran lebar tidak begitu penting */
position:relative; /* Penting! Posisi absolut pada elemen induk */
overflow:hidden;
}

/* Buat semua layer paralaks sebagai elemen absolut,
sehingga tampilannya akan bertumpuk satu sama lainnya */
.parallax-wrapper .layer {
position:absolute;
top:0;
right:0;
bottom:0;
left:0;
/* set beberapa pengaturan latar di sini,
sebelum kita mendefinisikan latar gambar secara sepihak
pada masing-masing layer */
background-position:0 0;
background-color:transparent;
background-repeat:repeat-x;
}

Setelah itu, gambar-gambar bisa diterapkan pada masing-masing layer:

.parallax-wrapper .layer-1 {background-image:url('img/parallax-bg-1.png')}
.parallax-wrapper .layer-2 {background-image:url('img/parallax-bg-2.png')}
.parallax-wrapper .layer-3 {background-image:url('img/parallax-bg-3.png')}

Navigasi Paralaks

Navigasi ini digunakan untuk menggerakkan latar paralaks —dan konten di dalamnya tentunya, agar paralaks tidak hanya berfungsi sebagai hiasan. Navigasi terdiri dari elemen <span> dengan beberapa tautan di dalamnya. Anda bisa membuatnya menggunakan elemen apa saja, tapi di sini Saya mencoba untuk membuatnya seminimalis mungkin:

<span id="parallax-navigation" class="parallax-navigation">
<a href="#1">1</a>
<a href="#2">2</a>
<a href="#3">3</a>
<a href="#4">4</a>
...
...
</span>

CSS untuk navigasinya:

.parallax-navigation {
display:block;
height:30px;
line-height:30px;
position:relative;
text-align:right;
font-size:11px;
font-weight:bold;
}

.parallax-navigation a {
text-decoration:none;
color:black;
background-color:#eee;
padding:5px 10px;
}

/* set latar dan warna yang berbeda untuk item navigasi yang sedang aktif */
.parallax-navigation a.active {
background-color:#529834;
color:white;
}

Selesai sampai di sini, sekarang kita akan mengerjakan fungsi dasar untuk menggerakkan layer:

Efek Paralaks

Beberapa mungkin akan membuat efek paralaks dengan cara menganimasikan properti left pada elemen relatif untuk menggerakkan elemen ke kiri atau ke kanan. Tapi kekurangannya adalah, mengubah jarak left terlalu jauh akan membuat posisi layer berubah dan pada akhirnya akan menghilang dari pandangan jika jaraknya sudah terlalu jauh. Di sini Saya lebih menyarankan untuk menganimasikan posisi latar dibandingkan posisi layer itu sendiri, sehingga layer tidak akan bergerak, hanya latarnya saja yang bergerak.

Namun tidak mendukung properti animasi background-position dengan baik, jadi kita membutuhkan sebuah plugin untuk itu. Anda akan menemukan begitu banyak plugin JQuery yang berfungsi untuk menganimasikan posisi latar jika Anda mencarinya, dan Saya memilih untuk menggunakan plugin animasi posisi latar dari Keith Wood. Saya tidak kenal dengan orang itu, tapi pluginnya bagus ⇒ http://keith-wood.name/backgroundPos.html

<!-- Muat JQuery di awal -->
<script type="text/javascript" src="js/jquery.js"></script>
<!-- Sertakan plugin JQuery BackgroundPos -->
<script type="text/javascript" src="js/jquery.backgroundpos.min.js"></script>
<script type="text/javascript">
// Pekerjaan kita di sini...
</script>

Definisikan beberapa variabel untuk mempermudah kita dalam menyeleksi elemen dan sekaligus juga memperbaiki performa. Seperti biasa:

var $parallax = $('#parallax-wrapper'),
$layer = $parallax.find('.layer'),
$nav = $('#parallax-navigation');

Setelah itu kita kumpulkan semua item navigasi dan layer di dalam paralaks. Kita akan cenderung menggunakan JQuery .each() di sini, karena ini adalah cara yang paling mudah untuk mendapatkan indeks/urutan masing-masing elemen. Kita akan menganimasikan elemen dengan parameter dari indeks elemen (urutan elemen):

$nav.find('a').each(function() {
// Saat pengguna mengeklik item navigasi...
$(this).on("click", function() {
var step = $(this).index(); // Dapatkan indeks dari setiap item navigasi
// Kumpulkan layer...
$layer.each(function() {
// Definisikan jarak animasi latar pada setiap layer berdasarkan indeksnya
var distance = ($(this).index()+1) * 200; // Kalikan dengan 200
});
return false;
});
}).first().addClass('active'); // Tambahkan kelas `active` pada item navigasi pertama sebagai awalan

Setelah itu, buat fungsi untuk menambah dan melepas kelas active pada setiap item navigasi. Dulu Saya sudah pernah menuliskan kodenya di sini

$nav.find('a').each(function() {
// Saat pengguna mengeklik item navigasi...
$(this).on("click", function() {
var step = $(this).index(); // Dapatkan indeks dari setiap item navigasi
$nav.find('.active').removeClass('active'); // Singkirkan kelas `active` pada item navigasi
$(this).addClass('active'); // Tambahkan kelas `active` pada item navigasi yang diklik
// Kumpulkan layer...
$layer.each(function() {
// Definisikan jarak animasi latar pada setiap layer berdasarkan indeksnya
var distance = ($(this).index()+1) * 200; // Kalikan dengan 200
});
return false;
});
}).first().addClass('active'); // Tambahkan kelas `active` pada item navigasi pertama sebagai awalan

Animasikan posisi latar pada masing-masing layer dengan parameter berupa urutan layer, sehingga jarak perubahan posisi akan berbeda-beda pada masing-masing layer (lebih tepatnya: jarak animasi akan meningkat berdasarkan urutan layer):

$nav.find('a').each(function() {
// Saat pengguna mengeklik item navigasi...
$(this).on("click", function() {
var step = $(this).index(); // Dapatkan indeks dari setiap item navigasi
$nav.find('.active').removeClass('active'); // Singkirkan kelas `active` pada item navigasi
$(this).addClass('active'); // Tambahkan kelas `active` pada item navigasi yang diklik
// Kumpulkan layer...
$layer.each(function() {
// Definisikan jarak animasi latar pada setiap layer berdasarkan indeksnya
var distance = ($(this).index()+1) * 200; // Kalikan dengan 200
// Animasikan posisi latar
$(this).stop().animate({backgroundPosition: '-' + (step*distance) + 'px 0px'}, 1500);
});
return false;
});
}).first().addClass('active'); // Tambahkan kelas `active` pada item navigasi pertama sebagai awalan

Dan beginilah hasil akhir sementara kita. Baru latarnya saja yang dianimasikan, belum ada konten:

Langkah Akhir: Menambahkan Konten

Animasi paralaks sudah berhasil dibuat, sekarang tinggal membuat konten paralaks saja. Setiap konten merupakan item yang bisa Anda isi dengan tulisan dan/atau gambar layaknya slideshow:

HTML

<div id="parallax-wrapper" class="parallax-wrapper">
<div class="layer layer-1"></div>
<div class="layer layer-2"></div>
<div class="layer layer-3"></div>
<div class="box-item-wrapper">
<div class="box-item"> ... </div>
<div class="box-item"> ... </div>
<div class="box-item"> ... </div>
<div class="box-item"> ... </div>
...
...
</div>
</div>

CSS

.box-item-wrapper {
position:relative;
overflow:hidden;
}

.box-item-wrapper .box-item {
float:left; /* posisikan `.box-item` sebagai layout mendatar */
width:100%;
margin:7em 0;
padding:1.5em 2em;
}

Fungsi selanjutnya ditujukan untuk mengeset ukuran kontainer item dan lebar item, serta menganimasikan kontainer item menuju ke kiri dengan jarak tertentu berdasarkan indeks item navigasi. Pertama-tama kita atur ukuran lebar .box-item-wrapper dan .box-item:

var $window = $(window),
$wrap = $parallax.find('.box-item-wrapper'),
width, totalWidth; // Variabel kosong

$window.on("resize", function() {

width = $parallax.width(); // Mendapatkan lebar `#parallax-wrapper`
totalWidth = width * $wrap.find('.box-item').length; // Lebar total = lebar `#parallax-wrapper` dikalikan jumlah `.box-item`

// Set lebar `.box-item-wrapper` selebar `totalWidth`
$wrap.width(totalWidth)
// Set lebar `.box-item` selebar `#parallax-wrapper`
.find('.box-item').width(width);

}).trigger("resize");

Saya menuliskan variabel width dan totalWidth kosong, kemudian menyatakan nilainya di dalam $window.on("resize", function() {}) agar lebar elemen bisa diperbaharui setiap kali ukuran layar diubah. Saya juga menyatakan lebar elemen di dalam event tersebut.

Terakhir, gabungkan animasi properti left di dalam event klik item navigasi untuk menganimasikan posisi .box-item-wrapper:

$nav.find('a').each(function() {
// Saat pengguna mengeklik item navigasi...
$(this).on("click", function() {
var step = $(this).index(); // Dapatkan indeks dari setiap item navigasi
$nav.find('.active').removeClass('active'); // Singkirkan kelas `active` pada item navigasi
$(this).addClass('active'); // Tambahkan kelas `active` pada item navigasi yang diklik
// Kumpulkan layer...
$layer.each(function() {
// Definisikan jarak animasi latar pada setiap layer berdasarkan indeksnya
var distance = ($(this).index()+1) * 200; // Kalikan dengan 200
// Animasikan posisi latar
$(this).stop().animate({backgroundPosition: '-' + (step*distance) + 'px 0px'}, 1500);
});
// Animasikan `.box-item-wrapper` ke kiri untuk menggerakkan `.box-item`
$wrap.stop().animate({'left': -(step*width)}, 1500);
return false;
});
}).first().addClass('active'); // Tambahkan kelas `active` pada item navigasi pertama sebagai awalan

Produk Final

HTML

<div id="parallax-wrapper" class="parallax-wrapper">
<div class="layer layer-1"></div>
<div class="layer layer-2"></div>
<div class="layer layer-3"></div>
<div class="box-item-wrapper">
<div class="box-item"> ... </div>
<div class="box-item"> ... </div>
<div class="box-item"> ... </div>
<div class="box-item"> ... </div>
</div>
</div>

<span id="parallax-navigation" class="parallax-navigation">
<a href="#1">1</a>
<a href="#2">2</a>
<a href="#3">3</a>
<a href="#4">4</a>
</span>

CSS

.parallax-wrapper {
border:1px solid black;
height:200px;
position:relative;
overflow:hidden;
}

.parallax-wrapper .layer {
position:absolute;
top:0;
right:0;
bottom:0;
left:0;
background-position:0 0;
background-color:transparent;
background-repeat:repeat-x;
}

.parallax-wrapper .layer-1 {background-image:url('img/parallax-bg-1.png')}
.parallax-wrapper .layer-2 {background-image:url('img/parallax-bg-2.png')}
.parallax-wrapper .layer-3 {background-image:url('img/parallax-bg-3.png')}

.box-item-wrapper {
position:relative;
overflow:hidden;
}

.box-item-wrapper .box-item {
float:left;
width:100%;
margin:5em 0 0;
padding:1.5em 2em;
}

.parallax-navigation {
display:block;
height:30px;
line-height:30px;
position:relative;
text-align:right;
font-size:11px;
font-weight:bold;
}

.parallax-navigation a {
text-decoration:none;
color:black;
background-color:#eee;
padding:5px 10px;
}

.parallax-navigation a.active {
background-color:#529834;
color:white;
}

JQuery

(function($) {

// Cache some elements
var $window = $(window),
$parallax = $('#parallax-wrapper'),
$layer = $parallax.find('.layer'),
$wrap = $parallax.find('.box-item-wrapper'),
$nav = $('#parallax-navigation'), width, totalWidth;

// Set the parallax content & item width in window resize ...
// ... so we can be sure that when the window is resized, the size of the elements will be updated too
$window.on("resize", function() {
width = $parallax.width(); // get the parallax wrapper width
totalWidth = width * $wrap.find('.box-item').length; // total width = (parallax wrapper width * box item length)
$wrap.width(totalWidth).find('.box-item').outerWidth(width);
}).trigger("resize");

// Collect all navigation item inside parallax navigation, then get their index to set the animation distance
$nav.find('a').each(function() {
// when user click on the navigation item
$(this).on("click", function() {
var step = $(this).index(); // get the index (0, 1, 2, 3, ...)
$nav.find('.active').removeClass('active'); // remove the active class from navigation item
$(this).addClass('active'); // add the active class to the clicked navigation item
$layer.each(function() {
// set the background-position per-animation distance of each layer ...
// ... based on its index
var distance = ($(this).index()+1) * 200; // multiplied by 200
$(this).stop().animate({backgroundPosition: '-' + (step*distance) + 'px 0px'}, 1500); // (jQuery background position plugin required)
});
// also, animate the `.box-item-wrapper` to the left to move the `.box-item`
$wrap.stop().animate({'left': -(step*width)}, 1500);
return false;
});
}).first().addClass('active'); // add active class to the first navigation item on initiation

})(jQuery);

Demo

JQuery Carousel

Carousel

HTML

<div class="carousel" id="carousel">
<div class="carousel-inner">
<img src="img/1.jjpg" alt="">
<img src="img/2.jjpg" alt="">
<img src="img/3.jjpg" alt="">
<img src="img/4.jjpg" alt="">
</div>
</div>
<nav class="carousel-nav" id="carousel-nav">
<button data-direction="prev">Prev</button>
<button data-direction="next">Next</button>
</nav>

CSS

.carousel {
width:400px;
overflow:auto;
margin:0 auto .7em;
}

.carousel,
.carousel-inner {
height:100px;
}

.carousel img {
width:100px;
height:100px;
background-color:#ccc;
display:block;
float:left;
margin:0 5px;
}

.carousel-nav {
text-align:center;
}

.carousel-nav button {
cursor:pointer;
}

JQuery

(function($) {
var $carousel = $('#carousel'),
$container = $carousel.find('.carousel-inner'),
$nav = $('#carousel-nav'),
$img = $container.find('img'),
totalWidth = ($img.outerWidth()+parseInt($img.css('margin-left'),10)+parseInt($img.css('margin-right'),10))*$img.length;
$carousel.css('overflow', 'hidden'); // Singkirkan scroll bar jika JavaScript aktif
$container.css('width', totalWidth); // Set lebar `.carousel-inner` selebar => [jumlah gambar + lebar gambar + margin kiri dan kanan gambar]
$nav.find('button').on("click", function() {
// Animasikan properti `scrollLeft` ke kiri/ke kanan,
// berdasarkan nilai atribut `data-direction` pada tombol yang diklik
var dir = $(this).data('direction');
$carousel.stop().animate({
scrollLeft: (dir == "next") ? "+=100px" : "-=100px"
}, 200);
});
})(jQuery);

Demo

Thumbnail Scroller

Pembaharuan: 25 September 2013

JQuery Thumbnail Scroller
Thumbnail scroller.

HTML

<div id="thumbnail-scroller">
<div class="container">
<figure>
<a href="#" title="Title for Caption 1">
<img alt="" src="img/thumbnail-1.jpg">
</a>
</figure>
<figure>
<a href="#" title="Title for Caption 2">
<img alt="" src="img/thumbnail-2.jpg">
</a>
</figure>
<figure>
<a href="#" title="Title for Caption 3">
<img alt="" src="img/thumbnail-3.jpg">
</a>
</figure>
</div>
</div>

CSS

#thumbnail-scroller {
height:130px;
background-color:#810A0A;
border:10px solid #12559D;
position:relative;
margin:50px;
overflow:auto;
}

/* Create shadow effect on the left and right of container */
#thumbnail-scroller:before,
#thumbnail-scroller:after {
content:"";
display:block;
position:absolute;
top:0;
bottom:0;
left:-4px;
width:4px;
height:100%;
box-shadow:0 0 4px black;
z-index:10;
}

#thumbnail-scroller:after {
left:auto;
right:-4px;
}

#thumbnail-scroller .container {
position:absolute;
top:0;
left:0;
margin:5px 0 0 5px;
width:300%;
height:120px;
}

#thumbnail-scroller figure {
display:block;
background-color:white;
float:left;
width:100px;
height:120px;
margin:0 5px 0 0;
position:relative;
overflow:hidden;
}

#thumbnail-scroller figcaption {
display:block;
position:absolute;
right:0;
bottom:-50px;
left:0;
background-color:black;
font:italic normal 11px/normal Arial,Sans-Serif;
color:white;
padding:4px 10px;
text-align:left;
opacity:.8;
}

#thumbnail-scroller figure img {
display:block;
border:none;
margin:0;
}

JQuery

(function($) {

var $thumbnailScroller = $('#thumbnail-scroller'),
$container = $thumbnailScroller.find('.container'),
$item = $container.find('figure'),
item_length = $item.length,
item_width = $item.outerWidth(true),
total_width = item_width * item_length,
$window = $(window);

$thumbnailScroller.css('overflow', 'hidden');
$container.css('width', total_width);

// Auto caption builder & hover effect
$item.each(function() {
if ($(this).children().attr('title')) {
var cap = $(this).children().attr('title');
$(this).append('<figcaption>' + cap + '</figcaption>').children().removeAttr('title');
}
}).on("mouseenter mouseleave", function(e) {
$('figcaption', this).stop().animate({
bottom: e.type == "mouseenter" ? 0 : -50
}, 200);
});

$window.on("resize", function() {
var o_l = $thumbnailScroller.offset().left,
t_w = $thumbnailScroller.width(),
c_w = total_width;
$thumbnailScroller.off().on("mousemove", function(e) {
if ($(this).width() < $container.width()) {
$container.css('left', -((e.pageX - o_l) * ((c_w - t_w) / t_w)));
}
});
}).trigger("resize");

})(jQuery);

Template JSON - #c4612763938057608800

<div id="thumbnail-scroller"></div>
<script>
//<![CDATA[
var noimg = "img/no-image.png";
function showThumbs(json) {
var entry = json.feed.entry,
title, url, skeleton = '<div class="container">';
for (var i = 0; i < entry.length; i++) {
for (var j = 0; j < entry[i].link.length; j++) {
if (entry[i].link[j].rel == 'alternate') {
url = entry[i].link[j].href;
break;
}
}
title = entry[i].title.$t;
img = ("media$thumbnail" in entry[i]) ? entry[i].media$thumbnail.url.replace(/\/s72\-c/, "/s120-c") : noimg;
skeleton += '<figure><a href="' + url + '" title="' + title + '"><img src="' + img + '" alt="" /></a></figure>';
}
skeleton += '</div>';
document.getElementById('thumbnail-scroller').innerHTML = skeleton;
}
//]]>
</script>
<script src='http://nama_blog.blogspot.com/feeds/posts/summary?alt=json-in-script&amp;max-results=30&amp;callback=showThumbs'></script>

Tip untuk Thumbnail Scroller Berjamak

Gunakan JQuery .each() untuk menerapkan fungsi kepada setiap target yang diinginkan, sehingga penargetan variabel $thumbnailScroller menjadi seperti ini:

$('.t-s').each(function() {
var $thumbnailScroller = $(this);
});

Beberapa Contoh Modifikasi Slideshow JQuery

Beberapa Contoh Modifikasi Slideshow JQuery

Artikel ini merupakan kelanjutan dari artikel JQuery Slideshow Otomatis dengan Navigasi Angka

1. Slideshow dengan Caption

HTML

Untuk membuat slideshow dengan caption, kita memerlukan beberapa langkah perubahan. Pertama-tama, kita ganti elemen <div class="slide"> dengan <img>. Kemudian sisipkan elemen <figcaption> ke dalam #slider. Bagian inilah yang nantinya akan diisi oleh teks dari setiap item slider:

<figure id="slider">
<div class="container">
<img src="img/slide-1.jpg" alt="Deskripsi gambar 1">
<img src="img/slide-2.jpg" alt="Deskripsi gambar 2">
<img src="img/slide-3.jpg" alt="Deskripsi gambar 3">
<img src="img/slide-4.jpg" alt="Deskripsi gambar 4">
</div>
<figcaption></figcaption>
</figure>
<nav id="slider-nav"></nav>

Supaya lebih semantik, Saya juga telah mengganti elemen #slider yang tadinya adalah elemen divisi menjadi elemen figur. Lihat kode di atas!

CSS

Setelah itu kita set beberapa perubahan pada kode CSS:

/* Slider */
#slider {
display:block;
position:relative;
}

/* Untuk caption */
#slider figcaption {
display:block;
background-color:black;
font:normal normal 11px/normal Arial,Sans-Serif;
color:white;
opacity:.8;
padding:10px 15px;
position:absolute;
right:0;
bottom:-100px; /* sembunyikan dengan cara ini :) */
left:0;
z-index:4;
}

#slider img {
display:block;
margin:0;
width:300px; /* dimensi lebar */
height:200px; /* dimensi tinggi */
float:left;
}

JQuery

Tangkap satu objek lagi dan simpan ke dalam variabel $caption, yaitu elemen <figcaption>:

$caption = $slider.find('figcaption');

Setelah itu, kita harus mengubah logika animasi slideshow, karena di sini kita baru saja menambahkan elemen caption. Langkah animasinya seperti ini:

Pertama-tama, tampilkan teks slide awal ke dalam elemen <figcaption> sebagai awalan (dalam kasus ini Saya mengambil teks tersebut dari atribut alt pada masing-masing gambar). Ke dua adalah langkah animasi. Urutannya:

  1. Sembunyikan caption
  2. Geser slider
  3. Ganti teks caption dengan deskripsi yang baru, kemudian tampilkan caption.

Semuanya akan menjadi seperti ini:

$nav.find('a').on("click", function() {
$nav.find('.active').removeClass('active');
$(this).addClass('active');
var pos = $(this).index() * $slider.width(),

text = $slide.eq($(this).index()).attr('alt'); // Mengambil teks dari atribut alt pada gambar ke-`$(this).index()`

// (1) Menyembunyikan caption...
$caption.stop().animate({bottom:'-100px'}, 400);

// (2) Menggeser slider...
$container.stop().animate({left:'-'+pos+'px'}, 600, function() {

// (3) Mengganti teks caption dengan deskripsi yang baru...
// kemudian tampilkan caption dengan efek animasi properti 'bottom'
$caption.html(text).stop().animate({bottom:'0'}, 400);

});
clearInterval(autoSlide);
autoSlide = setInterval(slideShow, 3000);
return false;
}).first().addClass('active');

// Sebagai awalan => tampilkan caption dengan deskripsi atribut alt dari slide pertama
$caption.html($slide.first().attr('alt')).stop().animate({bottom:'0'}, 600);

Lainnya

Slideshow berupa gambar membutuhkan waktu lebih lama untuk memuat. Dan saat proses pemuatan terjadi, biasanya kita akan melihat efek yang tidak bagus dari gambar yang terpotong-potong. Cara termudah untuk mengatasi itu adalah dengan menyembunyikan semua gambar terlebih dahulu sebelum termuat. Hingga saat gambar sudah termuat, kita bisa menampilkannya:

/**
* Tip yang baik untuk slideshow berupa gambar:
* Sembunyikan tampilan sampai semua gambar benar-benar termuat...
* ... agar saat gambar sedang dimuat, dia tidak merusak pemandangan kita :)
*/

#slider .container, #slider figcaption {display:none}
#slider-nav {opacity:0}
$(window).on("load", function() {

// Tampilkan '.container', 'figcaption' dan '#slide-nav' saat halaman (semua gambar) telah termuat!
$container.show();
$caption.show();
$nav.css('opacity',1);

// Kemudian jalankan interval slideshow...
autoSlide = setInterval(slideShow, 3000);

});

Sementara gambar sedang memuat, kita tampilkan efek animasi loading dengan menambahkan latar berupa loading.gif agar slideshow menjadi lebih menarik dan komunikatif:

#slider {
background:white url('img/loading.gif') no-repeat 50% 50%;
}

2. Efek Fade

CSS

Pembuatan efek fade bisa dilakukan dengan perhitungan yang lebih sederhana:

Konsep dasar slideshow dengan efek fade adalah: Semua gambar bertumpuk, dan masing-masing gambar bergantian menampilkan diri dengan efek peningkatan/penurunan pemudaran.

Sehingga, kode CSS yang perlu kita ubah hanya ada pada bagian ini:

#slider img {
display:block;
margin:0;
width:300px;
height:200px;
/* Gunakan posisi absolut untuk menumpuk masing-masing slide satu sama lain */
position:absolute;
top:0;
left:0;
}

JQuery

Setelah itu, ada beberapa bagian variabel yang bisa kita buang. Kita sudah tidak perlu lagi menggunakan variabel-variabel ini, karena semua slide kini berada dalam satu tumpukan!

var $slider = $('#slider'),
$caption = $slider.find('figcaption'),
$container = $slider.find('.container'),
$nav = $('#slider-nav'),
$slide = $container.children(),
s_length = $slide.length,
s_wide = $slider.width() * s_length,
s_height = $slider.height(),
autoSlide = null;

Efek animasi bisa dibuat dengan JQuery .fadeIn() dan .fadeOut(). Seperti ini:

$nav.find('a').on("click", function() {

$nav.find('.active').removeClass('active');
$(this).addClass('active');

var pos = $(this).index() * $slider.width(),
text = $slide.eq($(this).index()).attr('alt');
$caption.stop().animate({bottom:'-100px'}, 400);

// Sembunyikan semua slide dengan efek .fadeOut() ...
// ... kemudian tampilkan slide ke-`$(this).index()` dengan efek .fadeIn()
$slide.fadeOut(600).eq($(this).index()).fadeIn(600, function() {
$caption.html(text).stop().animate({bottom:'0'}, 400);
});

clearInterval(autoSlide);
autoSlide = setInterval(slideShow, 3000);

return false;

}).first().addClass('active');

Lainnya

Jangan lupa untuk menghilangkan latar animasi loading saat semua gambar sudah termuat:

$(window).on("load", function() {
$slider.css('background-image','none');
});

Framework JQuery Slideshow Otomatis dengan Item Navigasi Angka

Simple Useful JQuery Slideshow

HTML

<div id="slider">
<div class="container">
<div class="slide"> ... </div>
<div class="slide"> ... </div>
<div class="slide"> ... </div>
<div class="slide"> ... </div>
<div class="slide"> ... </div>
</div>
</div>
<nav id="slider-nav"></nav>

CSS

/* Slider */
#slider {
width:300px; /* dimensi lebar */
height:200px;; /* dimensi tinggi */
margin:0 auto;
background-color:black;
overflow:hidden; /* Sembunyikan muatan elemen '.container' yang berlebih dari '#slider' */
}

#slider .slide {
width:300px; /* dimensi lebar */
height:200px; /* dimensi tinggi */
float:left;
}

#slide-1 {background-color:darkred}
#slide-2 {background-color:darkgreen}
#slide-3 {background-color:darkblue}
#slide-4 {background-color:gold}
#slide-5 {background-color:darkviolet}

/* Navigasi */
#slider-nav {
display:block;
width:300px;
margin:10px auto;
text-align:center;
}

#slider-nav a {
display:inline-block;
width:15px;
height:15px;
background-color:#bbb;
font-size:0;
color:transparent;
overflow:hidden;
text-indent:-99px;
margin:0 2px 0 0;
border:2px solid white;
-webkit-box-shadow:0 1px 2px rgba(0,0,0,.4);
-moz-box-shadow:0 1px 2px rgba(0,0,0,.4);
box-shadow:0 1px 2px rgba(0,0,0,.4);
-webkit-border-radius:100%;
-moz-border-radius:100%;
border-radius:100%;
}

#slider-nav .active {
background-color:green;
}

JQuery

(function($) {

// Tangkap semua objek yang dibutuhkan
var $slider = $('#slider'),
$container = $slider.find('.container'),
$nav = $('#slider-nav'),
$slide = $container.children(),
s_length = $slide.length,
s_wide = $slider.width() * s_length,
s_height = $slider.height(),
autoSlide = null;

// Set posisi '.container' sebagai 'relative' (untuk kebutuhan animasi properti 'left')
// Set lebar '.container' dengan ukuran = (lebar slideshow * jumlah slide)
// Set tinggi '.container' dengan ukuran = tinggi slideshow
$container.css({
'position':'relative',
'width':s_wide,
'height':s_height
});

// Otomatis menyisipkan item navigasi berdasarkan jumlah slide
$slide.each(function(index) {
var i = index + 1;
$nav.append('<a href="#slide-'+i+'">'+i+'</a>');
$(this).attr('id', 'slide-'+i);
});

// Klik untuk mengganti slide
$nav.find('a').on("click", function(pos) {
// Tambah/lepas kelas 'active' dari item navigasi (untuk pewarnaan item navigasi yang aktif)
$nav.find('.active').removeClass('active');
$(this).addClass('active');
pos = $(this).index() * $slider.width(); // Jarak animasi dihitung berdasarkan indeks navigasi yang diklik * lebar slider
$container.animate({left:'-'+pos+'px'}, 600);
clearInterval(autoSlide); // Bersihkan interval slideshow otomatis...
autoSlide = setInterval(slideShow, 3000); // Kemudian set kembali interval seperti semula.
return false;
}).first().addClass('active');

// Untuk keperluan event klik otomatis pada navigasi
function slideShow() {
if ($nav.find('.active').next().length) {
$nav.find('.active').next().trigger("click");
} else {
$nav.find('a').first().trigger("click");
}
} autoSlide = setInterval(slideShow, 3000); // Jalankan fungsi slideShow() dengan interval 3 detik!

})(jQuery);

Penjelasan Singkat

Kotak Slider

Mendefinisikan ukuran tinggi dan lebar adalah bagian terpenting, karena slideshow ini menggunakan animasi slide (bergerak menyamping dengan jarak tertentu) yang jaraknya ditentukan oleh lebar slideshow:

#slider {
width:300px; /* lebar slider */
height:200px;; /* tinggi slider */
overflow:hidden;
}

#slider .slide {
width:300px; /* lebar item sama dengan lebar kontainer */
height:200px; /* tinggi item sama dengan lebar kontainer */
float:left;
}

Setelah dimensi ditentukan, selanjutnya adalah menyimpan semua data objek dan ukuran yang diperlukan. Diantaranya:

var $slider = $('#slider'), // Slideshow => '#slider'
$container = $slider.find('.container'), // Kontainer item slider => '.container'
$nav = $('#slider-nav'), // Navigasi slider => '#slider-nav'
$slide = $container.children(), // Item slider => '.slide'
s_length = $slide.length, // Jumlah item slider
s_wide = $slider.width() * s_length, // (lebar slider * jumlah slide) => digunakan untuk menentukan total ukuran lebar kontainer item slider
s_height = $slider.height(), // Tinggi slider
autoSlide = null; // Variabel kosong

Set ukuran kontainer item slider sesuai ukuran yang telah diperhitungkan di atas:

// Set posisi '.container' sebagai 'relative' (untuk kebutuhan animasi properti 'left')
// Set lebar '.container' dengan ukuran s_wide
// Set tinggi '.container' dengan ukuran s_height
$container.css({
'position':'relative',
'width':s_wide,
'height':s_height
});

Navigasi

Anda bisa saja menyisipkan setiap item navigasi secara manual dengan jumlah yang sama berdasarkan jumlah item slider. Tapi Saya lebih menyarankan untuk menggunakan cara otomatis, dengan JQuery .each()

$slide.each(function(index) {
var i = index + 1;
$nav.append('<a href="#slide-'+i+'">'+i+'</a>');
$(this).attr('id', 'slide-'+i);
});

Eksekutor

Fungsi tugas dibuat setelah navigasi terbentuk, yaitu fungsi yang akan menganimasikan elemen .container ke arah kiri dengan jarak tertentu saat sebuah item navigasi diklik:

$nav.find('a').on("click", function(pos) {

// Tambah/lepas kelas 'active' dari item navigasi (untuk pewarnaan item navigasi yang aktif)
$nav.find('.active').removeClass('active');
$(this).addClass('active');

pos = $(this).index() * $slider.width(); // Jarak animasi => Dihitung berdasarkan indeks navigasi yang diklik * lebar slider

$container.animate({left:'-'+pos+'px'}, 600); // Animasikan '.container'

clearInterval(autoSlide); // Bersihkan interval slideshow otomatis...

autoSlide = setInterval(slideShow, 3000); // Kemudian set kembali interval seperti semula.

return false;

}).first().addClass('active'); // Tambahkan kelas 'active' pada item navigasi pertama sebagai awalan

Ada dua hal yang belum dijelaskan pada kode di atas, yaitu clearInterval(slideShow) dan setInterval(slideShow, 3000). Bagian itu akan dibuat di bawah:

Utilitas Animasi Otomatis

Pertama, yang dibutuhkan adalah sebuah fungsi seperti ini:

function slideShow() {
if ($nav.find('.active').next().length) {
// Saat item navigasi '.active' ditemukan, dan terdapat item navigasi lain disampingnya...
// seleksi item navigasi di sampingnya kemudian picu event .click() padanya!
$nav.find('.active').next().trigger("click");
} else {
// Jika tidak ditemukan, seleksi item navigasi yang pertama kemudian picu event .click() padanya!
$nav.find('a').first().trigger("click");
}
}

Tugasnya adalah untuk mengecek keberadaan item navigasi yang aktif (yang memiliki kelas active). Saat item tersebut ditemukan, maka JQuery akan melihat kepada item di sampingnya kemudian akan memicu event .click(), sehingga fungsi $nav.find('a').on("click", doSomething) yang kita buat sebelumnya bisa bekerja melalui perantara ini.
Tambahan lainnya, jika elemen setelah item navigasi tidak ditemukan, maka pindahkan selektor .next() menjadi .first() untuk kembali ke bagian awal, menyeleksi item navigasi pertama.

Terakhir, gunakan JavaScript setInterval() untuk menjalankan slideShow() secara otomatis berdasarkan interval tertentu. Di sini, Saya menggunakan interval selama 3 detik:

// Variabel autoSlide bisa kita gunakan mulai sekarang :)
autoSlide = setInterval(slideShow, 3000);

Auto Rotating Slideshow

<style type="text/css">
#slideshow {
width:200px;
height:100px;
background-color:#222;
margin:0 auto;
}

#slideshow img {display:block;}
</style>
<div id="slideshow"></div>
<script type="text/javascript">
//<![CDATA[
(function() {
var container = document.getElementById('slideshow');
var slide = [
"images/slide-1.jpg",
"images/slide-2.jpg",
"images/slide-3.jpg",
"images/slide-4.jpg"
// dst...
];
var count = 0;
setInterval(function() {
container.innerHTML = "<img src='"+slide[count]+"' alt='Slide "+(count+1)+"'>";
count++;
if (count == slide.length) {
count = 0;
}
}, 3000); // Tiga detik sekali...
})();
//]]>
</script>

Demo

Animasi Blog Roll

var $ul = $('#blog-roll'),
roll = function() {
$ul.find('li').first().slideUp('slow', function() {
$(this).appendTo($(this).parent()).fadeIn();
});
}, anim = setInterval(roll, 3000);

// Pause on hover...
$ul.hover(function() {
clearInterval(anim);
}, function() {
anim = setInterval(roll, 3000);
});

Demo

JavaScript Slideshow Dasar

JavaScript Slideshow Dasar
<figure>
<img src="" id="image" alt="">
<span id="loading">Loading...</span>
<nav>
<span id="prev"><a href="javascript:navigate(0);">Prev</a></span>
- <strong id="num"></strong> -
<span id="next"><a href="javascript:navigate(1);">Next</a></span>
</nav>
</figure>

<script type="text/javascript">
var slide = [
"image/image1.jpg",
"image/image1.jpg",
"image/image1.jpg",
"image/image1.jpg",
"image/image1.jpg"
],
prev = document.getElementById('prev'),
next = document.getElementById('next'),
curr = document.getElementById('num'),
prev_a = prev.innerHTML,
next_a = next.innerHTML,
prev_d = prev_a.replace(/<\S[^>]*>/g, ""),
next_d = next_a.replace(/<\S[^>]*>/g, ""),
img = document.getElementById('image'),
loading = document.getElementById('loading'),
i = 0;

img.setAttribute('src', slide[i]);

if (i == 0) {
prev.innerHTML = prev_d;
curr.innerHTML = "Image " + (i + 1) + " of " + slide.length;
}

// SISTEM NAVIGASI
function navigate(dir) {
prev.innerHTML = prev_a;
next.innerHTML = next_a;
if (dir == 1) {
i++;
img.setAttribute('src', slide[i]);
if (i == slide.length - 1) next.innerHTML = next_d;
} else {
i--;
img.setAttribute('src', slide[i]);
if (i == 0) prev.innerHTML = prev_d;
}
curr.innerHTML = "Image " + (i + 1) + " of " + slide.length;
loading.style.display = "block";
img.style.display = "none";
}

img.onload = function() {
loading.style.display = "none";
this.style.display = "block";
};
</script>

Penjelasan Singkat

Kerangka slideshow terdiri dari elemen <figure> dimana di dalamnya terdapat elemen gambar dengan nilai src kosong dan juga navigasi:

<figure>
<img src="" id="image" alt="">
<span id="loading">Loading...</span>
<nav>
<span id="prev"><a href="javascript:navigate(0);">Prev</a></span>
- <strong id="num"></strong> -
<span id="next"><a href="javascript:navigate(1);">Next</a></span>
</nav>
</figure>

Setiap slide dikumpulkan dalam array, dan akan digilir penyisipan URL gambarnya setiap kali navigasi diklik:

var slide = [ // Setiap slide dikumpulkan dalam array
"image/image1.jpg", // slide[0]
"image/image1.jpg", // slide[1]
"image/image1.jpg", // slide[2]
"image/image1.jpg", // slide[3]
"image/image1.jpg" // slide[4]
// Dan seterusnya...
// Tambahkan sendiri. Pisahkan setiap slide dengan tanda koma
];

Meringkas semua elemen yang ditemukan menjadi variabel:

prev = document.getElementById('prev'), // Navigasi mundur
next = document.getElementById('next'), // Navigasi maju
curr = document.getElementById('num'), // Deskripsi halaman saat ini
prev_a = prev.innerHTML, // Duplikat konten navigasi mundur
next_a = next.innerHTML, // Duplikat konten navigasi maju
prev_d = prev_a.replace(/<\S[^>]*>/g, ""), // Navigasi mundur berupa teks mati
next_d = next_a.replace(/<\S[^>]*>/g, ""), // Navigasi maju berupa teks mati
img = document.getElementById('image'), // Gambar
loading = document.getElementById('loading'), // Indikator sedang memuat/loading
i = 0; // Awal

Set gambar dengan nilai src berupa array slide[i]. Saat ini nilai i adalah 0, jadi array yang akan diambil adalah slide[0] yaitu "image/image1.jpg"

// Set gambar dengan nilai src berupa array slide[0]
// Dalam hal ini: slide[i] = slide[0] = "image/1.jpg"
img.setAttribute('src', slide[i]);

Set tampilan navigasi slideshow pada posisi awal (yaitu navigasi mundur berupa tombol mati dan navigasi maju berupa tombol hidup). slide.length adalah jumlah nilai di dalam slide:

// Awalan: set tampilan navigasi mundur sebagai teks mati
// set deskripsi halaman saat ini menjadi "Image 1 of 5"
// Dalam hal ini: i = 0; (i + 1) = 1; slide.length = 5;
if (i == 0) {
prev.innerHTML = prev_d;
curr.innerHTML = "Image " + (i + 1) + " of " + slide.length;
}

Sistem Navigasi

Pada dasarnya ini hanyalah sebuah sistem untuk menambah dan mengurangi nilai i. Pada awal deklarasi, nilai i adalah 0, saat navigasi maju diklik, maka nilai i akan berubah menjadi 1, kemudian menjadi 2, menjadi 3 dan seterusnya. Begitu pula sebaliknya, saat navigasi mundur diklik, maka nilai i akan berkurang. Proses peningkatan dan penambahan variabel ini berfungsi untuk mengganti nilai array slide[i] dalam img.setAttribute('src', slide[i]); sehingga URL gambar yang disisipkan akan berganti secara bergiliran dan berurutan:

// SISTEM NAVIGASI
function navigate(dir) {

// Langkah reset: Isi navigasi mundur dan maju dengan masing-masing duplikatnya
prev.innerHTML = prev_a;
next.innerHTML = next_a;

// Jika dir == 1, artinya navigasi maju, selain itu berarti navigasi mundur
// <a href="javascript:navigate(1);"> ** maju!
// <a href="javascript:navigate(0);"> ** mundur!
if (dir == 1) {
// Tingkatkan nilai i dengan 1 (i++ = i+1)
i++;
// Set gambar dengan nilai src berupa array slide[berikutnya]
img.setAttribute('src', slide[i]);
// Jika i < (5-1), set tampilan navigasi maju sebagai teks mati
if (i == slide.length - 1) next.innerHTML = next_d;
} else {
// Kurangi nilai i dengan 1 (i-- = i-1)
i--;
// Set gambar dengan nilai src berupa array slide[sebelumnya]
img.setAttribute('src', slide[i]);
// Jika i == 0, set tampilan navigasi mundur sebagai teks mati
if (i == 0) prev.innerHTML = prev_d;
}

// Set ulang deskripsi halaman saat ini setiap kali fungsi dieksekusi
// Dalam hal ini: setiap kali navigasi diklik
curr.innerHTML = "Image " + (i + 1) + " of " + slide.length;
// Tampilkan indikator sedang memuat
loading.style.display = "block";
// Sembunyikan gambar
img.style.display = "none";

}

Saat ini elemen gambar masih disembunyikan: img.style.display = "none";
Sedangkan indikator 'sedang memuat' ditampilkan: loading.style.display = "block";

Setelah gambar termuat, sembunyikan indikator “sedang memuat” dan tampilkan gambar:

// Saat gambar termuat...
img.onload = function() {
// Hilangkan indikator sedang memuat
loading.style.display = "none";
// tampilkan kembali gambar yang kita sembunyikan tadi
this.style.display = "block";
}

CSS

figure {
display:inline-block;
border:1px solid black;
background-color:white;
padding:10px;
margin:10px auto;
text-align:center;
}

figure nav {margin:10px 0 0;}
figure img {display:none;}
figure span {background-color:yellow;}

Basic JQuery Text/Image Rotator

Basic JQuery Text/Image Rotator

Barusan Saya menemukan kode bagus di sini: Creating a Text Rotator with JQuery
Sangat sederhana dan mudah dipahami. Sebuah fungsi JQuery slider dasar untuk merotasikan sekelompok elemen di dalam kontainer yang seringkali dicari. Saya mencoba mengonversikannya menjadi plugin seperti ini:

Plugin

(function($) {
$.fn.rotator = function(settings) {
settings = jQuery.extend({
interval: 3000,
speed: 1000
}, settings);

return this.each(function() {
var $t = $(this),
$item = $t.children().addClass('item').hide();

$t.addClass('rotator');

// Jalankan animasi jika jumlah item lebih dari satu!
if ($item.length > 1) {
// Tambahkan kelas 'current' pada item pertama sebagai penanda awal slide
$item.first().addClass('current').fadeIn(settings.speed);
// Menjalankan interval fungsi animasi dengan waktu interval yang telah ditentukan
setInterval(function() {
var c = $t.find('.current');
// Jika item (slide) setelah item aktif tidak ditemukan...
if (c.next().length === 0) {
// Hilangkan kelas 'current' pada item aktif
c.removeClass('current').fadeOut(settings.speed);
// Kemudian tambahkan kelas 'current' ke item pertama...
// sehingga rotasi bisa dimulai kembali dari awal!
$item.first().addClass('current').fadeIn(settings.speed);
} else {
// Jika tidak (jika item setelah item aktif ditemukan) ...
// Hilangkan kelas 'current' pada item aktif
// Kemudian tambahkan kelas 'current' pada item berikutnya
c.removeClass('current').fadeOut(settings.speed).next().addClass('current').fadeIn(settings.speed);
}
}, settings.interval);
}
});
};
})(jQuery);

Kerangka HTML

<div id="slide">
<div>Konten 1</div>
<div>Konten 2</div>
<div>Konten 3</div>
<div>Konten 4</div>
</div>

Penggunaan

$(function() {
$('#slide').rotator({
interval: 3000,
speed: 1000
});
});
OpsiKeterangan
intervalDigunakan untuk menentukan interval pergantian slide
speedDigunakan untuk menentukan kecepatan animasi pergantian slide

Solusi untuk Masalah Blog Bertema Komik

Menambahkan Sistem Navigasi pada Komik
Menambahkan Sistem Navigasi pada Komik

Ini soal pengalaman pribadi. Selama Saya berkeliling mencari situs-situs penyedia baca komik online, ada tiga macam jenis penyajian yang Saya temukan. Pertama, situs tersebut menunjukkan setiap halaman komik tunggal pada satu posting. Sehingga jika kita ingin membaca cerita pada halaman berikutnya, kita harus mengeklik tombol Next atau semacamnya untuk memuat posting baru yang berisi satu halaman komik berikutnya.

Ke dua, situs tersebut akan menyajikan semua halaman komik dalam satu posting, sehingga kita bisa membaca dari awal sampai akhir tanpa harus berpindah-pindah halaman. Namun resikonya adalah kita akan kehilangan begitu banyak waktu hanya untuk menunggu semua halaman komik termuat pada posting tersebut. Belum lagi jika situs yang kita kunjungi telah dipenuhi berbagai macam iklan yang akan semakin memperlambat proses muat halaman.
Tidak berbeda dengan konsep penyajian pertama, karena saat kita berpindah-pindah halaman kita harus menunggu bermenit-menit hanya untuk memuat satu gambar saja.

Bagi Saya ini tidak efektif, mengingat yang para pembaca butuhkan pada dasarnya hanyalah halaman komik dan bukan halaman situs secara keseluruhan. Jika waktu kita dihabiskan hanya untuk menunggu seluruh halaman situs termuat, padahal yang sebenarnya kita butuhkan adalah halaman komik, maka resikonya adalah kita akan kehilangan masa-masa mendalami alur cerita.

Solusinya biasanya adalah dengan cara memuat halaman komik secara bertahap. Artinya adalah kita hanya akan melihat satu halaman komik saja pada satu posting, namun saat kita mengeklik tombol halaman berikutnya, kita tidak akan dibawa menuju ke halaman/posting situs baru, melainkan hanya akan berdiam diri pada satu tempat dan menunggu gambar baru selesai termuat pada satu tempat yang sama.

Saya tidak tahu pasti apa teknik yang mereka gunakan untuk itu. Mungkin AJAX. Tapi Saya pikir itu terlalu berlebihan. Kita bisa menggunakan Lightbox! Hanya saja, lightbox yang satu ini tidak menampilkan gambar di atas tabir hitam seperti lightbox pada umumnya. Kita akan menampilkan gambar tepat di atas navigasi, dengan begitu suasana membaca akan tetap terasa seperti halnya saat kita membaca komik biasa.

Konsep dasarnya masih sama seperti tutorial pembuatan lightbox yang pernah Saya tuliskan di sini. Yaitu kita akan menembak URL gambar pada tautan ke dalam elemen <img> setiap kali aksi klik dilakukan:

$('ul a').click(function() {
$('div').html('<img src="' + this.href + '" alt="Loading..."/>');
return false;
});

Di sini kita akan membuat markup yang berbeda agar setiap tautan tampak sebagai navigasi halaman berangka, dan gambar yang termuat akan ditampilkan di atasnya sebagai halaman komik tunggal:

Markup HTML

Yang kita perlukan tidak banyak. Kita hanya akan membuat daftar tautan yang mengarah ke setiap unit halaman komik (halaman komik adalah gambar). Jadi buat saja seperti ini:

<ul class="img-gallery" data-width="750" data-height="1088">
<li><a href="img/01.png">Judul Halaman 1</a></li>
<li><a href="img/02.png">Judul Halaman 2</a></li>
<li><a href="img/03.png">Judul Halaman 3</a></li>
<li><a href="img/04.png">Judul Halaman 4</a></li>
</ul>

Kelas img-gallery digunakan sebagai identitas, sehingga JQuery hanya akan memanipulasi elemen daftar yang memiliki kelas img-gallery saja. data-width digunakan untuk menentukan lebar halaman komik, data-height digunakan untuk menentukan tinggi halaman komik. Ini diperlukan karena kita akan membuat aplikasi yang tidak hanya bisa digunakan untuk menangani satu komik saja per satu posting tapi juga beberapa komik sekaligus dalam ukuran yang berbeda-beda. Dalam satu halaman.

Memulai Manipulasi

Pertama-tama kita akan membungkus grup tautan halaman komik di atas dengan elemen yang kita beri nama .img-show:

$('.img-gallery').each(function() {
$(this).addClass('img-nav').wrap('<div class="img-show"></div>');
});

Saya juga menambahkan kelas baru bernama .img-nav. Itu akan kita gunakan sebagai selektor CSS untuk mengubah tampilan daftar menjadi tampak sebagai navigasi halaman. Sehingga markup HTML akan menjadi seperti ini:

<div class="img-show"> <ul class="img-gallery img-nav" data-width="750" data-height="1088">
<li><a href="img/01.png">Judul Halaman 1</a></li>
<li><a href="img/02.png">Judul Halaman 2</a></li>
<li><a href="img/03.png">Judul Halaman 3</a></li>
<li><a href="img/04.png">Judul Halaman 4</a></li>
</ul>
</div>

Setelah itu sisipkan kontainer kosong yang akan kita gunakan sebagai tempat untuk meletakkan gambar:

$('.img-gallery').each(function() {
$(this).addClass('img-nav').wrap('<div class="img-show"></div>');
$(this).parents('.img-show').prepend('<div class="img-holder"></div>');
});

Sehingga markup HTML akan menjadi seperti ini:

<div class="img-show">
<div class="img-holder"></div> <ul class="img-gallery img-nav" data-width="750" data-height="1088">
<li><a href="img/01.png">Judul Halaman 1</a></li>
<li><a href="img/02.png">Judul Halaman 2</a></li>
<li><a href="img/03.png">Judul Halaman 3</a></li>
<li><a href="img/04.png">Judul Halaman 4</a></li>
</ul>
</div>

Pada dasarnya itu saja markup yang diperlukan untuk membuat aplikasi komik digital ini. Selebihnya hanya tinggal menentukan ukuran dan perintah.
Sekarang kita ringkas semua kode yang terlalu panjang, dan ambil data lebar dan tinggi halaman yang sudah kita simpan di dalam atribut data-width dan data-height:

$('.img-gallery').each(function() {
var w = $(this).data('width'),
h = $(this).data('height');
$(this).addClass('img-nav').wrap('<div class="img-show" style="width:' + w + 'px;"></div>');
var $parent = $(this).parents('.img-show');
$parent.prepend('<div class="img-holder" style="height:' + h + 'px;"></div>');
});

Sehingga hasilnya akan menjadi seperti ini:

<div class="img-show" style="width:750px;">
<div class="img-holder" style="height:1088px;"></div>
<ul class="img-gallery img-nav" data-width="750" data-height="1088">
<li><a href="img/01.png">Judul Halaman 1</a></li>
<li><a href="img/02.png">Judul Halaman 2</a></li>
<li><a href="img/03.png">Judul Halaman 3</a></li>
<li><a href="img/04.png">Judul Halaman 4</a></li>
</ul>
</div>

Dimensi halaman sudah tercipta, sekarang saatnya mengubah setiap item tautan menjadi navigasi berangka. Kita akan menggunakan JQuery .each() untuk merayapi semua elemen tautan satu persatu kemudian menyisipkan angka sesuai dengan urutannya, memindah semua teks judul halaman pada masing-masing tautan ke dalam atribut title. Tapi sebelum itu kita atur dulu agar saat halaman pertama kali dibuka, gambar pada navigasi halaman pertama bisa tampil tanpa diperintah:

$('.img-gallery').each(function() {
var w = $(this).data('width'),
h = $(this).data('height');
$(this).addClass('img-nav').wrap('<div class="img-show" style="width:' + w + 'px;"></div>');
var $firstNav = $('li:first a', this), // Mendapatkan tautan pertama dari semua tautan dalam daftar
current = $firstNav.attr('href'), // Mendapatkan nilai href tautan pertama untuk ditampilkan sebagai gambar pada saat pertama kali komik diakses
$parent = $(this).parents('.img-show');
$firstNav.addClass('active'); // Menambahkan kelas active pada tautan pertama
$parent.prepend('<div class="img-holder" style="height:' + h + 'px;"></div>');
// Sisipkan gambar (halaman komik) pada elemen .img-holder...
// dengan nilai src yang diambil dari atribut href tautan pertama
$parent.find('.img-holder').addClass('loading').html('<img class="transparent" src="' + current + '" alt="Loading..."/>');
});

Kelas .loading ditambahkan untuk mengaktifkan CSS khusus yang akan memberikan latar berupa gambar animasi loading:

<div class="img-show" syle="width:750px;">
<div class="img-holder loading" style="height:1088px;">
<img class="transparent" src="img/01.png" alt="Loading..."/> </div>
<ul class="img-gallery img-nav" data-width="750" data-height="1088">
<li><a class="active" href="img/01.png">Judul Halaman 1</a></li>
<li><a href="img/02.png">Judul Halaman 2</a></li>
<li><a href="img/03.png">Judul Halaman 3</a></li>
<li><a href="img/04.png">Judul Halaman 4</a></li>
</ul>
</div>
.img-show .img-holder.loading {
background:white url('img/loading.gif') no-repeat 50% 300px;
}

Atur tampilan gambar yang berhasil ditambahkan dengan tingkat transparasi sebesar 0, sehingga gambar akan tampak menghilang dan memperlihatkan latar animasi loading di belakangnya:

$parent.find('img.transparent').css('opacity', 0);

Saat ini gambar masih memuat, saat gambar telah benar-benar berhasil termuat, animasikan tingkat transparasi menuju 1 (opaque) sehingga efek fading akan tercipta setiap kali gambar selesai termuat:

$parent.find('img.transparent').css('opacity', 0).load(function() {
$parent.find('.img-holder').removeClass('loading'); // Singkirkan kelas loading pada kontainer saat gambar telah berhasil dimuat
$(this).animate({opacity:1}, 400); // Animasikan nilai transparasi dari 0 menuju 1
});;

Menyisipkan Angka-Angka

Untuk menyisipkan angka-angka, kita gunakan .each() untuk merayapi semua tautan yang ada kemudian ganti semua teks di dalamnya menjadi angka sesuai dengan urutannya. Di sini Saya juga akan memindah teks asli pada masing-masing tautan ke dalam atribut title, sehingga tidak akan ada yang sia-sia:

$('.img-gallery').each(function() {
var w = $(this).data('width'),
h = $(this).data('height');
$(this).addClass('img-nav').wrap('<div class="img-show" style="width:' + w + 'px;"></div>');
var $firstNav = $('li:first a', this),
current = $firstNav.attr('href'),
$parent = $(this).parents('.img-show');
$firstNav.addClass('active');
$parent.prepend('<div class="img-holder" style="height:' + h + 'px;"></div>');
$parent.find('.img-holder').addClass('loading').html('<img class="transparent" src="' + current + '" alt="Loading..."/>');

$('a', this).each(function(i) {
i = i+1; // Proses pengurutan dalam JavaScript dimulai dari nol, untuk mengangkat nilai awal pengurutan, naikkan satu tingkat!
$(this).attr('title', $(this).text()); // Pindahkan semua teks (judul halaman) pada tautan menjadi nilai atribut title pada setiap tautan
$(this).html(i); // Terakhir, sisipkan nomor urut pada masing-masing tautan
});
});

Sehingga hasilnya akan menjadi seperti ini:

<div class="img-show" syle="width:750px;">
<div class="img-holder loading" style="height:1088px;">
<img class="transparent" src="img/01.png" alt="Loading..."/>
</div>
<ul class="img-gallery img-nav" data-width="750" data-height="1088">
<li><a class="active" href="img/01.png" title="Judul Halaman 1">1</a></li>
<li><a href="img/02.png" title="Judul Halaman 2">2</a></li>
<li><a href="img/03.png" title="Judul Halaman 3">3</a></li>
<li><a href="img/04.png" title="Judul Halaman 4">4</a></li>
</ul>
</div>

Memasukkan Perintah

Sekarang kita tambahkan perintah pada setiap navigasi halaman. Jika navigasi halaman diklik, sisipkan nilai href dari navigasi halaman tersebut ke dalam elemen <img>, kemudian atur efek animasi seperti pada efek animasi yang kita buat sebelum ini:

$('a', this).each(function(i) {
i = i+1;
$(this).attr("title", $(this).text());
$(this).html(i);
}).on("click", function() {
var $activeNav = $(this).parents('.img-gallery').find('a.active'),
$activeParent = $(this).parents('.img-show');
// Bergantian mengganti kelas setiap kali klik pada navigasi
$activeNav.removeClass('active');
$(this).addClass('active').parents('.img-show').find('.img-holder').html('<img class="transparent" src="' + this.href + '" alt="Loading..."/>');
$parent.find('.img-holder').addClass('loading').find('img.transparent').css('opacity', 0).load(function() {
$(this).removeClass('loading').find('img').animate({opacity:1}, 400);
});
return false;
});

Lebar dan Tinggi Halaman yang Berbeda

Tidak semua halaman komik memiliki tinggi dan lebar yang sama. Terkadang mereka juga bisa tampak sebagai gambar lebar berbentuk persegi panjang mendatar. Oleh karena itu menganimasikan tinggi dan lebar kontainer juga penting. Kita bisa mendapatkan lebar dan tinggi gambar saat gambar telah termuat, sehingga kita misa menganimasikan ukuran kontainer sesuai dengan ukuran gambar yang tampil. Modifikasi dilakukan pada saat fungsi telah menunjukkan bahwa gambar sudah termuat:

$('a', this).each(function(i) {
i = i+1;
$(this).attr("title", $(this).text());
$(this).html(i);
}).on("click", function() {
var $activeNav = $(this).parents('.img-gallery').find('a.active'),
$activeParent = $(this).parents('.img-show');
$activeNav.removeClass('active');
$(this).addClass('active').parents('.img-show').find('.img-holder').html('<img class="transparent" src="' + this.href + '" alt="Loading..."/>');
$parent.find('.img-holder').addClass('loading').find('img.transparent').css('opacity', 0).load(function() {
// Animasikan lebar dan tinggi kontainer setelah gambar termuat
$parent.animate({width:$(this).width()}, 600).find('.img-holder').animate({height:$(this).height()}, 600, function() {
// Setelah animasi tinggi dan lebar selesai dijalankan,
// set nilai transparasi gambar menjadi opaque
$(this).removeClass('loading').find('img').animate({opacity:1}, 400);
});
});
return false;
});

Membuat Halaman Meloncat ke Posisi yang Tepat

Saat menekan tombol navigasi, pada dasarnya kita sedang berada pada posisi halaman paling bawah. Akan sangat merepotkan jika pembaca harus menggulung layar ke atas kembali setiap kali gambar baru termuat, jadi kita buat saja agar halaman meloncat ke atas setiap kali navigasi diklik. Kita gunakan JQuery .scrollTop() untuk urusan ini:

$('a', this).each(function(i) {
i = i+1;
$(this).attr("title", $(this).text());
$(this).html(i);
}).on("click", function() {
var $activeNav = $(this).parents('.img-gallery').find('a.active'),
$activeParent = $(this).parents('.img-show');
$activeNav.removeClass('active');
$('html, body').scrollTop($activeParent.offset().top-40);
$(this).addClass('active').parents('.img-show').find('.img-holder').html('<img class="transparent" src="' + this.href + '" alt="Loading..."/>');
$parent.find('.img-holder').addClass('loading').find('img.transparent').css('opacity', 0).load(function() {
// Animasikan lebar dan tinggi kontainer setelah gambar termuat
$parent.animate({width:$(this).width()}, 600).find('.img-holder').animate({height:$(this).height()}, 600, function() {
// Setelah animasi tinggi dan lebar selesai dijalankan,
// set nilai transparasi gambar menjadi opaque
$(this).removeClass('loading').find('img').animate({opacity:1}, 400);
});
});
return false;
});

Selesai! Sisanya tinggal merapikan dan memidah semua hal yang berhubungan dengan durasi animasi ke dalam variabel baru, sehingga proses modifikasi kecepatan animasi menjadi lebih mudah dilakukan.


Kode Lengkap

JQuery

$(function() {
$('.img-gallery').each(function() {
var w = $(this).data("width"),
h = $(this).data("height"),
viewport = $('html, body'),
fadeSpeed = 400, // Kecepatan efek fading
resizeSpeed = 600; // Kecepatan efek pelebaran/penyusutan
$(this).addClass('img-nav').wrap('<div class="img-show" style="width:' + w + 'px;"></div>');
var $firstNav = $('li:first a', this),
current = $firstNav.attr('href'),
$parent = $(this).parents('.img-show');
$firstNav.addClass('active');
$parent.prepend('<div class="img-holder" style="height:' + h + 'px;"></div>');
$parent.find('.img-holder').addClass('loading').html('<img class="transparent" src="' + current + '" alt="Loading..."/>');
$parent.find('img.transparent').css('opacity', 0).load(function() {
$parent.animate({width:$(this).width()}, resizeSpeed).find('.img-holder').animate({height:$(this).height()}, resizeSpeed, function() {
$(this).removeClass('loading').find('img').animate({opacity:1}, fadeSpeed);
});
});

$('a', this).each(function(i) {
i = i+1;
$(this).attr("title", $(this).text());
$(this).html(i);
}).on("click", function() {
var $activeNav = $(this).parents('.img-gallery').find('a.active'),
$activeParent = $(this).parents('.img-show');
$activeNav.removeClass('active');
viewport.scrollTop($activeParent.offset().top-40);
$(this).addClass('active').parents('.img-show').find('.img-holder').html('<img class="transparent" src="' + this.href + '" alt="Loading..."/>');
$parent.find('.img-holder').addClass('loading').find('img.transparent').css('opacity', 0).load(function() {
$parent.animate({width:$(this).width()}, resizeSpeed).find('.img-holder').animate({height:$(this).height()}, resizeSpeed, function() {
$(this).removeClass('loading').find('img').animate({opacity:1}, fadeSpeed);
});
});
return false;
});

});
});

CSS

.img-show {
width:400px;
margin:50px auto;
background-color:black;
border:2px solid black;
-webkit-box-shadow:0 1px 3px rgba(0,0,0,.2);
-moz-box-shadow:0 1px 3px rgba(0,0,0,.2);
box-shadow:0 1px 3px rgba(0,0,0,.2);
position:relative;
overflow:hidden;
}

.img-show .img-holder {
background-color:white;
}

.img-show .img-holder.loading {
background:white url('data:image/gif;base64,R0lGODlhIAAgANU7AICAgD8/P97e3vb29uTk5Ht7e/n5+efn5yoqKu3t7erq6tXV1dLS0nh4ePPz84GBgVRUVHV1dWNjYzAwMKWlpb29vZ+fn5mZmTMzM5CQkC0tLfz8/GlpaVdXVzY2NktLS6ysrF1dXc/PzxISEn5+foeHh2xsbLS0tLGxsYqKiiEhIcPDwwMDA8bGxm9vb83NzY2NjUVFRczMzPDw8ISEhAYGBgwMDB4eHsDAwCQkJAAAAP///wAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAAA7ACwAAAAAIAAgAAAGxcCdcEgczlwTz2NQbDqdh5tuqpswn9imhEqFZZ04UokxzHGnn2/xQa1ZhIizDqIeylhcW2JXkFPqQilyKDsGGFwdRQAAWBdyFUIGGRAhf4qMTwkjXBoGgF8tKlMIC591CwKmqqtPCgqsWAQBUwEEsE2zVAG3RAJyqauLQ75nwKrCQ7m0vESytLbMRAcH0dXWvCKl1ztbOjTXIFwvgMhPJ1xkdeVOA3E6MUUJERGvqwMVKxtFJlMc2w1TGmxzUKCAg20IbwUBACH5BAkAADsALAAAAAAgACAAAAbEwJ1wSCTiSCVGccls7h66aM3irC5lrGjUlrAyFQpiSqtFCWeuiecxaBIC0QBBeCFHK7vDjTxpL+FaAUIJI2QaBjsSdjowSwKLAkItKlEIC0I5ix+OkEQLkUMIixBMgHFWBYsUTG9xc1UGGGQdVQcHXkIGGRAhq7i/wMG4IpfCVoo6NMZOIGQvyzsAAEQnZErL0kQDojox0E0DFSsb3+Xm5+jpxgkREWHqJlEcwNlVDVEN9NNVDgUFDuqs1As4MKDBg9+CAAAh+QQJAAA7ACwAAAAAIAAgAAAGxcCdcEgsKhTFpHIpJAR0ugCBSVU+odGqVijAYgVDHKnEqIoWxK5XB949sDULUwKlEa/QgFDG8toSSiBeL0NOeVM7KWs6KEonXmVEBwdEF4sVSgMIUDFaCSNeGgZLAxUrG1stKlAIaFuvC22vs7S0My4THg8DtUsHN14TvDsJERFItXRrMEImUBy9OYsfQg1QDb2baxBCDgUFDr0FixS9SQYYXh3mSgYZECHl7PP09fb3AAC0+Vr8s/73AgIMuGMgwYMI6wUBACH5BAkAADsALAAAAAAgACAAAAbEwJ1wSCwaj8ikULRQOpESnY72rApBUumrqFBYi6esjjEkBKQBQjIRiXiHA4Q0RjxnA0mTlFMcVFYbQwJiUgJIDVINT4OEhkcOBQUOVXZoX05maGqXTgcHnKChSjgkJWSiRg9ZNRaoRDIsYjYJQwAAoSmEOii1t6AXuhWuQgkjYhoGw0ItKlIITcpDC47R1UQzLhMeDwPRBzdiE93DUYQwSbZVObof6L5OcoQQygW6FKDpQwYYYh2h+foyQAhxz5rBg5eCAAAh+QQJAAA7ACwAAAAAIAAgAAAGwcCdcEgsGo/IpHLJTEQiCqZ0aNLpONNpw9owihbZoqNQcBQlVtoSAJiCrNaXkj09wXWMsHKAsMb0SwMVKxuAhoeIgApRiUUEAVYBBI1DkHABRHSAAndWAkOaepydn5SWkZRCj5GTqUIHB66yRTgkJXmuD3A1FqkyLHc2CUmhQjMuEx4PA0IpnTooxG1DBzd3E8wXzxVZaJ0wOwkjdxoGWTnPH0ItKlYIYFl9nRBEC6VhBc8UlAYYdx2uDGSAEGKflCAAIfkECQAAOwAsAAAAACAAIAAABsHAnXBILBqPyKRyyWw6jQDA8xmdWouJSESxrDpNOh2nK3U2wo2r0lEoONTwuHxOrxtFC/tQEqYVvVcgYWEvRIBWJ4M6DHYDCGExejsDFSsbkphNMy4THg8DTgpcSAc3ihOgSgQBYQEER3yKOjBLrIMBRzmyOh9DOCQljEICuwJGj7IQQg+DNRbDxUYFuxQ7MiyKNglCtq1HBhiKHUIpuyhCq62v3xkQIdVCF7sVRAcHVwkjihoGdS0qYRDk0bPAmJMgACH5BAkAADsALAAAAAAgACAAAAbBwJ1wSCwaj8ikcslsOo0AwPMZnVqvwipVutQ6vdiweEwuD2euiecxMB9uurhu0iZL5HLYNRGJKIQ5eHEfVyZxHEIIgjoQVw1xDUIFixRXDgUFDkIGGHgdZjsGGRAhlaCnSTgkJQynD3I1Fk4iC0kyLHg2CUx3OjRIKYsoRAp/RCB4L0cXixVCBAFxAQRDJ3itRgkjeBoGQtFyAUMDijoxSS0qcQi1OwKLAuMVKxtLC/FD74L4ZODSoNCkUTt14MCTIAAh+QQFAAA7ACwAAAAAIAAgAAAGxMCdcEgsGo/IpHLJbCZnronnMSgCAE7i4abr6ibV4TU7lHi9MDIyd+5+mmMkoq2DwLHIAp2iPhowZx19SAYZECF8g4pqOCQlDItGD141FpFDMixnNgmXOyl0KINxOxd0FaN4OwkjZxoGnjstKl0IC7FDCwK4vEwKCr0EAV0BBLjDXgFNCRERwEcCdLtLJl0cSNFt00Iit0UNXQ1JyMREZjo0RQ4FBQ5JwsTGQiBnL4MHB0UnZ5CxA3M6YvQaUGHFhl59ggAAOw==') no-repeat 50% 160px;
}

.img-show .img-holder img {
display:block;
}

.img-show .img-nav {
margin:0;
padding:0;
overflow:hidden;
}

.img-show .img-nav li {
margin:2px 2px 0 0;
padding:0;
float:left;
display:inline;
list-style:none;
}

.img-nav li a {
display:block;
background-color:#ccc;
color:black;
padding:3px 7px;
font:normal normal 12px/normal Georgia,"URW Bookman L",Serif;
font-style:italic;
text-decoration:none;
}

.img-nav li a.active {
background-color:#900;
color:white;
}

Dasar Kerangka

<ul class="img-gallery" data-width="750" data-height="1000">
<li><a href="img/01.png">Judul Halaman 1</a></li>
<li><a href="img/02.png">Judul Halaman 2</a></li>
<li><a href="img/03.png">Judul Halaman 3</a></li>
</ul>
 
Support : Creating Website | Johny Template | Mas Template
Copyright © 2011. Homtimpa - All Rights Reserved
Template Modify by Creating Website
Proudly powered by Blogger