jquery.orbit-1.3.0.js 19 KB

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