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