/* * Basic jQuery Slider plug-in v.1.3 * * http://www.basic-slider.com * * Authored by John Cobb * http://www.johncobb.name * @john0514 * * Copyright 2011, John Cobb * License: GNU General Public License, version 3 (GPL-3.0) * http://www.opensource.org/licenses/gpl-3.0.html * */ ;(function($) { "use strict"; $.fn.bjqs = function(o) { // slider default settings var defaults = { // w + h to enforce consistency width : 700, height : 300, // transition valuess animtype : 'fade', animduration : 450, // length of transition animspeed : 4000, // delay between transitions automatic : true, // enable/disable automatic slide rotation // control and marker configuration showcontrols : true, // enable/disable next + previous UI elements centercontrols : true, // vertically center controls nexttext : 'Next', // text/html inside next UI element prevtext : 'Prev', // text/html inside previous UI element showmarkers : true, // enable/disable individual slide UI mark ers centermarkers : true, // horizontally center markers // interaction values keyboardnav : true, // enable/disable keyboard navigation hoverpause : true, // enable/disable pause slides on hover // presentational options usecaptions : true, // enable/disable captions using img title attribute randomstart : false, // start from a random slide responsive : false, // enable responsive behaviour existmarkers : false, existcontrols : false }; // create settings from defauls and user options var settings = $.extend({}, defaults, o); // slider elements var $wrapper = this, $slider = $wrapper.find('div.bjqs'), $slides = $slider.children('div'), // control elements $c_wrapper = null, $c_fwd = null, $c_prev = null, // marker elements $m_wrapper = null, $m_markers = null, // elements for slide animation $canvas = null, $clone_first = null, $clone_last = null; // state management object var state = { slidecount : $slides.length, // total number of slides animating : false, // bool: is transition is progress paused : false, // bool: is the slider paused currentslide : 1, // current slide being viewed (not 0 based) nextslide : 0, // slide to view next (not 0 based) currentindex : 0, // current slide being viewed (0 based) nextindex : 0, // slide to view next (0 based) interval : null // interval for automatic rotation }; var responsive = { width : null, height : null, ratio : null }; // helpful variables var vars = { fwd : 'forward', prev : 'previous' }; var bStart = false; // run through options and initialise settings var init = function() { // differentiate slider li from content li $slides.addClass('bjqs-slide'); // conf dimensions, responsive or static if( settings.responsive ) { conf_responsive(); } else { conf_static(); } // configurations only avaliable if more than 1 slide if( state.slidecount > 1 ){ // enable random start if (settings.randomstart){ conf_random(); } // create and show controls if( settings.showcontrols ){ conf_controls(); } // create and show markers if( settings.showmarkers ){ conf_markers(); } // enable slidenumboard navigation if( settings.keyboardnav ){ conf_keynav(); } // enable pause on hover if (settings.hoverpause && settings.automatic){ conf_hoverpause(); } // conf slide animation if (settings.animtype === 'slide'){ conf_slide(); } } else { // Stop automatic animation, because we only have one slide! settings.automatic = false; } if(settings.usecaptions){ conf_captions(); } // TODO: need to accomodate random start for slide transition setting if(settings.animtype === 'slide' && !settings.randomstart){ state.currentindex = 1; state.currentslide = 2; } // slide components are hidden by default, show them now $slider.show(); $slides.eq(state.currentindex).show(); // Finally, if automatic is set to true, kick off the interval if(settings.automatic){ state.interval = setInterval(function () { go(vars.fwd, false); }, settings.animspeed); } }; var conf_responsive = function() { responsive.width = $wrapper.outerWidth(); responsive.ratio = responsive.width/settings.width, responsive.height = settings.height * responsive.ratio; if(settings.animtype === 'fade') { // initial setup $slides.css({ 'height' : settings.height, 'width' : '100%' }); $slides.children('img').css({ 'height' : settings.height, 'width' : '100%' }); $slider.css({ 'height' : settings.height, 'width' : '100%' }); $wrapper.css({ 'height' : settings.height, //'max-width' : settings.width, 'position' : 'relative' }); if(responsive.width < settings.width) { $slides.css({ 'height' : responsive.height }); $slides.children('img').css({ 'height' : responsive.height }); $slider.css({ 'height' : responsive.height }); $wrapper.css({ 'height' : responsive.height }); } $(window).on("resize", function() { // calculate and update dimensions responsive.width = $slides.width(); if(settings.width <= 0) settings.width = responsive.width ; responsive.ratio = responsive.width / settings.width; if(responsive.ratio == Number.POSITIVE_INFINITY || responsive.ratio == Number.NEGATIVE_INFINITY) { alert(responsive.ratio); } //alert(responsive.width+"/"+responsive.height); if(settings.height <= 0) { responsive.height = $slides.find("img").height(); } else { responsive.height = settings.height * responsive.ratio; } $slides.css({ 'height' : responsive.height, 'width' : '100%' }); $slides.children('img').css({ 'height' : responsive.height, 'width' : '100%' }); $slider.css({ 'height' : responsive.height, 'width' : '100%' }); $wrapper.css({ 'height' : responsive.height, 'width' : '100%' }); }); } if(settings.animtype === 'slide') { // initial setup $slides.css({ 'height' : settings.height, 'width' : settings.width }); $slides.children('img').css({ 'height' : settings.height, 'width' : settings.width }); $slider.css({ 'position' : 'relative', 'float' : 'left', 'height' : settings.height, 'width' : settings.width * settings.slidecount, 'margin' : 'auto 0' }); $wrapper.css({ 'height' : settings.height, //'max-width' : settings.width, 'position' : 'relative' }); if(responsive.width < settings.width) { $slides.css({ 'height' : responsive.height }); $slides.children('img').css({ 'height' : responsive.height }); $slider.css({ 'height' : responsive.height }); $wrapper.css({ 'height' : responsive.height }); } $(window).resize(function() { // calculate and update dimensions //responsive.width = $wrapper.outerWidth(), responsive.width = $(window).width(), responsive.ratio = responsive.width/settings.width, //responsive.height = settings.height * responsive.ratio; responsive.height = settings.height; //alert($(window).width()); // calculate and update dimensions //responsive.width = $wrapper.outerWidth(), /*responsive.width = $(window).width(); if(settings.width <= 0) settings.width = responsive.width ; responsive.ratio = responsive.width/settings.width; //responsive.height = settings.height * responsive.ratio; if(settings.height <= 0){ responsive.height = $slides.find("img").height(); //alert(responsive.width+"/"+responsive.height); }else{ responsive.height = settings.height * responsive.ratio; }*/ if(window.matchMedia("(max-width:989px)").matches) { if(settings.height <= 0) { responsive.height = $slides.find("img").height(); } else { responsive.height = settings.height * responsive.ratio; } } $slides.css({ 'height' : responsive.height, 'width' : responsive.width }); $slides.children('img').css({ 'height' : responsive.height, 'width' : responsive.width }); $slider.css({ 'height' : responsive.height, 'width' : responsive.width * settings.slidecount }); $wrapper.css({ 'height' : responsive.height }); $canvas.css({ 'height' : responsive.height, 'width' : responsive.width }); resize_complete(function(){ go(false,state.currentslide); }, 200, "some unique string"); }); } }; var resize_complete = (function () { var timers = {}; return function (callback, ms, uniqueId) { if (!uniqueId) { uniqueId = "Don't call this twice without a uniqueId"; } if (timers[uniqueId]) { clearTimeout (timers[uniqueId]); } timers[uniqueId] = setTimeout(callback, ms); }; })(); // enforce fixed sizing on slides, slider and wrapper var conf_static = function() { $slides.css({ 'height' : settings.height, 'width' : settings.width }); $slider.css({ 'height' : settings.height, 'width' : settings.width }); $wrapper.css({ 'height' : settings.height, 'width' : settings.width, 'position' : 'relative' }); }; var conf_slide = function() { // create two extra elements which are clones of the first and last slides $clone_first = $slides.eq(0).clone(); $clone_last = $slides.eq(state.slidecount-1).clone(); // add them to the DOM where we need them $clone_first.attr({'data-clone' : 'last', 'data-slide' : 0}).appendTo($slider).show(); $clone_last.attr({'data-clone' : 'first', 'data-slide' : 0}).prependTo($slider).show(); // update the elements object $slides = $slider.children('div'); state.slidecount = $slides.length; // create a 'canvas' element which is neccessary for the slide animation to work $canvas = $('
'); // if the slider is responsive && the calculated width is less than the max width if(settings.responsive && (responsive.width < settings.width)){ $canvas.css({ 'width' : responsive.width, 'height' : responsive.height, 'overflow' : 'hidden', 'position' : 'relative' }); // update the dimensions to the slider to accomodate all the slides side by side $slider.css({ 'width' : responsive.width * (state.slidecount + 2), 'left' : -responsive.width * state.currentslide }); } else { $canvas.css({ 'width' : settings.width, 'height' : settings.height, 'overflow' : 'hidden', 'position' : 'relative' }); // update the dimensions to the slider to accomodate all the slides side by side $slider.css({ 'width' : settings.width * (state.slidecount + 2), 'left' : -settings.width * state.currentslide }); } // add some inline styles which will align our slides for left-right sliding $slides.css({ 'float' : 'left', 'position' : 'relative' //'display' : 'list-item' }); // 'everything.. in it's right place' $canvas.prependTo($wrapper); $slider.appendTo($canvas); }; var conf_controls = function() { if(!settings.existcontrols){ // create the elements for the controls $c_wrapper = $(''); $c_fwd = $('
  • ' + settings.nexttext + '
  • '); $c_prev = $('
  • ' + settings.prevtext + '
  • '); // bind click events $c_wrapper.on('click','a', function(e) { e.preventDefault(); var direction = $(this).attr('data-direction'); if(!state.animating) { if(direction === vars.fwd) { go(vars.fwd, false); } if(direction === vars.prev) { go(vars.prev, false); } } }); // put 'em all together $c_prev.appendTo($c_wrapper); $c_fwd.appendTo($c_wrapper); $c_wrapper.appendTo($wrapper); // vertically center the controls if (settings.centercontrols) { $c_wrapper.addClass('v-centered'); // calculate offset % for vertical positioning var offset_px = ($wrapper.height() - $c_fwd.children('a').outerHeight()) / 2, ratio = (offset_px / settings.height) * 100, offset = ratio + '%'; $c_fwd.find('a').css('top', offset); $c_prev.find('a').css('top', offset); } } else { $wrapper.find(".bjqs-next").on('click', 'a', function(e) { e.preventDefault(); var direction = $(this).attr('data-direction'); if(!state.animating) { go(direction, false); } }); $wrapper.find(".bjqs-prev").on('click', 'a', function(e) { e.preventDefault(); var direction = $(this).attr('data-direction'); if(!state.animating){ go(direction, false); } }); } }; var conf_markers = function() { if(!settings.existmarkers) { // create a wrapper for our markers $m_wrapper = $(''); // for every slide, create a marker $.each($slides, function(key, slide){ var slidenum = key + 1, gotoslide = key + 1; if(settings.animtype === 'slide'){ // + 2 to account for clones gotoslide = key + 2; } var marker = $('
  • '+ slidenum +'
  • '); // set the first marker to be active if(slidenum === state.currentslide){ marker.addClass('active-marker'); } // bind the click event marker.on('click','a',function(e){ e.preventDefault(); if(!state.animating && state.currentslide !== gotoslide){ go(false,gotoslide); } }); // add the marker to the wrapper marker.appendTo($m_wrapper); }); //$m_wrapper.appendTo($wrapper); $wrapper.prepend($m_wrapper); $m_markers = $m_wrapper.find('li'); // center the markers if (settings.centermarkers) { $m_wrapper.addClass('h-centered'); var offset = (settings.width - $m_wrapper.width()) / 2; $m_wrapper.css('left', offset); } } else{ var markers_obj = ($wrapper.find(".bjqs-markers").length)? $wrapper.find(".bjqs-markers") : $wrapper.parent().find(".bjqs-markers"); markers_obj.each(function(i){ var slidenum = i + 1, gotoslide = i + 1; if(settings.animtype === 'slide') { // + 2 to account for clones gotoslide = i + 2; } $(this).on('click','a',function(e) { e.preventDefault(); if(!state.animating && state.currentslide !== gotoslide) { go(false,gotoslide); } }); }); $m_markers = markers_obj; } /******* 시작 버튼 *******/ $slider.parent().find(".bjqs-control-start").on('click','a',function(e) { e.preventDefault(); if(!state.animating){ go(vars.fwd, false); state.interval = setInterval(function () { go(vars.fwd, false); }, settings.animspeed); state.paused = false; $(this).parent().hide(); $(this).parent().parent().find(".bjqs-control-pause").show(); } }); /******* 정지 버튼 *******/ $slider.parent().find(".bjqs-control-pause").on('click','a',function(e) { e.preventDefault(); if (!state.paused) { clearInterval(state.interval); state.paused = true; $(this).parent().hide(); $(this).parent().parent().find(".bjqs-control-start").show(); } }); }; var conf_keynav = function() { $(document).keyup(function (event) { if (!state.paused) { clearInterval(state.interval); state.paused = true; } if (!state.animating) { if (event.keyCode === 39) { event.preventDefault(); go(vars.fwd, false); } else if (event.keyCode === 37) { event.preventDefault(); go(vars.prev, false); } } if (state.paused && settings.automatic) { state.interval = setInterval(function () { go(vars.fwd); }, settings.animspeed); state.paused = false; } }); }; var conf_hoverpause = function() { $wrapper.hover(function () { if (!state.paused) { clearInterval(state.interval); state.paused = true; } }, function () { if (state.paused) { state.interval = setInterval(function () { go(vars.fwd, false); }, settings.animspeed); state.paused = false; } }); }; var conf_captions = function() { $.each($slides, function (key, slide) { var caption = $(slide).children('img:first-child').attr('title'); // Account for images wrapped in links if(!caption){ caption = $(slide).children('a').find('img:first-child').attr('title'); } if (caption) { caption = $('

    ' + caption + '

    '); caption.appendTo($(slide)); } }); }; var conf_random = function() { var rand = Math.floor(Math.random() * state.slidecount) + 1; state.currentslide = rand; state.currentindex = rand-1; }; var set_next = function(direction) { if(direction === vars.fwd){ if($slides.eq(state.currentindex).next().length){ state.nextindex = state.currentindex + 1; state.nextslide = state.currentslide + 1; } else{ state.nextindex = 0; state.nextslide = 1; } } else{ if($slides.eq(state.currentindex).prev().length) { state.nextindex = state.currentindex - 1; state.nextslide = state.currentslide - 1; } else { state.nextindex = state.slidecount - 1; state.nextslide = state.slidecount; } } }; var go = function(direction, position) { // only if we're not already doing things if(!state.animating) { // doing things state.animating = true; if(position) { state.nextslide = position; state.nextindex = position-1; } else { set_next(direction); } // fade animation if(settings.animtype === 'fade') { if(settings.showmarkers) { $m_markers.removeClass('active-marker'); if($m_markers.find("a > img").length > 0) { if($m_markers.find("a > img").attr("src").indexOf(".png") != -1) $m_markers.find("a > img").attr("src",$m_markers.find("a > img").attr("src").replace("on.png","off.png")); else if($m_markers.find("a > img").attr("src").indexOf(".gif") != -1) $m_markers.find("a > img").attr("src",$m_markers.find("a > img").attr("src").replace("on.gif","off.gif")); } $m_markers.eq(state.nextindex).addClass('active-marker'); if($m_markers.eq(state.nextindex).find("a > img").length > 0) { if($m_markers.eq(state.nextindex).find("a > img").attr("src").indexOf(".png") != -1) $m_markers.eq(state.nextindex).find("a > img").attr("src",$m_markers.eq(state.nextindex).find("a > img").attr("src").replace("off.png","on.png")); else if($m_markers.eq(state.nextindex).find("a > img").attr("src").indexOf(".gif") != -1) $m_markers.eq(state.nextindex).find("a > img").attr("src",$m_markers.eq(state.nextindex).find("a > img").attr("src").replace("off.gif","on.gif")); } } // fade out current $slides.eq(state.currentindex).fadeOut(settings.animduration); // fade in next $slides.eq(state.nextindex).fadeIn(settings.animduration, function() { // update state variables state.animating = false; state.currentslide = state.nextslide; state.currentindex = state.nextindex; }); } // slide animation if(settings.animtype === 'slide') { if(settings.showmarkers) { var markerindex = state.nextindex - 1; if(markerindex === state.slidecount - 2) { markerindex = 0; } else if(markerindex === -1) { markerindex = state.slidecount - 3; } $m_markers.removeClass('active-marker'); //버튼 오프 if($m_markers.find("a > img").length > 0) { if($m_markers.find("a > img").attr("src").indexOf(".png") != -1) $m_markers.find("a > img").attr("src",$m_markers.find("a > img").attr("src").replace("on.png","off.png")); else if($m_markers.find("a > img").attr("src").indexOf(".gif") != -1) $m_markers.find("a > img").attr("src",$m_markers.find("a > img").attr("src").replace("on.gif","off.gif")); } //클래스 오프 $m_markers.removeClass('on'); $m_markers.addClass('off'); $m_markers.eq(markerindex).addClass('active-marker'); //버튼 온 if($m_markers.eq(markerindex).find("a > img").length>0){ if($m_markers.eq(markerindex).find("a > img").attr("src").indexOf(".png") != -1) $m_markers.eq(markerindex).find("a > img").attr("src",$m_markers.eq(markerindex).find("a > img").attr("src").replace("off.png","on.png")); else if($m_markers.eq(markerindex).find("a > img").attr("src").indexOf(".gif") != -1) $m_markers.eq(markerindex).find("a > img").attr("src",$m_markers.eq(markerindex).find("a > img").attr("src").replace("off.gif","on.gif")); } //클래스 오프 $m_markers.eq(markerindex).removeClass('off'); $m_markers.eq(markerindex).addClass('on'); /*$m_markers.eq(markerindex).find("a > img").attr("src",$m_markers.eq(markerindex).find("a > img").attr("src").replace("off.png","on.png")); $m_markers.eq(markerindex).removeClass('tab_off'); $m_markers.eq(markerindex).addClass('tab_on');*/ } // if the slider is responsive && the calculated width is less than the max width if(settings.responsive && ( responsive.width < settings.width )) { state.slidewidth = responsive.width; if($slides.parent().parent().parent().attr("id") == "visual_bottom_rolling") { state.slidewidth = 1190; } } else { //state.slidewidth = settings.width; state.slidewidth = $(window).width(); if($slides.parent().parent().parent().attr("id") == "visual_bottom_rolling") { state.slidewidth = 1190; } } $slider.animate({'left': -state.nextindex * state.slidewidth }, settings.animduration, function() { //console.log(state.nextindex + " * " + state.slidewidth); state.currentslide = state.nextslide; state.currentindex = state.nextindex; // is the current slide a clone? if($slides.eq(state.currentindex).attr('data-clone') === 'last') { // affirmative, at the last slide (clone of first) $slider.css({'left': -state.slidewidth }); state.currentslide = 2; state.currentindex = 1; } else if($slides.eq(state.currentindex).attr('data-clone') === 'first') { // affirmative, at the fist slide (clone of last) $slider.css({'left': -state.slidewidth * (state.slidecount - 2)}); state.currentslide = state.slidecount - 1; state.currentindex = state.slidecount - 2; } state.animating = false; }); } } }; // lets get the party started :) init(); }; })(jQuery);