1/* 2 * Basic jQuery Slider plug-in v.1.3 3 * 4 * http://www.basic-slider.com 5 * 6 * Authored by John Cobb 7 * http://www.johncobb.name 8 * @john0514 9 * 10 * Copyright 2011, John Cobb 11 * License: GNU General Public License, version 3 (GPL-3.0) 12 * http://www.opensource.org/licenses/gpl-3.0.html 13 * 14 */ 15 16;(function($) { 17 18 "use strict"; 19 20 $.fn.bjqs = function(o) { 21 22 // slider default settings 23 var defaults = { 24 25 // w + h to enforce consistency 26 width : bjqsW, 27 height : bjqsH, 28 29 // transition valuess 30 animtype : 'fade', 31 animduration : 450, // length of transition 32 animspeed : 4000, // delay between transitions 33 automatic : true, // enable/disable automatic slide rotation 34 35 // control and marker configuration 36 showcontrols : true, // enable/disable next + previous UI elements 37 centercontrols : true, // vertically center controls 38 nexttext : 'Next', // text/html inside next UI element 39 prevtext : 'Prev', // text/html inside previous UI element 40 showmarkers : true, // enable/disable individual slide UI markers 41 centermarkers : true, // horizontally center markers 42 43 // interaction values 44 keyboardnav : true, // enable/disable keyboard navigation 45 hoverpause : true, // enable/disable pause slides on hover 46 47 // presentational options 48 usecaptions : true, // enable/disable captions using img title attribute 49 randomstart : false, // start from a random slide 50 responsive : true // enable responsive behaviour 51 52 }; 53 54 // create settings from defauls and user options 55 var settings = $.extend({}, defaults, o); 56 57 // slider elements 58 var $wrapper = this, 59 $slider = $wrapper.find('ul.bjqs'), 60 $slides = $slider.children('li'), 61 62 // control elements 63 $c_wrapper = null, 64 $c_fwd = null, 65 $c_prev = null, 66 67 // marker elements 68 $m_wrapper = null, 69 $m_markers = null, 70 71 // elements for slide animation 72 $canvas = null, 73 $clone_first = null, 74 $clone_last = null; 75 76 // state management object 77 var state = { 78 slidecount : $slides.length, // total number of slides 79 animating : false, // bool: is transition is progress 80 paused : false, // bool: is the slider paused 81 currentslide : 1, // current slide being viewed (not 0 based) 82 nextslide : 0, // slide to view next (not 0 based) 83 currentindex : 0, // current slide being viewed (0 based) 84 nextindex : 0, // slide to view next (0 based) 85 interval : null // interval for automatic rotation 86 }; 87 88 var responsive = { 89 width : null, 90 height : null, 91 ratio : null 92 }; 93 94 // helpful variables 95 var vars = { 96 fwd : 'forward', 97 prev : 'previous' 98 }; 99 100 // run through options and initialise settings 101 var init = function() { 102 103 settings.width = $wrapper.outerWidth(); 104 105 // differentiate slider li from content li 106 $slides.addClass('bjqs-slide'); 107 108 // conf dimensions, responsive or static 109 if( settings.responsive ){ 110 conf_responsive(); 111 } 112 else{ 113 conf_static(); 114 } 115 116 // configurations only avaliable if more than 1 slide 117 if( state.slidecount > 1 ){ 118 119 // enable random start 120 if (settings.randomstart){ 121 conf_random(); 122 } 123 124 // create and show controls 125 if( settings.showcontrols ){ 126 conf_controls(); 127 } 128 129 // create and show markers 130 if( settings.showmarkers ){ 131 conf_markers(); 132 } 133 134 // enable slidenumboard navigation 135 if( settings.keyboardnav ){ 136 conf_keynav(); 137 } 138 139 // enable pause on hover 140 if (settings.hoverpause && settings.automatic){ 141 conf_hoverpause(); 142 } 143 144 // conf slide animation 145 if (settings.animtype === 'slide'){ 146 conf_slide(); 147 } 148 149 } else { 150 // Stop automatic animation, because we only have one slide! 151 settings.automatic = false; 152 } 153 154 if(settings.usecaptions){ 155 conf_captions(); 156 } 157 158 // TODO: need to accomodate random start for slide transition setting
159 if(settings.animtype === 'slide' && !settings.randomstart){ 160 state.currentindex = 1; 161 state.currentslide = 2; 162 } 163 164 // slide components are hidden by default, show them now 165 $slider.show(); 166 $slides.eq(state.currentindex).show(); 167 168 // Finally, if automatic is set to true, kick off the interval 169 if(settings.automatic){ 170 state.interval = setInterval(function () { 171 go(vars.fwd, false); 172 }, settings.animspeed); 173 } 174 175 }; 176 177 var conf_responsive = function () { 178 179 responsive.width = $wrapper.outerWidth(); 180 responsive.ratio = responsive.width / settings.width; 181 responsive.height = settings.height * responsive.ratio; 182 183 if (settings.animtype === 'fade') { 184 185 // initial setup 186 $slides.css({ 187 'height': settings.height, 188 'width': '100%' 189 }); 190 $slides.find('img').css({ 191 'height': settings.height, 192 'width': '100%' 193 }); 194 $slider.css({ 195 'height': settings.height, 196 'width': '100%' 197 }); 198 $wrapper.css({ 199 'height': settings.height, 200 'max-width': settings.width, 201 'position': 'relative' 202 }); 203 204 if (responsive.width < settings.width) { 205 206 $slides.css({ 207 'height': responsive.height 208 }); 209 $slides.find('img').css({ 210 'height': responsive.height 211 }); 212 $slider.css({ 213 'height': responsive.height 214 }); 215 $wrapper.css({ 216 'height': responsive.height 217 }); 218 219 } 220 221 $(window).resize(function () { 222 223 // calculate and update dimensions 224 responsive.width = $wrapper.outerWidth(); 225 responsive.ratio = responsive.width / settings.width; 226 responsive.height = settings.height * responsive.ratio; 227 228 $slides.css({ 229 'height': responsive.height 230 }); 231 $slides.find('img').css({ 232 'height': responsive.height 233 }); 234 $slider.css({ 235 'height': responsive.height 236 }); 237 $wrapper.css({ 238 'height': responsive.height 239 }); 240 241 }); 242 243 } 244 245 if (settings.animtype === 'slide') { 246 247 // initial setup 248 $slides.css({ 249 'height': 'auto', 250 'width': settings.width 251 }); 252 $slides.find('img').css({ 253 'height': 'auto', 254 'width': settings.width 255 }); 256 $slider.css({ 257 'height': 'auto', 258 'width': $wrapper.outerWidth() * (state.slidecount + 2) 259 }); 260 $wrapper.css({ 261 'height': 'auto', 262 'max-width': settings.width, 263 'position': 'relative' 264 }); 265 266 if (responsive.width < settings.width) { 267 268 $slides.css({ 269 'height': 'auto' 270 }); 271 $slides.find('img').css({ 272 'height': 'auto' 273 }); 274 $slider.css({ 275 'height': 'auto' 276 }); 277 $wrapper.css({ 278 'height': 'auto' 279 }); 280 281 } 282 283 $(window).resize(function () { 284 285 // calculate and update dimensions 286 responsive.width = $wrapper.outerWidth(); 287 responsive.ratio = responsive.width / settings.width; 288 responsive.height = 'auto'; 289 290 $slides.css({ 291 'height': 'auto', 292 'width': responsive.width 293 }); 294 $slides.find('img').css({ 295 'height': 'auto', 296 'width': responsive.width 297 }); 298 $slider.css({ 299 'height': 'auto', 300 'width': responsive.width * settings.slidecount 301 }); 302 $wrapper.css({ 303 'height': 'auto' 304 }); 305 if ($canvas && $canvas.length) { 306 $canvas.css({ 307 'height': 'auto', 308 'width': responsive.width 309 }); 310 } 311 resize_complete(function () { 312 go(false, state.currentslide); 313 }, 200, "some unique string"); 314 315 }); 316 317 } 318 319 }; 320 321 322 var resize_complete = (function () { 323 324 var timers = {}; 325 326 return function (callback, ms, uniqueId) { 327 if (!uniqueId) { 328 uniqueId = "Don't call this twice without a uniqueId"; 329 } 330 if (timers[uniqueId]) { 331 clearTimeout (timers[uniqueId]); 332 } 333 timers[uniqueId] = setTimeout(callback, ms); 334 }; 335 336 })(); 337 338 // enforce fixed sizing on slides, slider and wrapper 339 var conf_static = function() { 340 341 $slides.css({ 342 'height' : 'auto', 343 'width' : settings.width 344 }); 345 $slider.css({ 346 'height' : 'auto', 347 'width' : settings.width 348 }); 349 $wrapper.css({ 350 'height' : 'auto', 351 'width' : settings.width, 352 'position' : 'relative' 353 }); 354 355 }; 356 357 var conf_slide = function() { 358 359 // create two extra elements which are clones of the first and last slides 360 $clone_first = $slides.eq(0).clone(); 361 $clone_last = $slides.eq(state.slidecount-1).clone(); 362 363 // add them to the DOM where we need them
364 $clone_first.attr({'data-clone' : 'last', 'data-slide' : 0}).appendTo($slider).show(); 365 $clone_last.attr({'data-clone' : 'first', 'data-slide' : 0}).prependTo($slider).show(); 366 367 // update the elements object 368 $slides = $slider.children('li'); 369 state.slidecount = $slides.length; 370 371 // create a 'canvas' element which is neccessary for the slide animation to work 372 $canvas = $('<div class="bjqs-wrapper"></div>'); 373 374 // if the slider is responsive && the calculated width is less than the max width 375 if(settings.responsive ){ //&& (responsive.width < settings.width) 376 377 $canvas.css({ 378 'width' : responsive.width, 379 'height' : 'auto', 380 'overflow' : 'hidden', 381 'position' : 'relative' 382 }); 383 384 // update the dimensions to the slider to accomodate all the slides side by side 385 $slider.css({ 386 'width' : responsive.width * state.slidecount, 387 'left' : -responsive.width * state.currentslide 388 }); 389 390 } 391 else { 392 393 $canvas.css({ 394 'width' : settings.width, 395 'height' : 'auto', 396 'overflow' : 'hidden', 397 'position' : 'relative' 398 }); 399 400 // update the dimensions to the slider to accomodate all the slides side by side 401 $slider.css({ 402 'width' : settings.width * state.slidecount, 403 'left' : -settings.width * state.currentslide 404 }); 405 406 } 407 408 // add some inline styles which will align our slides for left-right sliding 409 $slides.css({ 410 'float' : 'left', 411 'position' : 'relative', 412 'display' : 'list-item' 413 }); 414 415 // 'everything.. in it's right place' 416 $canvas.prependTo($wrapper); 417 $slider.appendTo($canvas); 418 419 }; 420 421 var conf_controls = function() { 422 423 // create the elements for the controls 424 $c_wrapper = $('<ul class="bjqs-controls"></ul>'); 425 $c_fwd = $('<li class="bjqs-next"><a href="#" data-direction="' + vars.fwd + '"><img src="/images/next_arrow.png" alt="Next Slide"></a></li>'); 426 $c_prev = $('<li class="bjqs-prev"><a href="#" data-direction="' + vars.prev + '"><img src="/images/prev_arrow.png" alt="Previous Slide"></a></li>'); 427 428 429 430 // bind click events 431 $c_wrapper.on('click','a',function(e){ 432 433 e.preventDefault(); 434 var direction = $(this).attr('data-direction'); 435 436 if(!state.animating){ 437 438 if(direction === vars.fwd){ 439 go(vars.fwd,false); 440 } 441 442 if(direction === vars.prev){ 443 go(vars.prev,false); 444 } 445 446 } 447 448 }); 449 450 // put 'em all together 451 $c_prev.appendTo($c_wrapper); 452 $c_fwd.appendTo($c_wrapper); 453 $c_wrapper.appendTo($wrapper); 454 455 // vertically center the controls 456 if (settings.centercontrols) { 457 458 $c_wrapper.addClass('v-centered'); 459 460 // calculate offset % for vertical positioning 461 var offset_px = ($wrapper.height() - $c_fwd.children('a').outerHeight()) / 2, 462 ratio = (offset_px) * 100, 463 offset = ratio + '%'; 464 465 $c_fwd.find('a').css('top', offset); 466 $c_prev.find('a').css('top', offset); 467 468 } 469 470 }; 471 472 var conf_markers = function() { 473 474 // create a wrapper for our markers 475 $m_wrapper = $('<ol class="bjqs-markers"></ol>'); 476 477 // for every slide, create a marker 478 $.each($slides, function(key, slide){ 479
480 var slidenum = key + 1, 481 gotoslide = key + 1; 482 483 if(settings.animtype === 'slide'){ 484 // + 2 to account for clones 485 gotoslide = key + 2; 486 } 487 488 var marker = $('<li><a href="#" alt="Go To Slide"></a></li>'); 489 490 // set the first marker to be active 491 if(slidenum === state.currentslide){ marker.addClass('active-marker'); } 492 493 // bind the click event 494 marker.on('click','a',function(e){ 495 e.preventDefault(); 496 if(!state.animating && state.currentslide !== gotoslide){ 497 go(false,gotoslide); 498 } 499 }); 500 501 // add the marker to the wrapper 502 marker.appendTo($m_wrapper); 503 504 }); 505 506 $m_wrapper.appendTo($wrapper); 507 $m_markers = $m_wrapper.find('li'); 508 509 // center the markers 510 if (settings.centermarkers) { 511 $m_wrapper.addClass('h-centered'); 512 var offset = (settings.width - $m_wrapper.width()) / 2; 513 $m_wrapper.css('left', offset); 514 } 515 516 }; 517 518 var conf_keynav = function() { 519 520 $(document).keyup(function (event) { 521 522 if (!state.paused) { 523 clearInterval(state.interval); 524 state.paused = true; 525 } 526 527 if (!state.animating) { 528 if (event.keyCode === 39) { 529 event.preventDefault(); 530 go(vars.fwd, false); 531 } else if (event.keyCode === 37) { 532 event.preventDefault(); 533 go(vars.prev, false); 534 } 535 } 536 537 if (state.paused && settings.automatic) { 538 state.interval = setInterval(function () { 539 go(vars.fwd); 540 }, settings.animspeed); 541 state.paused = false; 542 } 543 544 }); 545 546 }; 547 548 var conf_hoverpause = function() { 549 550 $wrapper.hover(function () { 551 if (!state.paused) { 552 clearInterval(state.interval); 553 state.paused = true; 554 } 555 }, function () { 556 if (state.paused) { 557 state.interval = setInterval(function () { 558 go(vars.fwd, false); 559 }, settings.animspeed); 560 state.paused = false; 561 } 562 }); 563 564 }; 565 566 var conf_captions = function() { 567 568 $.each($slides, function (key, slide) { 569 570 var caption = $(slide).children('img:first-child').attr('title'); 571 572 // Account for images wrapped in links 573 if(!caption){ 574 caption = $(slide).children('a').find('img:first-child').attr('title'); 575 } 576 577 if (caption) { 578 caption = $('<p class="bjqs-caption">' + caption + '</p>'); 579 //caption.appendTo($(slide)); 580 } 581 582 }); 583 584 }; 585 586 var conf_random = function() { 587 588 var rand = Math.floor(Math.random() * state.slidecount) + 1; 589 state.currentslide = rand; 590 state.currentindex = rand-1; 591 592 }; 593 594 var set_next = function(direction) { 595 596 if(direction === vars.fwd){ 597 598 if($slides.eq(state.currentindex).next().length){ 599 state.nextindex = state.currentindex + 1; 600 state.nextslide = state.currentslide + 1; 601 } 602 else{ 603 state.nextindex = 0; 604 state.nextslide = 1; 605 } 606 607 } 608 else{ 609 610 if($slides.eq(state.currentindex).prev().length){ 611 state.nextindex = state.currentindex - 1; 612 state.nextslide = state.currentslide - 1; 613 } 614 else{ 615 state.nextindex = state.slidecount - 1; 616 state.nextslide = state.slidecount; 617 } 618 619 } 620 621 }; 622 623 var go = function(direction, position) { 624 625 // only if we're not already doing things 626 if(!state.animating){ 627 628 // doing things 629 state.animating = true; 630 631 if(position){ 632 state.nextslide = position; 633 state.nextindex = position-1; 634 } 635 else{ 636 set_next(direction); 637 } 638 639 // fade animation 640 if(settings.animtype === 'fade'){ 641 642 if(settings.showmarkers){ 643 $m_markers.removeClass('active-marker'); 644 $m_markers.eq(state.nextindex).addClass('active-marker'); 645 } 646 647 // fade out current 648 $slides.eq(state.currentindex).fadeOut(settings.animduration); 649 // fade in next 650 $slides.eq(state.nextindex).fadeIn(settings.animduration, function(){ 651 652 // update state variables 653 state.animating = false; 654 state.currentslide = state.nextslide; 655 state.currentindex = state.nextindex; 656 657 }); 658 659 } 660 661 // slide animation 662 if(settings.animtype === 'slide'){ 663 664 if(settings.showmarkers){ 665 666 var markerindex = state.nextindex-1; 667 668 if(markerindex === state.slidecount-2){ 669 markerindex = 0; 670 } 671 else if(markerindex === -1){ 672 markerindex = state.slidecount-3; 673 } 674 675 $m_markers.removeClass('active-marker'); 676 $m_markers.eq(markerindex).addClass('active-marker'); 677 } 678 679 // if the slider is responsive && the calculated width is less than the max width 680 if(settings.responsive && ( responsive.width < settings.width ) ){ 681 state.slidewidth = responsive.width; 682 } 683 else{ 684 state.slidewidth = settings.width; 685 } 686 687 $slider.animate({'left': -state.nextindex * state.slidewidth }, settings.animduration, function(){ 688 689 state.currentslide = state.nextslide; 690 state.currentindex = state.nextindex; 691 692 // is the current slide a clone? 693 if($slides.eq(state.currentindex).attr('data-clone') === 'last'){ 694 695 // affirmative, at the last slide (clone of first) 696 $slider.css({'left': -state.slidewidth }); 697 state.currentslide = 2; 698 state.currentindex = 1; 699 700 } 701 else if($slides.eq(state.currentindex).attr('data-clone') === 'first'){ 702 703 // affirmative, at the fist slide (clone of last) 704 $slider.css({'left': -state.slidewidth *(state.slidecount - 2)}); 705 state.currentslide = state.slidecount - 1; 706 state.currentindex = state.slidecount - 2; 707 708 } 709 710 state.animating = false; 711 712 }); 713 714 } 715 716 } 717 718 }; 719 720 // lets get the party started :) 721 init(); 722 723 }; 724 725})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.