jquery.orbit-1.3.0.js 19 KB

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