prev-next-button.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // prev/next buttons
  2. ( function( window, factory ) {
  3. // universal module definition
  4. /* jshint strict: false */
  5. if ( typeof define == 'function' && define.amd ) {
  6. // AMD
  7. define( [
  8. './flickity',
  9. 'unipointer/unipointer',
  10. 'fizzy-ui-utils/utils'
  11. ], function( Flickity, Unipointer, utils ) {
  12. return factory( window, Flickity, Unipointer, utils );
  13. });
  14. } else if ( typeof module == 'object' && module.exports ) {
  15. // CommonJS
  16. module.exports = factory(
  17. window,
  18. require('./flickity'),
  19. require('unipointer'),
  20. require('fizzy-ui-utils')
  21. );
  22. } else {
  23. // browser global
  24. factory(
  25. window,
  26. window.Flickity,
  27. window.Unipointer,
  28. window.fizzyUIUtils
  29. );
  30. }
  31. }( window, function factory( window, Flickity, Unipointer, utils ) {
  32. 'use strict';
  33. var svgURI = 'http://www.w3.org/2000/svg';
  34. // -------------------------- PrevNextButton -------------------------- //
  35. function PrevNextButton( direction, parent ) {
  36. this.direction = direction;
  37. this.parent = parent;
  38. this._create();
  39. }
  40. PrevNextButton.prototype = Object.create( Unipointer.prototype );
  41. PrevNextButton.prototype._create = function() {
  42. // properties
  43. this.isEnabled = true;
  44. this.isPrevious = this.direction == -1;
  45. var leftDirection = this.parent.options.rightToLeft ? 1 : -1;
  46. this.isLeft = this.direction == leftDirection;
  47. var element = this.element = document.createElement('button');
  48. element.className = 'flickity-button flickity-prev-next-button';
  49. element.className += this.isPrevious ? ' previous' : ' next';
  50. // prevent button from submitting form http://stackoverflow.com/a/10836076/182183
  51. element.setAttribute( 'type', 'button' );
  52. // init as disabled
  53. this.disable();
  54. element.setAttribute( 'aria-label', this.isPrevious ? 'Previous' : 'Next' );
  55. // create arrow
  56. var svg = this.createSVG();
  57. element.appendChild( svg );
  58. // events
  59. this.parent.on( 'select', this.update.bind( this ) );
  60. this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) );
  61. };
  62. PrevNextButton.prototype.activate = function() {
  63. this.bindStartEvent( this.element );
  64. this.element.addEventListener( 'click', this );
  65. // add to DOM
  66. this.parent.element.appendChild( this.element );
  67. };
  68. PrevNextButton.prototype.deactivate = function() {
  69. // remove from DOM
  70. this.parent.element.removeChild( this.element );
  71. // click events
  72. this.unbindStartEvent( this.element );
  73. this.element.removeEventListener( 'click', this );
  74. };
  75. PrevNextButton.prototype.createSVG = function() {
  76. var svg = document.createElementNS( svgURI, 'svg');
  77. svg.setAttribute( 'class', 'flickity-button-icon' );
  78. svg.setAttribute( 'viewBox', '0 0 100 100' );
  79. var path = document.createElementNS( svgURI, 'path');
  80. var pathMovements = getArrowMovements( this.parent.options.arrowShape );
  81. path.setAttribute( 'd', pathMovements );
  82. path.setAttribute( 'class', 'arrow' );
  83. // rotate arrow
  84. if ( !this.isLeft ) {
  85. path.setAttribute( 'transform', 'translate(100, 100) rotate(180) ' );
  86. }
  87. svg.appendChild( path );
  88. return svg;
  89. };
  90. // get SVG path movmement
  91. function getArrowMovements( shape ) {
  92. // use shape as movement if string
  93. if ( typeof shape == 'string' ) {
  94. return shape;
  95. }
  96. // create movement string
  97. return 'M ' + shape.x0 + ',50' +
  98. ' L ' + shape.x1 + ',' + ( shape.y1 + 50 ) +
  99. ' L ' + shape.x2 + ',' + ( shape.y2 + 50 ) +
  100. ' L ' + shape.x3 + ',50 ' +
  101. ' L ' + shape.x2 + ',' + ( 50 - shape.y2 ) +
  102. ' L ' + shape.x1 + ',' + ( 50 - shape.y1 ) +
  103. ' Z';
  104. }
  105. PrevNextButton.prototype.handleEvent = utils.handleEvent;
  106. PrevNextButton.prototype.onclick = function() {
  107. if ( !this.isEnabled ) {
  108. return;
  109. }
  110. this.parent.uiChange();
  111. var method = this.isPrevious ? 'previous' : 'next';
  112. this.parent[ method ]();
  113. };
  114. // ----- ----- //
  115. PrevNextButton.prototype.enable = function() {
  116. if ( this.isEnabled ) {
  117. return;
  118. }
  119. this.element.disabled = false;
  120. this.isEnabled = true;
  121. };
  122. PrevNextButton.prototype.disable = function() {
  123. if ( !this.isEnabled ) {
  124. return;
  125. }
  126. this.element.disabled = true;
  127. this.isEnabled = false;
  128. };
  129. PrevNextButton.prototype.update = function() {
  130. // index of first or last slide, if previous or next
  131. var slides = this.parent.slides;
  132. // enable is wrapAround and at least 2 slides
  133. if ( this.parent.options.wrapAround && slides.length > 1 ) {
  134. this.enable();
  135. return;
  136. }
  137. var lastIndex = slides.length ? slides.length - 1 : 0;
  138. var boundIndex = this.isPrevious ? 0 : lastIndex;
  139. var method = this.parent.selectedIndex == boundIndex ? 'disable' : 'enable';
  140. this[ method ]();
  141. };
  142. PrevNextButton.prototype.destroy = function() {
  143. this.deactivate();
  144. this.allOff();
  145. };
  146. // -------------------------- Flickity prototype -------------------------- //
  147. utils.extend( Flickity.defaults, {
  148. prevNextButtons: true,
  149. arrowShape: {
  150. x0: 10,
  151. x1: 60, y1: 50,
  152. x2: 70, y2: 40,
  153. x3: 30
  154. }
  155. });
  156. Flickity.createMethods.push('_createPrevNextButtons');
  157. var proto = Flickity.prototype;
  158. proto._createPrevNextButtons = function() {
  159. if ( !this.options.prevNextButtons ) {
  160. return;
  161. }
  162. this.prevButton = new PrevNextButton( -1, this );
  163. this.nextButton = new PrevNextButton( 1, this );
  164. this.on( 'activate', this.activatePrevNextButtons );
  165. };
  166. proto.activatePrevNextButtons = function() {
  167. this.prevButton.activate();
  168. this.nextButton.activate();
  169. this.on( 'deactivate', this.deactivatePrevNextButtons );
  170. };
  171. proto.deactivatePrevNextButtons = function() {
  172. this.prevButton.deactivate();
  173. this.nextButton.deactivate();
  174. this.off( 'deactivate', this.deactivatePrevNextButtons );
  175. };
  176. // -------------------------- -------------------------- //
  177. Flickity.PrevNextButton = PrevNextButton;
  178. return Flickity;
  179. }));