(function($){ $.fn.kwicks = function(options) { var defaults = { isvertical: false, sticky: false, defaultkwick: 0, event: 'mouseover', spacing: 0, duration: 500 }; var o = $.extend(defaults, options); var woh = (o.isvertical ? 'height' : 'width'); // woh = width or height var lot = (o.isvertical ? 'top' : 'left'); // lot = left or top return this.each(function() { var container = $(this); var kwicks = container.children('li'); var normwoh = kwicks.eq(0).css(woh).replace(/px/,''); // normwoh = normal width or height if(!o.max) { o.max = (normwoh * kwicks.size()) - (o.min * (kwicks.size() - 1)); } else { o.min = ((normwoh * kwicks.size()) - o.max) / (kwicks.size() - 1); } // set width of container ul if(o.isvertical) { container.css({ width : kwicks.eq(0).css('width'), height : (normwoh * kwicks.size()) + (o.spacing * (kwicks.size() - 1)) + 'px' }); } else { container.css({ width : (normwoh * kwicks.size()) + (o.spacing * (kwicks.size() - 1)) + 'px', height : kwicks.eq(0).css('height') }); } // pre calculate left or top values for all kwicks but the first and last // i = index of currently hovered kwick, j = index of kwick we're calculating var precalclots = []; // precalclots = pre-calculated left or top's for(i = 0; i < kwicks.size(); i++) { precalclots[i] = []; // don't need to calculate values for first or last kwick for(j = 1; j < kwicks.size() - 1; j++) { if(i == j) { precalclots[i][j] = o.isvertical ? j * o.min + (j * o.spacing) : j * o.min + (j * o.spacing); } else { precalclots[i][j] = (j <= i ? (j * o.min) : (j-1) * o.min + o.max) + (j * o.spacing); } } } // loop through all kwick elements kwicks.each(function(i) { var kwick = $(this); // set initial width or height and left or top values // set first kwick if(i === 0) { kwick.css(lot, '0px'); } // set last kwick else if(i == kwicks.size() - 1) { kwick.css(o.isvertical ? 'bottom' : 'right', '0px'); } // set all other kwicks else { if(o.sticky) { kwick.css(lot, precalclots[o.defaultkwick][i]); } else { kwick.css(lot, (i * normwoh) + (i * o.spacing)); } } // correct size in sticky mode if(o.sticky) { if(o.defaultkwick == i) { kwick.css(woh, o.max + 'px'); kwick.addclass('active'); } else { kwick.css(woh, o.min + 'px'); } } kwick.css({ margin: 0, position: 'absolute' }); kwick.bind(o.event, function() { // calculate previous width or heights and left or top values var prevwohs = []; // prevwohs = previous widths or heights var prevlots = []; // prevlots = previous left or tops kwicks.stop().removeclass('active'); for(j = 0; j < kwicks.size(); j++) { prevwohs[j] = kwicks.eq(j).css(woh).replace(/px/, ''); prevlots[j] = kwicks.eq(j).css(lot).replace(/px/, ''); } var aniobj = {}; aniobj[woh] = o.max; var maxdif = o.max - prevwohs[i]; var prevwohsmaxdifratio = prevwohs[i]/maxdif; kwick.addclass('active').animate(aniobj, { step: function(now) { // calculate animation completeness as percentage var percentage = maxdif != 0 ? now/maxdif - prevwohsmaxdifratio : 1; // adjsut other elements based on percentage kwicks.each(function(j) { if(j != i) { kwicks.eq(j).css(woh, prevwohs[j] - ((prevwohs[j] - o.min) * percentage) + 'px'); } if(j > 0 && j < kwicks.size() - 1) { // if not the first or last kwick kwicks.eq(j).css(lot, prevlots[j] - ((prevlots[j] - precalclots[i][j]) * percentage) + 'px'); } }); }, duration: o.duration, easing: o.easing }); }); }); if(!o.sticky) { container.bind("mouseleave", function() { var prevwohs = []; var prevlots = []; kwicks.removeclass('active').stop(); for(i = 0; i < kwicks.size(); i++) { prevwohs[i] = kwicks.eq(i).css(woh).replace(/px/, ''); prevlots[i] = kwicks.eq(i).css(lot).replace(/px/, ''); } var aniobj = {}; aniobj[woh] = normwoh; var normdif = normwoh - prevwohs[0]; kwicks.eq(0).animate(aniobj, { step: function(now) { var percentage = normdif != 0 ? (now - prevwohs[0])/normdif : 1; for(i = 1; i < kwicks.size(); i++) { kwicks.eq(i).css(woh, prevwohs[i] - ((prevwohs[i] - normwoh) * percentage) + 'px'); if(i < kwicks.size() - 1) { kwicks.eq(i).css(lot, prevlots[i] - ((prevlots[i] - ((i * normwoh) + (i * o.spacing))) * percentage) + 'px'); } } }, duration: o.duration, easing: o.easing }); }); } }); }; })(jquery);