Licitator 1.0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

881 lines
39 KiB

5 years ago
  1. /*
  2. * jQuery FlexSlider v2.1
  3. * http://www.woothemes.com/flexslider/
  4. *
  5. * Copyright 2012 WooThemes
  6. * Free to use under the GPLv2 license.
  7. * http://www.gnu.org/licenses/gpl-2.0.html
  8. *
  9. * Contributing author: Tyler Smith (@mbmufffin)
  10. */
  11. ;(function ($) {
  12. //FlexSlider: Object Instance
  13. $.flexslider = function(el, options) {
  14. var slider = $(el),
  15. vars = $.extend({}, $.flexslider.defaults, options),
  16. namespace = vars.namespace,
  17. touch = ("ontouchstart" in window) || window.DocumentTouch && document instanceof DocumentTouch,
  18. eventType = (touch) ? "touchend" : "click",
  19. vertical = vars.direction === "vertical",
  20. reverse = vars.reverse,
  21. carousel = (vars.itemWidth > 0),
  22. fade = vars.animation === "fade",
  23. asNav = vars.asNavFor !== "",
  24. methods = {};
  25. // Store a reference to the slider object
  26. $.data(el, "flexslider", slider);
  27. // Privat slider methods
  28. methods = {
  29. init: function() {
  30. slider.animating = false;
  31. slider.currentSlide = vars.startAt;
  32. slider.animatingTo = slider.currentSlide;
  33. slider.atEnd = (slider.currentSlide === 0 || slider.currentSlide === slider.last);
  34. slider.containerSelector = vars.selector.substr(0,vars.selector.search(' '));
  35. slider.slides = $(vars.selector, slider);
  36. slider.container = $(slider.containerSelector, slider);
  37. slider.count = slider.slides.length;
  38. // SYNC:
  39. slider.syncExists = $(vars.sync).length > 0;
  40. // SLIDE:
  41. if (vars.animation === "slide") vars.animation = "swing";
  42. slider.prop = (vertical) ? "top" : "marginLeft";
  43. slider.args = {};
  44. // SLIDESHOW:
  45. slider.manualPause = false;
  46. // TOUCH/USECSS:
  47. slider.transitions = !vars.video && !fade && vars.useCSS && (function() {
  48. var obj = document.createElement('div'),
  49. props = ['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective'];
  50. for (var i in props) {
  51. if ( obj.style[ props[i] ] !== undefined ) {
  52. slider.pfx = props[i].replace('Perspective','').toLowerCase();
  53. slider.prop = "-" + slider.pfx + "-transform";
  54. return true;
  55. }
  56. }
  57. return false;
  58. }());
  59. // CONTROLSCONTAINER:
  60. if (vars.controlsContainer !== "") slider.controlsContainer = $(vars.controlsContainer).length > 0 && $(vars.controlsContainer);
  61. // MANUAL:
  62. if (vars.manualControls !== "") slider.manualControls = $(vars.manualControls).length > 0 && $(vars.manualControls);
  63. // RANDOMIZE:
  64. if (vars.randomize) {
  65. slider.slides.sort(function() { return (Math.round(Math.random())-0.5); });
  66. slider.container.empty().append(slider.slides);
  67. }
  68. slider.doMath();
  69. // ASNAV:
  70. if (asNav) methods.asNav.setup();
  71. // INIT
  72. slider.setup("init");
  73. // CONTROLNAV:
  74. if (vars.controlNav) methods.controlNav.setup();
  75. // DIRECTIONNAV:
  76. if (vars.directionNav) methods.directionNav.setup();
  77. // KEYBOARD:
  78. if (vars.keyboard && ($(slider.containerSelector).length === 1 || vars.multipleKeyboard)) {
  79. $(document).bind('keyup', function(event) {
  80. var keycode = event.keyCode;
  81. if (!slider.animating && (keycode === 39 || keycode === 37)) {
  82. var target = (keycode === 39) ? slider.getTarget('next') :
  83. (keycode === 37) ? slider.getTarget('prev') : false;
  84. slider.flexAnimate(target, vars.pauseOnAction);
  85. }
  86. });
  87. }
  88. // MOUSEWHEEL:
  89. if (vars.mousewheel) {
  90. slider.bind('mousewheel', function(event, delta, deltaX, deltaY) {
  91. event.preventDefault();
  92. var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev');
  93. slider.flexAnimate(target, vars.pauseOnAction);
  94. });
  95. }
  96. // PAUSEPLAY
  97. if (vars.pausePlay) methods.pausePlay.setup();
  98. // SLIDSESHOW
  99. if (vars.slideshow) {
  100. if (vars.pauseOnHover) {
  101. slider.hover(function() {
  102. if (!slider.manualPlay && !slider.manualPause) slider.pause();
  103. }, function() {
  104. if (!slider.manualPause && !slider.manualPlay) slider.play();
  105. });
  106. }
  107. // initialize animation
  108. (vars.initDelay > 0) ? setTimeout(slider.play, vars.initDelay) : slider.play();
  109. }
  110. // TOUCH
  111. if (touch && vars.touch) methods.touch();
  112. // FADE&&SMOOTHHEIGHT || SLIDE:
  113. if (!fade || (fade && vars.smoothHeight)) $(window).bind("resize focus", methods.resize);
  114. // API: start() Callback
  115. setTimeout(function(){
  116. vars.start(slider);
  117. }, 200);
  118. },
  119. asNav: {
  120. setup: function() {
  121. slider.asNav = true;
  122. slider.animatingTo = Math.floor(slider.currentSlide/slider.move);
  123. slider.currentItem = slider.currentSlide;
  124. slider.slides.removeClass(namespace + "active-slide").eq(slider.currentItem).addClass(namespace + "active-slide");
  125. slider.slides.click(function(e){
  126. e.preventDefault();
  127. var $slide = $(this),
  128. target = $slide.index();
  129. if (!$(vars.asNavFor).data('flexslider').animating && !$slide.hasClass('active')) {
  130. slider.direction = (slider.currentItem < target) ? "next" : "prev";
  131. slider.flexAnimate(target, vars.pauseOnAction, false, true, true);
  132. }
  133. });
  134. }
  135. },
  136. controlNav: {
  137. setup: function() {
  138. if (!slider.manualControls) {
  139. methods.controlNav.setupPaging();
  140. } else { // MANUALCONTROLS:
  141. methods.controlNav.setupManual();
  142. }
  143. },
  144. setupPaging: function() {
  145. var type = (vars.controlNav === "thumbnails") ? 'control-thumbs' : 'control-paging',
  146. j = 1,
  147. item;
  148. slider.controlNavScaffold = $('<ol class="'+ namespace + 'control-nav ' + namespace + type + '"></ol>');
  149. if (slider.pagingCount > 1) {
  150. for (var i = 0; i < slider.pagingCount; i++) {
  151. item = (vars.controlNav === "thumbnails") ? '<img src="' + slider.slides.eq(i).attr("data-thumb") + '"/>' : '<a>' + j + '</a>';
  152. slider.controlNavScaffold.append('<li>' + item + '</li>');
  153. j++;
  154. }
  155. }
  156. // CONTROLSCONTAINER:
  157. (slider.controlsContainer) ? $(slider.controlsContainer).append(slider.controlNavScaffold) : slider.append(slider.controlNavScaffold);
  158. methods.controlNav.set();
  159. methods.controlNav.active();
  160. slider.controlNavScaffold.delegate('a, img', eventType, function(event) {
  161. event.preventDefault();
  162. var $this = $(this),
  163. target = slider.controlNav.index($this);
  164. if (!$this.hasClass(namespace + 'active')) {
  165. slider.direction = (target > slider.currentSlide) ? "next" : "prev";
  166. slider.flexAnimate(target, vars.pauseOnAction);
  167. }
  168. });
  169. // Prevent iOS click event bug
  170. if (touch) {
  171. slider.controlNavScaffold.delegate('a', "click touchstart", function(event) {
  172. event.preventDefault();
  173. });
  174. }
  175. },
  176. setupManual: function() {
  177. slider.controlNav = slider.manualControls;
  178. methods.controlNav.active();
  179. slider.controlNav.live(eventType, function(event) {
  180. event.preventDefault();
  181. var $this = $(this),
  182. target = slider.controlNav.index($this);
  183. if (!$this.hasClass(namespace + 'active')) {
  184. (target > slider.currentSlide) ? slider.direction = "next" : slider.direction = "prev";
  185. slider.flexAnimate(target, vars.pauseOnAction);
  186. }
  187. });
  188. // Prevent iOS click event bug
  189. if (touch) {
  190. slider.controlNav.live("click touchstart", function(event) {
  191. event.preventDefault();
  192. });
  193. }
  194. },
  195. set: function() {
  196. var selector = (vars.controlNav === "thumbnails") ? 'img' : 'a';
  197. slider.controlNav = $('.' + namespace + 'control-nav li ' + selector, (slider.controlsContainer) ? slider.controlsContainer : slider);
  198. },
  199. active: function() {
  200. slider.controlNav.removeClass(namespace + "active").eq(slider.animatingTo).addClass(namespace + "active");
  201. },
  202. update: function(action, pos) {
  203. if (slider.pagingCount > 1 && action === "add") {
  204. slider.controlNavScaffold.append($('<li><a>' + slider.count + '</a></li>'));
  205. } else if (slider.pagingCount === 1) {
  206. slider.controlNavScaffold.find('li').remove();
  207. } else {
  208. slider.controlNav.eq(pos).closest('li').remove();
  209. }
  210. methods.controlNav.set();
  211. (slider.pagingCount > 1 && slider.pagingCount !== slider.controlNav.length) ? slider.update(pos, action) : methods.controlNav.active();
  212. }
  213. },
  214. directionNav: {
  215. setup: function() {
  216. var directionNavScaffold = $('<ul class="' + namespace + 'direction-nav"><li><a class="' + namespace + 'prev" href="#">' + vars.prevText + '</a></li><li><a class="' + namespace + 'next" href="#">' + vars.nextText + '</a></li></ul>');
  217. // CONTROLSCONTAINER:
  218. if (slider.controlsContainer) {
  219. $(slider.controlsContainer).append(directionNavScaffold);
  220. slider.directionNav = $('.' + namespace + 'direction-nav li a', slider.controlsContainer);
  221. } else {
  222. slider.append(directionNavScaffold);
  223. slider.directionNav = $('.' + namespace + 'direction-nav li a', slider);
  224. }
  225. methods.directionNav.update();
  226. slider.directionNav.bind(eventType, function(event) {
  227. event.preventDefault();
  228. var target = ($(this).hasClass(namespace + 'next')) ? slider.getTarget('next') : slider.getTarget('prev');
  229. slider.flexAnimate(target, vars.pauseOnAction);
  230. });
  231. // Prevent iOS click event bug
  232. if (touch) {
  233. slider.directionNav.bind("click touchstart", function(event) {
  234. event.preventDefault();
  235. });
  236. }
  237. },
  238. update: function() {
  239. var disabledClass = namespace + 'disabled';
  240. if (slider.pagingCount === 1) {
  241. slider.directionNav.addClass(disabledClass);
  242. } else if (!vars.animationLoop) {
  243. if (slider.animatingTo === 0) {
  244. slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "prev").addClass(disabledClass);
  245. } else if (slider.animatingTo === slider.last) {
  246. slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "next").addClass(disabledClass);
  247. } else {
  248. slider.directionNav.removeClass(disabledClass);
  249. }
  250. } else {
  251. slider.directionNav.removeClass(disabledClass);
  252. }
  253. }
  254. },
  255. pausePlay: {
  256. setup: function() {
  257. var pausePlayScaffold = $('<div class="' + namespace + 'pauseplay"><a></a></div>');
  258. // CONTROLSCONTAINER:
  259. if (slider.controlsContainer) {
  260. slider.controlsContainer.append(pausePlayScaffold);
  261. slider.pausePlay = $('.' + namespace + 'pauseplay a', slider.controlsContainer);
  262. } else {
  263. slider.append(pausePlayScaffold);
  264. slider.pausePlay = $('.' + namespace + 'pauseplay a', slider);
  265. }
  266. methods.pausePlay.update((vars.slideshow) ? namespace + 'pause' : namespace + 'play');
  267. slider.pausePlay.bind(eventType, function(event) {
  268. event.preventDefault();
  269. if ($(this).hasClass(namespace + 'pause')) {
  270. slider.manualPause = true;
  271. slider.manualPlay = false;
  272. slider.pause();
  273. } else {
  274. slider.manualPause = false;
  275. slider.manualPlay = true;
  276. slider.play();
  277. }
  278. });
  279. // Prevent iOS click event bug
  280. if (touch) {
  281. slider.pausePlay.bind("click touchstart", function(event) {
  282. event.preventDefault();
  283. });
  284. }
  285. },
  286. update: function(state) {
  287. (state === "play") ? slider.pausePlay.removeClass(namespace + 'pause').addClass(namespace + 'play').text(vars.playText) : slider.pausePlay.removeClass(namespace + 'play').addClass(namespace + 'pause').text(vars.pauseText);
  288. }
  289. },
  290. touch: function() {
  291. var startX,
  292. startY,
  293. offset,
  294. cwidth,
  295. dx,
  296. startT,
  297. scrolling = false;
  298. el.addEventListener('touchstart', onTouchStart, false);
  299. function onTouchStart(e) {
  300. if (slider.animating) {
  301. e.preventDefault();
  302. } else if (e.touches.length === 1) {
  303. slider.pause();
  304. // CAROUSEL:
  305. cwidth = (vertical) ? slider.h : slider. w;
  306. startT = Number(new Date());
  307. // CAROUSEL:
  308. offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 :
  309. (carousel && reverse) ? slider.limit - (((slider.itemW + vars.itemMargin) * slider.move) * slider.animatingTo) :
  310. (carousel && slider.currentSlide === slider.last) ? slider.limit :
  311. (carousel) ? ((slider.itemW + vars.itemMargin) * slider.move) * slider.currentSlide :
  312. (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth;
  313. startX = (vertical) ? e.touches[0].pageY : e.touches[0].pageX;
  314. startY = (vertical) ? e.touches[0].pageX : e.touches[0].pageY;
  315. el.addEventListener('touchmove', onTouchMove, false);
  316. el.addEventListener('touchend', onTouchEnd, false);
  317. }
  318. }
  319. function onTouchMove(e) {
  320. dx = (vertical) ? startX - e.touches[0].pageY : startX - e.touches[0].pageX;
  321. scrolling = (vertical) ? (Math.abs(dx) < Math.abs(e.touches[0].pageX - startY)) : (Math.abs(dx) < Math.abs(e.touches[0].pageY - startY));
  322. if (!scrolling || Number(new Date()) - startT > 500) {
  323. e.preventDefault();
  324. if (!fade && slider.transitions) {
  325. if (!vars.animationLoop) {
  326. dx = dx/((slider.currentSlide === 0 && dx < 0 || slider.currentSlide === slider.last && dx > 0) ? (Math.abs(dx)/cwidth+2) : 1);
  327. }
  328. slider.setProps(offset + dx, "setTouch");
  329. }
  330. }
  331. }
  332. function onTouchEnd(e) {
  333. if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) {
  334. var updateDx = (reverse) ? -dx : dx,
  335. target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev');
  336. if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) {
  337. slider.flexAnimate(target, vars.pauseOnAction);
  338. } else {
  339. slider.flexAnimate(slider.currentSlide, vars.pauseOnAction, true);
  340. }
  341. }
  342. // finish the touch by undoing the touch session
  343. el.removeEventListener('touchmove', onTouchMove, false);
  344. el.removeEventListener('touchend', onTouchEnd, false);
  345. startX = null;
  346. startY = null;
  347. dx = null;
  348. offset = null;
  349. }
  350. },
  351. resize: function() {
  352. if (!slider.animating && slider.is(':visible')) {
  353. if (!carousel) slider.doMath();
  354. if (fade) {
  355. // SMOOTH HEIGHT:
  356. methods.smoothHeight();
  357. } else if (carousel) { //CAROUSEL:
  358. slider.slides.width(slider.computedW);
  359. slider.update(slider.pagingCount);
  360. slider.setProps();
  361. }
  362. else if (vertical) { //VERTICAL:
  363. slider.viewport.height(slider.h);
  364. slider.setProps(slider.h, "setTotal");
  365. } else {
  366. // SMOOTH HEIGHT:
  367. if (vars.smoothHeight) methods.smoothHeight();
  368. slider.newSlides.width(slider.computedW);
  369. slider.setProps(slider.computedW, "setTotal");
  370. }
  371. }
  372. },
  373. smoothHeight: function(dur) {
  374. if (!vertical || fade) {
  375. var $obj = (fade) ? slider : slider.viewport;
  376. (dur) ? $obj.animate({"height": slider.slides.eq(slider.animatingTo).height()}, dur) : $obj.height(slider.slides.eq(slider.animatingTo).height());
  377. }
  378. },
  379. sync: function(action) {
  380. var $obj = $(vars.sync).data("flexslider"),
  381. target = slider.animatingTo;
  382. switch (action) {
  383. case "animate": $obj.flexAnimate(target, vars.pauseOnAction, false, true); break;
  384. case "play": if (!$obj.playing && !$obj.asNav) { $obj.play(); } break;
  385. case "pause": $obj.pause(); break;
  386. }
  387. }
  388. }
  389. // public methods
  390. slider.flexAnimate = function(target, pause, override, withSync, fromNav) {
  391. if (asNav && slider.pagingCount === 1) slider.direction = (slider.currentItem < target) ? "next" : "prev";
  392. if (!slider.animating && (slider.canAdvance(target, fromNav) || override) && slider.is(":visible")) {
  393. if (asNav && withSync) {
  394. var master = $(vars.asNavFor).data('flexslider');
  395. slider.atEnd = target === 0 || target === slider.count - 1;
  396. master.flexAnimate(target, true, false, true, fromNav);
  397. slider.direction = (slider.currentItem < target) ? "next" : "prev";
  398. master.direction = slider.direction;
  399. if (Math.ceil((target + 1)/slider.visible) - 1 !== slider.currentSlide && target !== 0) {
  400. slider.currentItem = target;
  401. slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
  402. target = Math.floor(target/slider.visible);
  403. } else {
  404. slider.currentItem = target;
  405. slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
  406. return false;
  407. }
  408. }
  409. slider.animating = true;
  410. slider.animatingTo = target;
  411. // API: before() animation Callback
  412. vars.before(slider);
  413. // SLIDESHOW:
  414. if (pause) slider.pause();
  415. // SYNC:
  416. if (slider.syncExists && !fromNav) methods.sync("animate");
  417. // CONTROLNAV
  418. if (vars.controlNav) methods.controlNav.active();
  419. // !CAROUSEL:
  420. // CANDIDATE: slide active class (for add/remove slide)
  421. if (!carousel) slider.slides.removeClass(namespace + 'active-slide').eq(target).addClass(namespace + 'active-slide');
  422. // INFINITE LOOP:
  423. // CANDIDATE: atEnd
  424. slider.atEnd = target === 0 || target === slider.last;
  425. // DIRECTIONNAV:
  426. if (vars.directionNav) methods.directionNav.update();
  427. if (target === slider.last) {
  428. // API: end() of cycle Callback
  429. vars.end(slider);
  430. // SLIDESHOW && !INFINITE LOOP:
  431. if (!vars.animationLoop) slider.pause();
  432. }
  433. // SLIDE:
  434. if (!fade) {
  435. var dimension = (vertical) ? slider.slides.filter(':first').height() : slider.computedW,
  436. margin, slideString, calcNext;
  437. // INFINITE LOOP / REVERSE:
  438. if (carousel) {
  439. margin = (vars.itemWidth > slider.w) ? vars.itemMargin * 2 : vars.itemMargin;
  440. calcNext = ((slider.itemW + margin) * slider.move) * slider.animatingTo;
  441. slideString = (calcNext > slider.limit && slider.visible !== 1) ? slider.limit : calcNext;
  442. } else if (slider.currentSlide === 0 && target === slider.count - 1 && vars.animationLoop && slider.direction !== "next") {
  443. slideString = (reverse) ? (slider.count + slider.cloneOffset) * dimension : 0;
  444. } else if (slider.currentSlide === slider.last && target === 0 && vars.animationLoop && slider.direction !== "prev") {
  445. slideString = (reverse) ? 0 : (slider.count + 1) * dimension;
  446. } else {
  447. slideString = (reverse) ? ((slider.count - 1) - target + slider.cloneOffset) * dimension : (target + slider.cloneOffset) * dimension;
  448. }
  449. slider.setProps(slideString, "", vars.animationSpeed);
  450. if (slider.transitions) {
  451. if (!vars.animationLoop || !slider.atEnd) {
  452. slider.animating = false;
  453. slider.currentSlide = slider.animatingTo;
  454. }
  455. slider.container.unbind("webkitTransitionEnd transitionend");
  456. slider.container.bind("webkitTransitionEnd transitionend", function() {
  457. slider.wrapup(dimension);
  458. });
  459. } else {
  460. slider.container.animate(slider.args, vars.animationSpeed, vars.easing, function(){
  461. slider.wrapup(dimension);
  462. });
  463. }
  464. } else { // FADE:
  465. slider.slides.eq(slider.currentSlide).fadeOut(vars.animationSpeed, vars.easing);
  466. slider.slides.eq(target).fadeIn(vars.animationSpeed, vars.easing, slider.wrapup);
  467. }
  468. // SMOOTH HEIGHT:
  469. if (vars.smoothHeight) methods.smoothHeight(vars.animationSpeed);
  470. }
  471. }
  472. slider.wrapup = function(dimension) {
  473. // SLIDE:
  474. if (!fade && !carousel) {
  475. if (slider.currentSlide === 0 && slider.animatingTo === slider.last && vars.animationLoop) {
  476. slider.setProps(dimension, "jumpEnd");
  477. } else if (slider.currentSlide === slider.last && slider.animatingTo === 0 && vars.animationLoop) {
  478. slider.setProps(dimension, "jumpStart");
  479. }
  480. }
  481. slider.animating = false;
  482. slider.currentSlide = slider.animatingTo;
  483. // API: after() animation Callback
  484. vars.after(slider);
  485. }
  486. // SLIDESHOW:
  487. slider.animateSlides = function() {
  488. if (!slider.animating) slider.flexAnimate(slider.getTarget("next"));
  489. }
  490. // SLIDESHOW:
  491. slider.pause = function() {
  492. clearInterval(slider.animatedSlides);
  493. slider.playing = false;
  494. // PAUSEPLAY:
  495. if (vars.pausePlay) methods.pausePlay.update("play");
  496. // SYNC:
  497. if (slider.syncExists) methods.sync("pause");
  498. }
  499. // SLIDESHOW:
  500. slider.play = function() {
  501. slider.animatedSlides = setInterval(slider.animateSlides, vars.slideshowSpeed);
  502. slider.playing = true;
  503. // PAUSEPLAY:
  504. if (vars.pausePlay) methods.pausePlay.update("pause");
  505. // SYNC:
  506. if (slider.syncExists) methods.sync("play");
  507. }
  508. slider.canAdvance = function(target, fromNav) {
  509. // ASNAV:
  510. var last = (asNav) ? slider.pagingCount - 1 : slider.last;
  511. return (fromNav) ? true :
  512. (asNav && slider.currentItem === slider.count - 1 && target === 0 && slider.direction === "prev") ? true :
  513. (asNav && slider.currentItem === 0 && target === slider.pagingCount - 1 && slider.direction !== "next") ? false :
  514. (target === slider.currentSlide && !asNav) ? false :
  515. (vars.animationLoop) ? true :
  516. (slider.atEnd && slider.currentSlide === 0 && target === last && slider.direction !== "next") ? false :
  517. (slider.atEnd && slider.currentSlide === last && target === 0 && slider.direction === "next") ? false :
  518. true;
  519. }
  520. slider.getTarget = function(dir) {
  521. slider.direction = dir;
  522. if (dir === "next") {
  523. return (slider.currentSlide === slider.last) ? 0 : slider.currentSlide + 1;
  524. } else {
  525. return (slider.currentSlide === 0) ? slider.last : slider.currentSlide - 1;
  526. }
  527. }
  528. // SLIDE:
  529. slider.setProps = function(pos, special, dur) {
  530. var target = (function() {
  531. var posCheck = (pos) ? pos : ((slider.itemW + vars.itemMargin) * slider.move) * slider.animatingTo,
  532. posCalc = (function() {
  533. if (carousel) {
  534. return (special === "setTouch") ? pos :
  535. (reverse && slider.animatingTo === slider.last) ? 0 :
  536. (reverse) ? slider.limit - (((slider.itemW + vars.itemMargin) * slider.move) * slider.animatingTo) :
  537. (slider.animatingTo === slider.last) ? slider.limit : posCheck;
  538. } else {
  539. switch (special) {
  540. case "setTotal": return (reverse) ? ((slider.count - 1) - slider.currentSlide + slider.cloneOffset) * pos : (slider.currentSlide + slider.cloneOffset) * pos;
  541. case "setTouch": return (reverse) ? pos : pos;
  542. case "jumpEnd": return (reverse) ? pos : slider.count * pos;
  543. case "jumpStart": return (reverse) ? slider.count * pos : pos;
  544. default: return pos;
  545. }
  546. }
  547. }());
  548. return (posCalc * -1) + "px";
  549. }());
  550. if (slider.transitions) {
  551. target = (vertical) ? "translate3d(0," + target + ",0)" : "translate3d(" + target + ",0,0)";
  552. dur = (dur !== undefined) ? (dur/1000) + "s" : "0s";
  553. slider.container.css("-" + slider.pfx + "-transition-duration", dur);
  554. }
  555. slider.args[slider.prop] = target;
  556. if (slider.transitions || dur === undefined) slider.container.css(slider.args);
  557. }
  558. slider.setup = function(type) {
  559. // SLIDE:
  560. if (!fade) {
  561. var sliderOffset, arr;
  562. if (type === "init") {
  563. slider.viewport = $('<div class="' + namespace + 'viewport"></div>').css({"overflow": "hidden", "position": "relative"}).appendTo(slider).append(slider.container);
  564. // INFINITE LOOP:
  565. slider.cloneCount = 0;
  566. slider.cloneOffset = 0;
  567. // REVERSE:
  568. if (reverse) {
  569. arr = $.makeArray(slider.slides).reverse();
  570. slider.slides = $(arr);
  571. slider.container.empty().append(slider.slides);
  572. }
  573. }
  574. // INFINITE LOOP && !CAROUSEL:
  575. if (vars.animationLoop && !carousel) {
  576. slider.cloneCount = 2;
  577. slider.cloneOffset = 1;
  578. // clear out old clones
  579. if (type !== "init") slider.container.find('.clone').remove();
  580. slider.container.append(slider.slides.first().clone().addClass('clone')).prepend(slider.slides.last().clone().addClass('clone'));
  581. }
  582. slider.newSlides = $(vars.selector, slider);
  583. sliderOffset = (reverse) ? slider.count - 1 - slider.currentSlide + slider.cloneOffset : slider.currentSlide + slider.cloneOffset;
  584. // VERTICAL:
  585. if (vertical && !carousel) {
  586. slider.container.height((slider.count + slider.cloneCount) * 200 + "%").css("position", "absolute").width("100%");
  587. setTimeout(function(){
  588. slider.newSlides.css({"display": "block"});
  589. slider.doMath();
  590. slider.viewport.height(slider.h);
  591. slider.setProps(sliderOffset * slider.h, "init");
  592. }, (type === "init") ? 100 : 0);
  593. } else {
  594. slider.container.width((slider.count + slider.cloneCount) * 200 + "%");
  595. slider.setProps(sliderOffset * slider.computedW, "init");
  596. setTimeout(function(){
  597. slider.doMath();
  598. slider.newSlides.css({"width": slider.computedW, "float": "left", "display": "block"});
  599. // SMOOTH HEIGHT:
  600. if (vars.smoothHeight) methods.smoothHeight();
  601. }, (type === "init") ? 100 : 0);
  602. }
  603. } else { // FADE:
  604. slider.slides.css({"width": "100%", "float": "left", "marginRight": "-100%", "position": "relative"});
  605. if (type === "init") slider.slides.eq(slider.currentSlide).fadeIn(vars.animationSpeed, vars.easing);
  606. // SMOOTH HEIGHT:
  607. if (vars.smoothHeight) methods.smoothHeight();
  608. }
  609. // !CAROUSEL:
  610. // CANDIDATE: active slide
  611. if (!carousel) slider.slides.removeClass(namespace + "active-slide").eq(slider.currentSlide).addClass(namespace + "active-slide");
  612. }
  613. slider.doMath = function() {
  614. var slide = slider.slides.first(),
  615. slideMargin = vars.itemMargin,
  616. minItems = vars.minItems,
  617. maxItems = vars.maxItems;
  618. slider.w = slider.width();
  619. slider.h = slide.height();
  620. slider.boxPadding = slide.outerWidth() - slide.width();
  621. // CAROUSEL:
  622. if (carousel) {
  623. slider.itemT = vars.itemWidth + slideMargin;
  624. slider.minW = (minItems) ? minItems * slider.itemT : slider.w;
  625. slider.maxW = (maxItems) ? maxItems * slider.itemT : slider.w;
  626. slider.itemW = (slider.minW > slider.w) ? (slider.w - (slideMargin * minItems))/minItems :
  627. (slider.maxW < slider.w) ? (slider.w - (slideMargin * maxItems))/maxItems :
  628. (vars.itemWidth > slider.w) ? slider.w : vars.itemWidth;
  629. slider.visible = Math.floor(slider.w/(slider.itemW + slideMargin));
  630. slider.move = (vars.move > 0 && vars.move < slider.visible ) ? vars.move : slider.visible;
  631. slider.pagingCount = Math.ceil(((slider.count - slider.visible)/slider.move) + 1);
  632. slider.last = slider.pagingCount - 1;
  633. slider.limit = (slider.pagingCount === 1) ? 0 :
  634. (vars.itemWidth > slider.w) ? ((slider.itemW + (slideMargin * 2)) * slider.count) - slider.w - slideMargin : ((slider.itemW + slideMargin) * slider.count) - slider.w - slideMargin;
  635. } else {
  636. slider.itemW = slider.w;
  637. slider.pagingCount = slider.count;
  638. slider.last = slider.count - 1;
  639. }
  640. slider.computedW = slider.itemW - slider.boxPadding;
  641. }
  642. slider.update = function(pos, action) {
  643. slider.doMath();
  644. // update currentSlide and slider.animatingTo if necessary
  645. if (!carousel) {
  646. if (pos < slider.currentSlide) {
  647. slider.currentSlide += 1;
  648. } else if (pos <= slider.currentSlide && pos !== 0) {
  649. slider.currentSlide -= 1;
  650. }
  651. slider.animatingTo = slider.currentSlide;
  652. }
  653. // update controlNav
  654. if (vars.controlNav && !slider.manualControls) {
  655. if ((action === "add" && !carousel) || slider.pagingCount > slider.controlNav.length) {
  656. methods.controlNav.update("add");
  657. } else if ((action === "remove" && !carousel) || slider.pagingCount < slider.controlNav.length) {
  658. if (carousel && slider.currentSlide > slider.last) {
  659. slider.currentSlide -= 1;
  660. slider.animatingTo -= 1;
  661. }
  662. methods.controlNav.update("remove", slider.last);
  663. }
  664. }
  665. // update directionNav
  666. if (vars.directionNav) methods.directionNav.update();
  667. }
  668. slider.addSlide = function(obj, pos) {
  669. var $obj = $(obj);
  670. slider.count += 1;
  671. slider.last = slider.count - 1;
  672. // append new slide
  673. if (vertical && reverse) {
  674. (pos !== undefined) ? slider.slides.eq(slider.count - pos).after($obj) : slider.container.prepend($obj);
  675. } else {
  676. (pos !== undefined) ? slider.slides.eq(pos).before($obj) : slider.container.append($obj);
  677. }
  678. // update currentSlide, animatingTo, controlNav, and directionNav
  679. slider.update(pos, "add");
  680. // update slider.slides
  681. slider.slides = $(vars.selector + ':not(.clone)', slider);
  682. // re-setup the slider to accomdate new slide
  683. slider.setup();
  684. //FlexSlider: added() Callback
  685. vars.added(slider);
  686. }
  687. slider.removeSlide = function(obj) {
  688. var pos = (isNaN(obj)) ? slider.slides.index($(obj)) : obj;
  689. // update count
  690. slider.count -= 1;
  691. slider.last = slider.count - 1;
  692. // remove slide
  693. if (isNaN(obj)) {
  694. $(obj, slider.slides).remove();
  695. } else {
  696. (vertical && reverse) ? slider.slides.eq(slider.last).remove() : slider.slides.eq(obj).remove();
  697. }
  698. // update currentSlide, animatingTo, controlNav, and directionNav
  699. slider.doMath();
  700. slider.update(pos, "remove");
  701. // update slider.slides
  702. slider.slides = $(vars.selector + ':not(.clone)', slider);
  703. // re-setup the slider to accomdate new slide
  704. slider.setup();
  705. // FlexSlider: removed() Callback
  706. vars.removed(slider);
  707. }
  708. //FlexSlider: Initialize
  709. methods.init();
  710. }
  711. //FlexSlider: Default Settings
  712. $.flexslider.defaults = {
  713. namespace: "flex-", //{NEW} String: Prefix string attached to the class of every element generated by the plugin
  714. selector: ".slides > li", //{NEW} Selector: Must match a simple pattern. '{container} > {slide}' -- Ignore pattern at your own peril
  715. animation: "fade", //String: Select your animation type, "fade" or "slide"
  716. easing: "swing", //{NEW} String: Determines the easing method used in jQuery transitions. jQuery easing plugin is supported!
  717. direction: "horizontal", //String: Select the sliding direction, "horizontal" or "vertical"
  718. reverse: false, //{NEW} Boolean: Reverse the animation direction
  719. animationLoop: true, //Boolean: Should the animation loop? If false, directionNav will received "disable" classes at either end
  720. smoothHeight: false, //{NEW} Boolean: Allow height of the slider to animate smoothly in horizontal mode
  721. startAt: 0, //Integer: The slide that the slider should start on. Array notation (0 = first slide)
  722. slideshow: true, //Boolean: Animate slider automatically
  723. slideshowSpeed: 7000, //Integer: Set the speed of the slideshow cycling, in milliseconds
  724. animationSpeed: 600, //Integer: Set the speed of animations, in milliseconds
  725. initDelay: 0, //{NEW} Integer: Set an initialization delay, in milliseconds
  726. randomize: false, //Boolean: Randomize slide order
  727. // Usability features
  728. pauseOnAction: true, //Boolean: Pause the slideshow when interacting with control elements, highly recommended.
  729. pauseOnHover: false, //Boolean: Pause the slideshow when hovering over slider, then resume when no longer hovering
  730. useCSS: true, //{NEW} Boolean: Slider will use CSS3 transitions if available
  731. touch: true, //{NEW} Boolean: Allow touch swipe navigation of the slider on touch-enabled devices
  732. video: false, //{NEW} Boolean: If using video in the slider, will prevent CSS3 3D Transforms to avoid graphical glitches
  733. // Primary Controls
  734. controlNav: true, //Boolean: Create navigation for paging control of each clide? Note: Leave true for manualControls usage
  735. directionNav: true, //Boolean: Create navigation for previous/next navigation? (true/false)
  736. prevText: "Previous", //String: Set the text for the "previous" directionNav item
  737. nextText: "Next", //String: Set the text for the "next" directionNav item
  738. // Secondary Navigation
  739. keyboard: true, //Boolean: Allow slider navigating via keyboard left/right keys
  740. multipleKeyboard: false, //{NEW} Boolean: Allow keyboard navigation to affect multiple sliders. Default behavior cuts out keyboard navigation with more than one slider present.
  741. mousewheel: false, //{UPDATED} Boolean: Requires jquery.mousewheel.js (https://github.com/brandonaaron/jquery-mousewheel) - Allows slider navigating via mousewheel
  742. pausePlay: false, //Boolean: Create pause/play dynamic element
  743. pauseText: "Pause", //String: Set the text for the "pause" pausePlay item
  744. playText: "Play", //String: Set the text for the "play" pausePlay item
  745. // Special properties
  746. controlsContainer: "", //{UPDATED} jQuery Object/Selector: Declare which container the navigation elements should be appended too. Default container is the FlexSlider element. Example use would be $(".flexslider-container"). Property is ignored if given element is not found.
  747. manualControls: "", //{UPDATED} jQuery Object/Selector: Declare custom control navigation. Examples would be $(".flex-control-nav li") or "#tabs-nav li img", etc. The number of elements in your controlNav should match the number of slides/tabs.
  748. sync: "", //{NEW} Selector: Mirror the actions performed on this slider with another slider. Use with care.
  749. asNavFor: "", //{NEW} Selector: Internal property exposed for turning the slider into a thumbnail navigation for another slider
  750. // Carousel Options
  751. itemWidth: 0, //{NEW} Integer: Box-model width of individual carousel items, including horizontal borders and padding.
  752. itemMargin: 0, //{NEW} Integer: Margin between carousel items.
  753. minItems: 0, //{NEW} Integer: Minimum number of carousel items that should be visible. Items will resize fluidly when below this.
  754. maxItems: 0, //{NEW} Integer: Maxmimum number of carousel items that should be visible. Items will resize fluidly when above this limit.
  755. move: 0, //{NEW} Integer: Number of carousel items that should move on animation. If 0, slider will move all visible items.
  756. // Callback API
  757. start: function(){}, //Callback: function(slider) - Fires when the slider loads the first slide
  758. before: function(){}, //Callback: function(slider) - Fires asynchronously with each slider animation
  759. after: function(){}, //Callback: function(slider) - Fires after each slider animation completes
  760. end: function(){}, //Callback: function(slider) - Fires when the slider reaches the last slide (asynchronous)
  761. added: function(){}, //{NEW} Callback: function(slider) - Fires after a slide is added
  762. removed: function(){} //{NEW} Callback: function(slider) - Fires after a slide is removed
  763. }
  764. //FlexSlider: Plugin Function
  765. $.fn.flexslider = function(options) {
  766. if (options === undefined) options = {};
  767. if (typeof options === "object") {
  768. return this.each(function() {
  769. var $this = $(this),
  770. selector = (options.selector) ? options.selector : ".slides > li",
  771. $slides = $this.find(selector);
  772. if ($slides.length === 1) {
  773. $slides.fadeIn(400);
  774. if (options.start) options.start($this);
  775. } else if ($this.data('flexslider') === undefined) {
  776. new $.flexslider(this, options);
  777. }
  778. });
  779. } else {
  780. // Helper strings to quickly perform functions on the slider
  781. var $slider = $(this).data('flexslider');
  782. switch (options) {
  783. case "play": $slider.play(); break;
  784. case "pause": $slider.pause(); break;
  785. case "next": $slider.flexAnimate($slider.getTarget("next"), true); break;
  786. case "prev":
  787. case "previous": $slider.flexAnimate($slider.getTarget("prev"), true); break;
  788. default: if (typeof options === "number") $slider.flexAnimate(options, true);
  789. }
  790. }
  791. }
  792. })(jQuery);