flickity-fade.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /**
  2. * Flickity fade v1.0.0
  3. * Fade between Flickity slides
  4. */
  5. /* jshint browser: true, undef: true, unused: true */
  6. ( function( window, factory ) {
  7. // universal module definition
  8. /*globals define, module, require */
  9. if ( typeof define == 'function' && define.amd ) {
  10. // AMD
  11. define( [
  12. 'flickity/js/index',
  13. 'fizzy-ui-utils/utils',
  14. ], factory );
  15. } else if ( typeof module == 'object' && module.exports ) {
  16. // CommonJS
  17. module.exports = factory(
  18. require('flickity'),
  19. require('fizzy-ui-utils')
  20. );
  21. } else {
  22. // browser global
  23. factory(
  24. window.Flickity,
  25. window.fizzyUIUtils
  26. );
  27. }
  28. }( this, function factory( Flickity, utils ) {
  29. // ---- Slide ---- //
  30. var Slide = Flickity.Slide;
  31. var slideUpdateTarget = Slide.prototype.updateTarget;
  32. Slide.prototype.updateTarget = function() {
  33. slideUpdateTarget.apply( this, arguments );
  34. if ( !this.parent.options.fade ) {
  35. return;
  36. }
  37. // position cells at selected target
  38. var slideTargetX = this.target - this.x;
  39. var firstCellX = this.cells[0].x;
  40. this.cells.forEach( function( cell ) {
  41. var targetX = cell.x - firstCellX - slideTargetX;
  42. cell.renderPosition( targetX );
  43. });
  44. };
  45. Slide.prototype.setOpacity = function( alpha ) {
  46. this.cells.forEach( function( cell ) {
  47. cell.element.style.opacity = alpha;
  48. });
  49. };
  50. // ---- Flickity ---- //
  51. var proto = Flickity.prototype;
  52. Flickity.createMethods.push('_createFade');
  53. proto._createFade = function() {
  54. this.fadeIndex = this.selectedIndex;
  55. this.prevSelectedIndex = this.selectedIndex;
  56. this.on( 'select', this.onSelectFade );
  57. this.on( 'dragEnd', this.onDragEndFade );
  58. this.on( 'settle', this.onSettleFade );
  59. this.on( 'activate', this.onActivateFade );
  60. this.on( 'deactivate', this.onDeactivateFade );
  61. };
  62. var updateSlides = proto.updateSlides;
  63. proto.updateSlides = function() {
  64. updateSlides.apply( this, arguments );
  65. if ( !this.options.fade ) {
  66. return;
  67. }
  68. // set initial opacity
  69. this.slides.forEach( function( slide, i ) {
  70. var alpha = i == this.selectedIndex ? 1 : 0;
  71. slide.setOpacity( alpha );
  72. }, this );
  73. };
  74. /* ---- events ---- */
  75. proto.onSelectFade = function() {
  76. // in case of resize, keep fadeIndex within current count
  77. this.fadeIndex = Math.min( this.prevSelectedIndex, this.slides.length - 1 );
  78. this.prevSelectedIndex = this.selectedIndex;
  79. };
  80. proto.onSettleFade = function() {
  81. delete this.didDragEnd;
  82. if ( !this.options.fade ) {
  83. return;
  84. }
  85. // set full and 0 opacity on selected & faded slides
  86. this.selectedSlide.setOpacity( 1 );
  87. var fadedSlide = this.slides[ this.fadeIndex ];
  88. if ( fadedSlide && this.fadeIndex != this.selectedIndex ) {
  89. this.slides[ this.fadeIndex ].setOpacity( 0 );
  90. }
  91. };
  92. proto.onDragEndFade = function() {
  93. // set flag
  94. this.didDragEnd = true;
  95. };
  96. proto.onActivateFade = function() {
  97. if ( this.options.fade ) {
  98. this.element.classList.add('is-fade');
  99. }
  100. };
  101. proto.onDeactivateFade = function() {
  102. if ( !this.options.fade ) {
  103. return;
  104. }
  105. this.element.classList.remove('is-fade');
  106. // reset opacity
  107. this.slides.forEach( function( slide ) {
  108. slide.setOpacity('');
  109. });
  110. };
  111. /* ---- position & fading ---- */
  112. var positionSlider = proto.positionSlider;
  113. proto.positionSlider = function() {
  114. if ( !this.options.fade ) {
  115. positionSlider.apply( this, arguments );
  116. return;
  117. }
  118. this.fadeSlides();
  119. this.dispatchScrollEvent();
  120. };
  121. var positionSliderAtSelected = proto.positionSliderAtSelected;
  122. proto.positionSliderAtSelected = function() {
  123. if ( this.options.fade ) {
  124. // position fade slider at origin
  125. this.setTranslateX( 0 );
  126. }
  127. positionSliderAtSelected.apply( this, arguments );
  128. };
  129. proto.fadeSlides = function() {
  130. if ( this.slides.length < 2 ) {
  131. return;
  132. }
  133. // get slides to fade-in & fade-out
  134. var indexes = this.getFadeIndexes();
  135. var fadeSlideA = this.slides[ indexes.a ];
  136. var fadeSlideB = this.slides[ indexes.b ];
  137. var distance = this.wrapDifference( fadeSlideA.target, fadeSlideB.target );
  138. var progress = this.wrapDifference( fadeSlideA.target, -this.x );
  139. progress = progress / distance;
  140. fadeSlideA.setOpacity( 1 - progress );
  141. fadeSlideB.setOpacity( progress );
  142. // hide previous slide
  143. var fadeHideIndex = indexes.a;
  144. if ( this.isDragging ) {
  145. fadeHideIndex = progress > 0.5 ? indexes.a : indexes.b;
  146. }
  147. var isNewHideIndex = this.fadeHideIndex != undefined &&
  148. this.fadeHideIndex != fadeHideIndex &&
  149. this.fadeHideIndex != indexes.a &&
  150. this.fadeHideIndex != indexes.b;
  151. if ( isNewHideIndex ) {
  152. // new fadeHideSlide set, hide previous
  153. this.slides[ this.fadeHideIndex ].setOpacity( 0 );
  154. }
  155. this.fadeHideIndex = fadeHideIndex;
  156. };
  157. proto.getFadeIndexes = function() {
  158. if ( !this.isDragging && !this.didDragEnd ) {
  159. return {
  160. a: this.fadeIndex,
  161. b: this.selectedIndex,
  162. };
  163. }
  164. if ( this.options.wrapAround ) {
  165. return this.getFadeDragWrapIndexes();
  166. } else {
  167. return this.getFadeDragLimitIndexes();
  168. }
  169. };
  170. proto.getFadeDragWrapIndexes = function() {
  171. var distances = this.slides.map( function( slide, i ) {
  172. return this.getSlideDistance( -this.x, i );
  173. }, this );
  174. var absDistances = distances.map( function( distance ) {
  175. return Math.abs( distance );
  176. });
  177. var minDistance = Math.min.apply( Math, absDistances );
  178. var closestIndex = absDistances.indexOf( minDistance );
  179. var distance = distances[ closestIndex ];
  180. var len = this.slides.length;
  181. var delta = distance >= 0 ? 1 : -1;
  182. return {
  183. a: closestIndex,
  184. b: utils.modulo( closestIndex + delta, len ),
  185. };
  186. };
  187. proto.getFadeDragLimitIndexes = function() {
  188. // calculate closest previous slide
  189. var dragIndex = 0;
  190. for ( var i=0; i < this.slides.length - 1; i++ ) {
  191. var slide = this.slides[i];
  192. if ( -this.x < slide.target ) {
  193. break;
  194. }
  195. dragIndex = i;
  196. }
  197. return {
  198. a: dragIndex,
  199. b: dragIndex + 1,
  200. };
  201. };
  202. proto.wrapDifference = function( a, b ) {
  203. var diff = b - a;
  204. if ( !this.options.wrapAround ) {
  205. return diff;
  206. }
  207. var diffPlus = diff + this.slideableWidth;
  208. var diffMinus = diff - this.slideableWidth;
  209. if ( Math.abs( diffPlus ) < Math.abs( diff ) ) {
  210. diff = diffPlus;
  211. }
  212. if ( Math.abs( diffMinus ) < Math.abs( diff ) ) {
  213. diff = diffMinus;
  214. }
  215. return diff;
  216. };
  217. // ---- wrapAround ---- //
  218. var _getWrapShiftCells = proto._getWrapShiftCells;
  219. proto._getWrapShiftCells = function() {
  220. if ( !this.options.fade ) {
  221. _getWrapShiftCells.apply( this, arguments );
  222. }
  223. };
  224. var shiftWrapCells = proto.shiftWrapCells;
  225. proto.shiftWrapCells = function() {
  226. if ( !this.options.fade ) {
  227. shiftWrapCells.apply( this, arguments );
  228. }
  229. };
  230. return Flickity;
  231. }));