player.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // player & autoPlay
  2. ( function( window, factory ) {
  3. // universal module definition
  4. /* jshint strict: false */
  5. if ( typeof define == 'function' && define.amd ) {
  6. // AMD
  7. define( [
  8. 'ev-emitter/ev-emitter',
  9. 'fizzy-ui-utils/utils',
  10. './flickity'
  11. ], function( EvEmitter, utils, Flickity ) {
  12. return factory( EvEmitter, utils, Flickity );
  13. });
  14. } else if ( typeof module == 'object' && module.exports ) {
  15. // CommonJS
  16. module.exports = factory(
  17. require('ev-emitter'),
  18. require('fizzy-ui-utils'),
  19. require('./flickity')
  20. );
  21. } else {
  22. // browser global
  23. factory(
  24. window.EvEmitter,
  25. window.fizzyUIUtils,
  26. window.Flickity
  27. );
  28. }
  29. }( window, function factory( EvEmitter, utils, Flickity ) {
  30. 'use strict';
  31. // -------------------------- Player -------------------------- //
  32. function Player( parent ) {
  33. this.parent = parent;
  34. this.state = 'stopped';
  35. // visibility change event handler
  36. this.onVisibilityChange = this.visibilityChange.bind( this );
  37. this.onVisibilityPlay = this.visibilityPlay.bind( this );
  38. }
  39. Player.prototype = Object.create( EvEmitter.prototype );
  40. // start play
  41. Player.prototype.play = function() {
  42. if ( this.state == 'playing' ) {
  43. return;
  44. }
  45. // do not play if page is hidden, start playing when page is visible
  46. var isPageHidden = document.hidden;
  47. if ( isPageHidden ) {
  48. document.addEventListener( 'visibilitychange', this.onVisibilityPlay );
  49. return;
  50. }
  51. this.state = 'playing';
  52. // listen to visibility change
  53. document.addEventListener( 'visibilitychange', this.onVisibilityChange );
  54. // start ticking
  55. this.tick();
  56. };
  57. Player.prototype.tick = function() {
  58. // do not tick if not playing
  59. if ( this.state != 'playing' ) {
  60. return;
  61. }
  62. var time = this.parent.options.autoPlay;
  63. // default to 3 seconds
  64. time = typeof time == 'number' ? time : 3000;
  65. var _this = this;
  66. // HACK: reset ticks if stopped and started within interval
  67. this.clear();
  68. this.timeout = setTimeout( function() {
  69. _this.parent.next( true );
  70. _this.tick();
  71. }, time );
  72. };
  73. Player.prototype.stop = function() {
  74. this.state = 'stopped';
  75. this.clear();
  76. // remove visibility change event
  77. document.removeEventListener( 'visibilitychange', this.onVisibilityChange );
  78. };
  79. Player.prototype.clear = function() {
  80. clearTimeout( this.timeout );
  81. };
  82. Player.prototype.pause = function() {
  83. if ( this.state == 'playing' ) {
  84. this.state = 'paused';
  85. this.clear();
  86. }
  87. };
  88. Player.prototype.unpause = function() {
  89. // re-start play if paused
  90. if ( this.state == 'paused' ) {
  91. this.play();
  92. }
  93. };
  94. // pause if page visibility is hidden, unpause if visible
  95. Player.prototype.visibilityChange = function() {
  96. var isPageHidden = document.hidden;
  97. this[ isPageHidden ? 'pause' : 'unpause' ]();
  98. };
  99. Player.prototype.visibilityPlay = function() {
  100. this.play();
  101. document.removeEventListener( 'visibilitychange', this.onVisibilityPlay );
  102. };
  103. // -------------------------- Flickity -------------------------- //
  104. utils.extend( Flickity.defaults, {
  105. pauseAutoPlayOnHover: true
  106. });
  107. Flickity.createMethods.push('_createPlayer');
  108. var proto = Flickity.prototype;
  109. proto._createPlayer = function() {
  110. this.player = new Player( this );
  111. this.on( 'activate', this.activatePlayer );
  112. this.on( 'uiChange', this.stopPlayer );
  113. this.on( 'pointerDown', this.stopPlayer );
  114. this.on( 'deactivate', this.deactivatePlayer );
  115. };
  116. proto.activatePlayer = function() {
  117. if ( !this.options.autoPlay ) {
  118. return;
  119. }
  120. this.player.play();
  121. this.element.addEventListener( 'mouseenter', this );
  122. };
  123. // Player API, don't hate the ... thanks I know where the door is
  124. proto.playPlayer = function() {
  125. this.player.play();
  126. };
  127. proto.stopPlayer = function() {
  128. this.player.stop();
  129. };
  130. proto.pausePlayer = function() {
  131. this.player.pause();
  132. };
  133. proto.unpausePlayer = function() {
  134. this.player.unpause();
  135. };
  136. proto.deactivatePlayer = function() {
  137. this.player.stop();
  138. this.element.removeEventListener( 'mouseenter', this );
  139. };
  140. // ----- mouseenter/leave ----- //
  141. // pause auto-play on hover
  142. proto.onmouseenter = function() {
  143. if ( !this.options.pauseAutoPlayOnHover ) {
  144. return;
  145. }
  146. this.player.pause();
  147. this.element.addEventListener( 'mouseleave', this );
  148. };
  149. // resume auto-play on hover off
  150. proto.onmouseleave = function() {
  151. this.player.unpause();
  152. this.element.removeEventListener( 'mouseleave', this );
  153. };
  154. // ----- ----- //
  155. Flickity.Player = Player;
  156. return Flickity;
  157. }));