Lo scopo di questo plugin è di fare uno slider con gli elementi di un elenco HTML.
In questo caso, si trattava di un insieme d'immagini con la loro descrizione che raccontano la storia di un'azienda lungo i suoi quasi 150 anni. Il risultato finale si può vedere qui
Il codice HTML di partenza era più o meno questo:
<div id="slideme">
<div id="slides">
<ul>
<li>
<div>
<h4 id="button">
1854</h4>
<h4>
First factory for the chestnut extraction production in Italy</h4>
<p>In Corsaglia di Frabosa.....</p>
</div>
[immagine]
</li>
<li>
....
</li>
</ul>
</div>
</div>
Queste sono le funzioni del plugin:
/* jQuery Plugin
* Muestra en forma rotativa cada elemento en forma de lista contenido
* dentro de otro que deja mostrar solo uno
*
* FX1: Desplaza los elementos hacia arriba y llegado el fin, vuelve a
* mostrar el primero
* FX2: Oculta el elemento que se esta viendo (fadeout) y muestra el
* siguiente (fadeto)
pause
type: number
descr: tiempo en milisegundos en que la animación permanecerá inmovil
controls
type: boolean
descr: genera html con botones para moverse a través de las diapositivas
go_to
type: number
descr: indice del elemento que se mostrará en primer lugar
display
type: enum
opts: horizontal, vertical, fade
descr: tipo de animacion entre cada elemento. Horizontal y vertical hacen
movimiento. Fade hace un efecto de transparencia entre los elementos
*/
jQuery.fn.penny_slider = function(options){
var defaults = {
elements: 'li',
go_to: -1,
fade_over: 1,
fade_to: 0.4,
fx_delay: 600,
pause: 0,
controls: false,
display: 'horizontal'
};
/* merge options given with defaults */
var opts = $.extend(defaults, options);
var slider = this;
var len = slider.find(opts['elements']).length;
/* check for requiered values */
if (!options['width']) {
options['width'] = slider.find(opts['elements']).outerWidth(true);
}
if (!options['height']) {
options['height'] = slider.find('ul').outerHeight(true)/len;
}
if (!options['slide_dist']) {
switch (opts['display'])
{
case 'horizontal':
opts['slide_dist'] = options['width'];
break;
case 'vertical':
opts['slide_dist'] = options['height'];
break;
}
}
var slider_width = opts['width']*len;
// create buttons
if (opts['controls'] == true && slider.find('.slider_control').length == 0) {
var html = "";
for (n=0; n < len; n++) {
var element = slider.find('li:eq('+n+')');
if (opts['display'] == 'horizontal') {
element.css("float","left");
}
var button_wrapper = element.find('#button');
var button_name = button_wrapper.html();
button_wrapper.remove();
html += "<span id='"+(n+1)+"' >"+button_name+"</span>";
}
controls_ = "<div id='controls'>";
controls_ += " <div class='repro'></div>";
controls_ += " <div class='pause'></div>";
controls_ += " <div class='time'></div>";
controls_ += "</div>";
slider.prepend(controls_+"<div class='slider_control_wpr'><div class='slider_control'>"+html+"</div></div>");
slider.find(".time").html(opts['pause']/1000);
/* control events */
slider.find(".repro").click(function(){
clock();
showme ();
start();
}).mouseover(function(){
$(this).css('cursor','pointer');
});
slider.find(".pause").click(function(){
pause();
}).mouseover(function(){
$(this).css('cursor','pointer');
});
/* botones creados
*
*/
var wp_width = slider.find('.slider_control_wpr').width();
$(".slider_control").data('wp_width', wp_width);
var wp_pos = slider.offset();
var bt_wp = slider.find('.slider_control');
$(".slider_control").data('bt_wp', bt_wp);
var bt_wp_pos = bt_wp.offset();
$(".slider_control").data('bt_wp_pos', bt_wp.offset());
/* width del contenedor de los botones */
var bt_wp_width = 0;
slider.find(".slider_control span").each(function(){
bt_wp_width += $(this).outerWidth(true);
});
/* control buttons wrapper */
var bt_wp_width = 0;
$(".slider_control").find('span').each(function(){
if (opts['go_to'] == $(".slider_control span").index($(this))+1) {
$(".slider_control").data("active", $(this).attr('id'));
$(this).addClass("active");
}
bt_wp_width += $(this).outerWidth(true);
$(this).click(function(){
/* distinguish active */
pause ();
active_id = $('.slider_control').data('active');
$(".slider_control #"+active_id).removeClass('active');
$(".slider_control").data("active", $(this).attr('id'));
$(this).addClass("active");
//control_move ($(this));
slider.penny_slider({
fade_to: 1,
slide_dist: opts['slide_dist'],
elements: opts['elements'],
go_to: $(this).attr('id'),
display: opts['display'],
pause: 0
})
}).mouseover(function(){
$(this).css("cursor","pointer");
})
});
/* correct wrapper width */
slider.find(".slider_control").width(bt_wp_width);
$(".slider_control").data('bt_wp_width', bt_wp_width);
}
/* botones listos */
if (opts['fade_to'] != 1) {
slider.find(opts['elements']+':first').fadeTo(opts['fx_delay'], opts['fade_to']);
}
slider.find(opts['elements']).fadeTo(opts['fx_delay'], opts['fade_to']);
goto_n = opts['go_to']-1;
function control_move (button) {
/* porcentaje del ancho del boton cliqueado
*
*/
var bt_position = button.offset();
var bt_width = button.outerWidth();
var bt_wp = $(".slider_control").data('bt_wp');
var bt_wp_pos = $(".slider_control").data('bt_wp_pos');
var bt_wp_width = $(".slider_control").data('bt_wp_width');
var wp_width = $(".slider_control").data('wp_width');
/* this_limit: distancia desde el 0 de los botones
* hasta la mitad del ancho del boton apretado
*/
this_limit = bt_position['left'] - bt_wp_pos['left'] + bt_width/2;
this_percent = this_limit*100/bt_wp_width;
wp_width_rel = wp_width*this_percent/100;
/* dist difference btw control and content */
dist_diff = this_limit-wp_width_rel;
if (this_limit > wp_width/2) {
move_diff = this_limit-(wp_width/2);
if (move_diff > (bt_wp_width - wp_width)) {
move_diff = bt_wp_width - wp_width;
}
} else {
move_diff = 0;
}
// move controls
$(".slider_control").animate({
left: -move_diff
}, 600, 'swing',
function(){
$(".slider_control").data('bt_wp_pos',bt_wp.offset());
});
}
function showme () {
/* fx: move element */
if (opts['display'] == 'horizontal' || opts['display'] == 'vertical') {
if (goto_n >= len) {
goto_n = 0;
}
if (opts['display'] == 'vertical') {
_top = opts['slide_dist']*-1*goto_n;
_left = 0;
} else {
_top = 0;
_left = opts['width']*-1*goto_n;
}
bt_active = $(".slider_control").data("active");
$(".slider_control").find("#"+bt_active).removeClass("active");
goto_n++;
var button_active = $(".slider_control").find("#"+goto_n);
button_active.addClass("active");
$(".slider_control").data("active", goto_n);
control_move (button_active);
// move it
slider.find('ul').animate({
top: _top+'px',
left: _left+'px'
}, opts['fx_delay'], 'swing', function() {
// Animation complete.
});
} else {
/* fx: fade_out -> fade_in => time/2 */
var fx_delay = opts['fx_delay']/2;
slider.find(opts['elements']).unbind();
// hide current
slider.find(opts['elements']+':eq('+current_show+')').fadeOut(fx_delay, function(){
// bind!
slider.find(opts['elements']+':eq('+next_show+')').bind({
mouseenter: function(){
pause();
$(this).fadeTo('fast', opts['fade_over']);
},
mouseleave: function(){
$(this).fadeTo('fast', opts['fade_to']);
start();
}
})
// show!
.fadeTo(fx_delay, opts['fade_to'], function(){
current_show = next_show;
next_show++;
if (next_show >= len) {
next_show = 0;
current_show = len-1;
}
});
});
}
}
function start () {
if (opts['pause'] > 0) {
slider.find("#controls .repro").hide();
slider.find("#controls .pause").show();
slider.everyTime(opts['pause'], function(){
debug("start");
clock();
showme ();
});
} else {
showme ();
}
}
function pause () {
slider.find("#controls .pause").hide();
slider.find("#controls .repro").show();
slider.find('.time').stopTime();
slider.stopTime();
}
function clock () {
var time_ = (opts['pause']/1000)-1;
slider.find('.time').stopTime();
debug("clock");
slider.find('.time').everyTime(1000, function(){
slider.find('.time').html(time_);
debug(time_);
time_--;
});
}
start ();
}