|
// available also @ https://gist.github.com/elvanja/ed543c02b8e24637cd8c |
|
var DynamicSlider = function() { |
|
var config = { |
|
wrapperSelector: '#slider-bar-wrap', |
|
barSelector: '#slider-bar', |
|
paneSelector: '#slider-pane', |
|
contentSelector: '#slider-content', |
|
paddingRight: 0, |
|
focus: true |
|
}; |
|
|
|
var wrapper; |
|
var bar; |
|
var pane; |
|
var content; |
|
var slider; |
|
|
|
var init = function(_config) { |
|
$.extend(true, config, _config); |
|
|
|
wrapper = $(config.wrapperSelector); |
|
bar = $(config.barSelector); |
|
pane = $(config.paneSelector); |
|
content = $(config.contentSelector); |
|
|
|
content.size() === 0 ? hide() : apply(); |
|
}; |
|
|
|
var apply = function() { |
|
var itemCount = content.find('>div').length; |
|
var itemWidth = content.find('>div:eq(0)').outerWidth(true); |
|
var totalWidth = itemCount * itemWidth; |
|
|
|
if (totalWidth > pane.outerWidth()) { |
|
content.width(totalWidth); |
|
show(); |
|
} else { |
|
hide(); |
|
} |
|
}; |
|
|
|
var show = function() { |
|
build(); |
|
resetValue(); |
|
sizeScrollbar(); |
|
reflowContent(); |
|
}; |
|
|
|
var build = function() { |
|
wrapper.data('visible', 'visible').attr('data-visible', 'visible'); |
|
|
|
// create slider if not there already |
|
if (bar.children('.ui-handle-helper-parent').size() === 0) { |
|
bar.append("<div class='ui-handle-helper-parent'></div>"); |
|
} |
|
bar.addClass('ui-widget ui-widget-content ui-corner-all'); // normally added by jQueryUI slider |
|
|
|
// fix for clicking the bar outside the slider |
|
bar.click(function (event) { |
|
var mouseX = event.pageX; |
|
var sliderX = slider.offset().left; |
|
|
|
if (mouseX < sliderX || mouseX > (sliderX + slider.width())) { |
|
var handleWidth = slider.find(".ui-slider-handle").first().width(); |
|
var barX = bar.offset().left; |
|
var percentage = Math.round(((mouseX - handleWidth / 2) - barX) / (bar.width() - handleWidth) * 100); |
|
slider.slider("value", percentage); // value < min && value > max are OK with slider, no need to fix |
|
} |
|
}); |
|
|
|
slider = bar.find('.ui-handle-helper-parent').first(); |
|
slider.css({ |
|
"border-width": 0, |
|
"background-color": 'transparent' |
|
}); |
|
slider.slider({ |
|
slide: slide, // reacts to mouse drag |
|
change: slide // reacts to setting the value from code, @see bar click fix above |
|
}); |
|
|
|
if (config.focus === true) { |
|
slider.find(".ui-slider-handle").focus(); |
|
} |
|
}; |
|
|
|
var slide = function(event, ui) { |
|
var position = 0; |
|
if (content.width() > pane.width()) { |
|
var remainder = pane.width() - content.width() + config.paddingRight; |
|
position = Math.round(ui.value / 100 * remainder); |
|
} |
|
content.css("margin-left", position + 'px'); |
|
}; |
|
|
|
var resetValue = function() { |
|
var remainder = pane.width() - content.width(); |
|
var position = content.css("margin-left") === "auto" ? 0 : parseInt(content.css("margin-left")); |
|
var percentage = Math.round(position / remainder * 100); |
|
slider.slider("value", percentage); |
|
}; |
|
|
|
var sizeScrollbar = function() { |
|
var proportion = Math.min(pane.width() / content.width(), 1); |
|
var handleWidth = bar.width() * proportion; |
|
var handleParentWidth = bar.width() - handleWidth; |
|
|
|
slider.css({ |
|
width: handleParentWidth + 'px' |
|
}); |
|
|
|
slider.find(".ui-slider-handle").css({ |
|
width: handleWidth + 'px', |
|
"margin-left": -(handleWidth / 2) + 'px' |
|
}); |
|
}; |
|
|
|
var reflowContent = function() { |
|
var showing = content.width() + parseInt(content.css("margin-left"), 10); |
|
var gap = pane.width() - showing; |
|
|
|
if (gap > 0) { |
|
content.css("margin-left", parseInt(content.css("margin-left"), 10) + gap); |
|
} |
|
}; |
|
|
|
var hide = function() { |
|
wrapper.data('visible', 'hidden').attr('data-visible', 'hidden'); |
|
if (slider && slider.slider('instance')) { |
|
slider.slider("destroy").empty(); |
|
} |
|
content.css("margin-left", '0px'); // return to normal position |
|
}; |
|
|
|
var unbindEvents = function() { |
|
$(window).off('resize'); |
|
}; |
|
|
|
var bindEvents = function() { |
|
$(window).on('resize', function() { |
|
apply(); |
|
}); |
|
}; |
|
|
|
unbindEvents(); |
|
bindEvents(); |
|
|
|
return { |
|
init: init |
|
}; |
|
}; |
|
|
|
// source: http://css-tricks.com/snippets/javascript/lighten-darken-color/ |
|
function LightenDarkenColor(col, amt) { |
|
var usePound = false; |
|
|
|
if (col[0] == "#") { |
|
col = col.slice(1); |
|
usePound = true; |
|
} |
|
|
|
var num = parseInt(col, 16); |
|
|
|
var r = (num >> 16) + amt; |
|
|
|
if (r > 255) r = 255; |
|
else if (r < 0) r = 0; |
|
|
|
var b = ((num >> 8) & 0x00FF) + amt; |
|
|
|
if (b > 255) b = 255; |
|
else if (b < 0) b = 0; |
|
|
|
var g = (num & 0x0000FF) + amt; |
|
|
|
if (g > 255) g = 255; |
|
else if (g < 0) g = 0; |
|
|
|
return (usePound?"#":"") + (g | (b << 8) | (r << 16)).toString(16); |
|
} |
|
|
|
function getRandomInt(min, max) { |
|
return Math.floor(Math.random() * (max - min + 1)) + min; |
|
} |
|
|
|
// content generator |
|
var Generator = function() { |
|
var generate = function() { |
|
var content = $("#slider-content"); |
|
|
|
var firstRun = $('.box').size() === 0; |
|
var colors = ['#F00000', '#FF4500', '#FFA500', '#FFD700', '#FFFF00']; |
|
var color = colors[0]; |
|
var count = 12; |
|
|
|
if (firstRun === false) { |
|
var previousColor = $('.box').first().data('background-color'); |
|
colors.splice(colors.indexOf(previousColor), 1); |
|
color = colors[getRandomInt(0, colors.length - 1)]; |
|
count = getRandomInt(5, 15); |
|
} |
|
|
|
var startColor = color; |
|
|
|
content.empty(); |
|
for(var i = 0; i < count; i++) { |
|
content.append('<div class="box"/>'); |
|
$('.box').last().css('background-color', color); |
|
color = LightenDarkenColor(color, -15); |
|
} |
|
$('.box').first().data('background-color', startColor); |
|
|
|
new DynamicSlider().init(); |
|
} |
|
|
|
return { |
|
generate: generate |
|
}; |
|
} |
|
|
|
new Generator().generate(); |