1
0

jquery.orbit-1.4.0.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. /*
  2. * jQuery Orbit Plugin 1.4.0
  3. * www.ZURB.com/playground
  4. * Copyright 2010, ZURB
  5. * Free to use under the MIT license.
  6. * http://www.opensource.org/licenses/mit-license.php
  7. */
  8. (function($) {
  9. 'use strict';
  10. $.fn.findFirstImage = function () {
  11. return this.first()
  12. .find('img')
  13. .andSelf().filter('img')
  14. .first();
  15. };
  16. var ORBIT = {
  17. defaults: {
  18. animation: 'horizontal-push', // fade, horizontal-slide, vertical-slide, horizontal-push, vertical-push
  19. animationSpeed: 600, // how fast animtions are
  20. timer: true, // true or false to have the timer
  21. advanceSpeed: 4000, // if timer is enabled, time between transitions
  22. pauseOnHover: false, // if you hover pauses the slider
  23. startClockOnMouseOut: false, // if clock should start on MouseOut
  24. startClockOnMouseOutAfter: 1000, // how long after MouseOut should the timer start again
  25. directionalNav: true, // manual advancing directional navs
  26. directionalNavRightText: 'Right', // text of right directional element for accessibility
  27. directionalNavLeftText: 'Left', // text of left directional element for accessibility
  28. captions: true, // do you want captions?
  29. captionAnimation: 'fade', // fade, slideOpen, none
  30. captionAnimationSpeed: 600, // if so how quickly should they animate in
  31. resetTimerOnClick: false, // true resets the timer instead of pausing slideshow progress on manual navigation
  32. bullets: false, // true or false to activate the bullet navigation
  33. bulletThumbs: false, // thumbnails for the bullets
  34. bulletThumbLocation: '', // location from this file where thumbs will be
  35. afterSlideChange: $.noop, // empty function
  36. afterLoadComplete: $.noop, //callback to execute after everything has been loaded
  37. fluid: true,
  38. centerBullets: true // center bullet nav with js, turn this off if you want to position the bullet nav manually
  39. },
  40. activeSlide: 0,
  41. numberSlides: 0,
  42. orbitWidth: null,
  43. orbitHeight: null,
  44. locked: null,
  45. timerRunning: null,
  46. degrees: 0,
  47. wrapperHTML: '<div class="orbit-wrapper" />',
  48. timerHTML: '<div class="timer"><span class="mask"><span class="rotator"></span></span><span class="pause"></span></div>',
  49. captionHTML: '<div class="orbit-caption"></div>',
  50. directionalNavHTML: '<div class="slider-nav"><span class="right"></span><span class="left"></span></div>',
  51. bulletHTML: '<ul class="orbit-bullets"></ul>',
  52. init: function (element, options) {
  53. var $imageSlides,
  54. imagesLoadedCount = 0,
  55. self = this;
  56. // Bind functions to correct context
  57. this.clickTimer = $.proxy(this.clickTimer, this);
  58. this.addBullet = $.proxy(this.addBullet, this);
  59. this.resetAndUnlock = $.proxy(this.resetAndUnlock, this);
  60. this.stopClock = $.proxy(this.stopClock, this);
  61. this.startTimerAfterMouseLeave = $.proxy(this.startTimerAfterMouseLeave, this);
  62. this.clearClockMouseLeaveTimer = $.proxy(this.clearClockMouseLeaveTimer, this);
  63. this.rotateTimer = $.proxy(this.rotateTimer, this);
  64. this.options = $.extend({}, this.defaults, options);
  65. if (this.options.timer === 'false') this.options.timer = false;
  66. if (this.options.captions === 'false') this.options.captions = false;
  67. if (this.options.directionalNav === 'false') this.options.directionalNav = false;
  68. this.$element = $(element);
  69. this.$wrapper = this.$element.wrap(this.wrapperHTML).parent();
  70. this.$slides = this.$element.children('img, a, div');
  71. this.$element.bind('orbit.next', function () {
  72. self.shift('next');
  73. });
  74. this.$element.bind('orbit.prev', function () {
  75. self.shift('prev');
  76. });
  77. this.$element.bind('orbit.goto', function (event, index) {
  78. self.shift(index);
  79. });
  80. this.$element.bind('orbit.start', function (event, index) {
  81. self.startClock();
  82. });
  83. this.$element.bind('orbit.stop', function (event, index) {
  84. self.stopClock();
  85. });
  86. $imageSlides = this.$slides.filter('img');
  87. if ($imageSlides.length === 0) {
  88. this.loaded();
  89. } else {
  90. $imageSlides.bind('imageready', function () {
  91. imagesLoadedCount += 1;
  92. if (imagesLoadedCount === $imageSlides.length) {
  93. self.loaded();
  94. }
  95. });
  96. }
  97. },
  98. loaded: function () {
  99. this.$element
  100. .addClass('orbit')
  101. .css({width: '1px', height: '1px'});
  102. this.$slides.addClass('orbit-slide');
  103. this.setDimentionsFromLargestSlide();
  104. this.updateOptionsIfOnlyOneSlide();
  105. this.setupFirstSlide();
  106. if (this.options.timer) {
  107. this.setupTimer();
  108. this.startClock();
  109. }
  110. if (this.options.captions) {
  111. this.setupCaptions();
  112. }
  113. if (this.options.directionalNav) {
  114. this.setupDirectionalNav();
  115. }
  116. if (this.options.bullets) {
  117. this.setupBulletNav();
  118. this.setActiveBullet();
  119. }
  120. this.options.afterLoadComplete.call(this);
  121. },
  122. currentSlide: function () {
  123. return this.$slides.eq(this.activeSlide);
  124. },
  125. setDimentionsFromLargestSlide: function () {
  126. //Collect all slides and set slider size of largest image
  127. var self = this,
  128. $fluidPlaceholder;
  129. self.$element.add(self.$wrapper).width(this.$slides.first().outerWidth());
  130. self.$element.add(self.$wrapper).height(this.$slides.first().height());
  131. self.orbitWidth = this.$slides.first().outerWidth();
  132. self.orbitHeight = this.$slides.first().height();
  133. $fluidPlaceholder = this.$slides.first().findFirstImage().clone();
  134. this.$slides.each(function () {
  135. var slide = $(this),
  136. slideWidth = slide.outerWidth(),
  137. slideHeight = slide.height();
  138. if (slideWidth > self.$element.outerWidth()) {
  139. self.$element.add(self.$wrapper).width(slideWidth);
  140. self.orbitWidth = self.$element.outerWidth();
  141. }
  142. if (slideHeight > self.$element.height()) {
  143. self.$element.add(self.$wrapper).height(slideHeight);
  144. self.orbitHeight = self.$element.height();
  145. $fluidPlaceholder = $(this).findFirstImage().clone();
  146. }
  147. self.numberSlides += 1;
  148. });
  149. if (this.options.fluid) {
  150. if (typeof this.options.fluid === "string") {
  151. $fluidPlaceholder = $('<img src="http://placehold.it/' + this.options.fluid + '" />')
  152. }
  153. self.$element.prepend($fluidPlaceholder);
  154. $fluidPlaceholder.addClass('fluid-placeholder');
  155. self.$element.add(self.$wrapper).css({width: 'inherit'});
  156. self.$element.add(self.$wrapper).css({height: 'inherit'});
  157. $(window).bind('resize', function () {
  158. self.orbitWidth = self.$element.outerWidth();
  159. self.orbitHeight = self.$element.height();
  160. });
  161. }
  162. },
  163. //Animation locking functions
  164. lock: function () {
  165. this.locked = true;
  166. },
  167. unlock: function () {
  168. this.locked = false;
  169. },
  170. updateOptionsIfOnlyOneSlide: function () {
  171. if(this.$slides.length === 1) {
  172. this.options.directionalNav = false;
  173. this.options.timer = false;
  174. this.options.bullets = false;
  175. }
  176. },
  177. setupFirstSlide: function () {
  178. //Set initial front photo z-index and fades it in
  179. var self = this;
  180. this.$slides.first()
  181. .css({"z-index" : 3})
  182. .fadeIn(function() {
  183. //brings in all other slides IF css declares a display: none
  184. self.$slides.css({"display":"block"})
  185. });
  186. },
  187. startClock: function () {
  188. var self = this;
  189. if(!this.options.timer) {
  190. return false;
  191. }
  192. if (this.$timer.is(':hidden')) {
  193. this.clock = setInterval(function () {
  194. self.$element.trigger('orbit.next');
  195. }, this.options.advanceSpeed);
  196. } else {
  197. this.timerRunning = true;
  198. this.$pause.removeClass('active')
  199. this.clock = setInterval(this.rotateTimer, this.options.advanceSpeed / 180);
  200. }
  201. },
  202. rotateTimer: function (reset) {
  203. var degreeCSS = "rotate(" + this.degrees + "deg)"
  204. this.degrees += 2;
  205. this.$rotator.css({
  206. "-webkit-transform": degreeCSS,
  207. "-moz-transform": degreeCSS,
  208. "-o-transform": degreeCSS
  209. });
  210. if(this.degrees > 180) {
  211. this.$rotator.addClass('move');
  212. this.$mask.addClass('move');
  213. }
  214. if(this.degrees > 360 || reset) {
  215. this.$rotator.removeClass('move');
  216. this.$mask.removeClass('move');
  217. this.degrees = 0;
  218. this.$element.trigger('orbit.next');
  219. }
  220. },
  221. stopClock: function () {
  222. if (!this.options.timer) {
  223. return false;
  224. } else {
  225. this.timerRunning = false;
  226. clearInterval(this.clock);
  227. this.$pause.addClass('active');
  228. }
  229. },
  230. setupTimer: function () {
  231. this.$timer = $(this.timerHTML);
  232. this.$wrapper.append(this.$timer);
  233. this.$rotator = this.$timer.find('.rotator');
  234. this.$mask = this.$timer.find('.mask');
  235. this.$pause = this.$timer.find('.pause');
  236. this.$timer.click(this.clickTimer);
  237. if (this.options.startClockOnMouseOut) {
  238. this.$wrapper.mouseleave(this.startTimerAfterMouseLeave);
  239. this.$wrapper.mouseenter(this.clearClockMouseLeaveTimer);
  240. }
  241. if (this.options.pauseOnHover) {
  242. this.$wrapper.mouseenter(this.stopClock);
  243. }
  244. },
  245. startTimerAfterMouseLeave: function () {
  246. var self = this;
  247. this.outTimer = setTimeout(function() {
  248. if(!self.timerRunning){
  249. self.startClock();
  250. }
  251. }, this.options.startClockOnMouseOutAfter)
  252. },
  253. clearClockMouseLeaveTimer: function () {
  254. clearTimeout(this.outTimer);
  255. },
  256. clickTimer: function () {
  257. if(!this.timerRunning) {
  258. this.startClock();
  259. } else {
  260. this.stopClock();
  261. }
  262. },
  263. setupCaptions: function () {
  264. this.$caption = $(this.captionHTML);
  265. this.$wrapper.append(this.$caption);
  266. this.setCaption();
  267. },
  268. setCaption: function () {
  269. var captionLocation = this.currentSlide().attr('data-caption'),
  270. captionHTML;
  271. if (!this.options.captions) {
  272. return false;
  273. }
  274. //Set HTML for the caption if it exists
  275. if (captionLocation) {
  276. //if caption text is blank, don't show captions
  277. if ($.trim($(captionLocation).text()).length < 1){
  278. return false;
  279. }
  280. captionHTML = $(captionLocation).html(); //get HTML from the matching HTML entity
  281. this.$caption
  282. .attr('id', captionLocation) // Add ID caption TODO why is the id being set?
  283. .html(captionHTML); // Change HTML in Caption
  284. //Animations for Caption entrances
  285. switch (this.options.captionAnimation) {
  286. case 'none':
  287. this.$caption.show();
  288. break;
  289. case 'fade':
  290. this.$caption.fadeIn(this.options.captionAnimationSpeed);
  291. break;
  292. case 'slideOpen':
  293. this.$caption.slideDown(this.options.captionAnimationSpeed);
  294. break;
  295. }
  296. } else {
  297. //Animations for Caption exits
  298. switch (this.options.captionAnimation) {
  299. case 'none':
  300. this.$caption.hide();
  301. break;
  302. case 'fade':
  303. this.$caption.fadeOut(this.options.captionAnimationSpeed);
  304. break;
  305. case 'slideOpen':
  306. this.$caption.slideUp(this.options.captionAnimationSpeed);
  307. break;
  308. }
  309. }
  310. },
  311. setupDirectionalNav: function () {
  312. var self = this,
  313. $directionalNav = $(this.directionalNavHTML);
  314. $directionalNav.find('.right').html(this.options.directionalNavRightText);
  315. $directionalNav.find('.left').html(this.options.directionalNavLeftText);
  316. this.$wrapper.append($directionalNav);
  317. this.$wrapper.find('.left').click(function () {
  318. self.stopClock();
  319. if (self.options.resetTimerOnClick) {
  320. self.rotateTimer(true);
  321. self.startClock();
  322. }
  323. self.$element.trigger('orbit.prev');
  324. });
  325. this.$wrapper.find('.right').click(function () {
  326. self.stopClock();
  327. if (self.options.resetTimerOnClick) {
  328. self.rotateTimer(true);
  329. self.startClock();
  330. }
  331. self.$element.trigger('orbit.next');
  332. });
  333. },
  334. setupBulletNav: function () {
  335. this.$bullets = $(this.bulletHTML);
  336. this.$wrapper.append(this.$bullets);
  337. this.$slides.each(this.addBullet);
  338. this.$element.addClass('with-bullets');
  339. if (this.options.centerBullets) this.$bullets.css('margin-left', -this.$bullets.outerWidth() / 2);
  340. },
  341. addBullet: function (index, slide) {
  342. var position = index + 1,
  343. $li = $('<li>' + (position) + '</li>'),
  344. thumbName,
  345. self = this;
  346. if (this.options.bulletThumbs) {
  347. thumbName = $(slide).attr('data-thumb');
  348. if (thumbName) {
  349. $li
  350. .addClass('has-thumb')
  351. .css({background: "url(" + this.options.bulletThumbLocation + thumbName + ") no-repeat"});;
  352. }
  353. }
  354. this.$bullets.append($li);
  355. $li.data('index', index);
  356. $li.click(function () {
  357. self.stopClock();
  358. if (self.options.resetTimerOnClick) {
  359. self.rotateTimer(true);
  360. self.startClock();
  361. }
  362. self.$element.trigger('orbit.goto', [$li.data('index')])
  363. });
  364. },
  365. setActiveBullet: function () {
  366. if(!this.options.bullets) { return false; } else {
  367. this.$bullets.find('li')
  368. .removeClass('active')
  369. .eq(this.activeSlide)
  370. .addClass('active');
  371. }
  372. },
  373. resetAndUnlock: function () {
  374. this.$slides
  375. .eq(this.prevActiveSlide)
  376. .css({"z-index" : 1});
  377. this.unlock();
  378. this.options.afterSlideChange.call(this, this.$slides.eq(this.prevActiveSlide), this.$slides.eq(this.activeSlide));
  379. },
  380. shift: function (direction) {
  381. var slideDirection = direction;
  382. //remember previous activeSlide
  383. this.prevActiveSlide = this.activeSlide;
  384. //exit function if bullet clicked is same as the current image
  385. if (this.prevActiveSlide == slideDirection) { return false; }
  386. if (this.$slides.length == "1") { return false; }
  387. if (!this.locked) {
  388. this.lock();
  389. //deduce the proper activeImage
  390. if (direction == "next") {
  391. this.activeSlide++;
  392. if (this.activeSlide == this.numberSlides) {
  393. this.activeSlide = 0;
  394. }
  395. } else if (direction == "prev") {
  396. this.activeSlide--
  397. if (this.activeSlide < 0) {
  398. this.activeSlide = this.numberSlides - 1;
  399. }
  400. } else {
  401. this.activeSlide = direction;
  402. if (this.prevActiveSlide < this.activeSlide) {
  403. slideDirection = "next";
  404. } else if (this.prevActiveSlide > this.activeSlide) {
  405. slideDirection = "prev"
  406. }
  407. }
  408. //set to correct bullet
  409. this.setActiveBullet();
  410. //set previous slide z-index to one below what new activeSlide will be
  411. this.$slides
  412. .eq(this.prevActiveSlide)
  413. .css({"z-index" : 2});
  414. //fade
  415. if (this.options.animation == "fade") {
  416. this.$slides
  417. .eq(this.activeSlide)
  418. .css({"opacity" : 0, "z-index" : 3})
  419. .animate({"opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock);
  420. }
  421. //horizontal-slide
  422. if (this.options.animation == "horizontal-slide") {
  423. if (slideDirection == "next") {
  424. this.$slides
  425. .eq(this.activeSlide)
  426. .css({"left": this.orbitWidth, "z-index" : 3})
  427. .animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
  428. }
  429. if (slideDirection == "prev") {
  430. this.$slides
  431. .eq(this.activeSlide)
  432. .css({"left": -this.orbitWidth, "z-index" : 3})
  433. .animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
  434. }
  435. }
  436. //vertical-slide
  437. if (this.options.animation == "vertical-slide") {
  438. if (slideDirection == "prev") {
  439. this.$slides
  440. .eq(this.activeSlide)
  441. .css({"top": this.orbitHeight, "z-index" : 3})
  442. .animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock);
  443. }
  444. if (slideDirection == "next") {
  445. this.$slides
  446. .eq(this.activeSlide)
  447. .css({"top": -this.orbitHeight, "z-index" : 3})
  448. .animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock);
  449. }
  450. }
  451. //horizontal-push
  452. if (this.options.animation == "horizontal-push") {
  453. if (slideDirection == "next") {
  454. this.$slides
  455. .eq(this.activeSlide)
  456. .css({"left": this.orbitWidth, "z-index" : 3})
  457. .animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
  458. this.$slides
  459. .eq(this.prevActiveSlide)
  460. .animate({"left" : -this.orbitWidth}, this.options.animationSpeed);
  461. }
  462. if (slideDirection == "prev") {
  463. this.$slides
  464. .eq(this.activeSlide)
  465. .css({"left": -this.orbitWidth, "z-index" : 3})
  466. .animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
  467. this.$slides
  468. .eq(this.prevActiveSlide)
  469. .animate({"left" : this.orbitWidth}, this.options.animationSpeed);
  470. }
  471. }
  472. //vertical-push
  473. if (this.options.animation == "vertical-push") {
  474. if (slideDirection == "next") {
  475. this.$slides
  476. .eq(this.activeSlide)
  477. .css({top: -this.orbitHeight, "z-index" : 3})
  478. .animate({top : 0}, this.options.animationSpeed, this.resetAndUnlock);
  479. this.$slides
  480. .eq(this.prevActiveSlide)
  481. .animate({top : this.orbitHeight}, this.options.animationSpeed);
  482. }
  483. if (slideDirection == "prev") {
  484. this.$slides
  485. .eq(this.activeSlide)
  486. .css({top: this.orbitHeight, "z-index" : 3})
  487. .animate({top : 0}, this.options.animationSpeed, this.resetAndUnlock);
  488. this.$slides
  489. .eq(this.prevActiveSlide)
  490. .animate({top : -this.orbitHeight}, this.options.animationSpeed);
  491. }
  492. }
  493. this.setCaption();
  494. }
  495. }
  496. };
  497. $.fn.orbit = function (options) {
  498. return this.each(function () {
  499. var orbit = $.extend({}, ORBIT);
  500. orbit.init(this, options);
  501. });
  502. };
  503. })(jQuery);
  504. /*!
  505. * jQuery imageready Plugin
  506. * http://www.zurb.com/playground/
  507. *
  508. * Copyright 2011, ZURB
  509. * Released under the MIT License
  510. */
  511. (function ($) {
  512. var options = {};
  513. $.event.special.imageready = {
  514. setup: function (data, namespaces, eventHandle) {
  515. options = data || options;
  516. },
  517. add: function (handleObj) {
  518. var $this = $(this),
  519. src;
  520. if ( this.nodeType === 1 && this.tagName.toLowerCase() === 'img' && this.src !== '' ) {
  521. if (options.forceLoad) {
  522. src = $this.attr('src');
  523. $this.attr('src', '');
  524. bindToLoad(this, handleObj.handler);
  525. $this.attr('src', src);
  526. } else if ( this.complete || this.readyState === 4 ) {
  527. handleObj.handler.apply(this, arguments);
  528. } else {
  529. bindToLoad(this, handleObj.handler);
  530. }
  531. }
  532. },
  533. teardown: function (namespaces) {
  534. $(this).unbind('.imageready');
  535. }
  536. };
  537. function bindToLoad(element, callback) {
  538. var $this = $(element);
  539. $this.bind('load.imageready', function () {
  540. callback.apply(element, arguments);
  541. $this.unbind('load.imageready');
  542. });
  543. }
  544. }(jQuery));