autoplay.mjs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. import { g as getDocument } from '../shared/ssr-window.esm.mjs';
  2. /* eslint no-underscore-dangle: "off" */
  3. /* eslint no-use-before-define: "off" */
  4. function Autoplay(_ref) {
  5. let {
  6. swiper,
  7. extendParams,
  8. on,
  9. emit,
  10. params
  11. } = _ref;
  12. swiper.autoplay = {
  13. running: false,
  14. paused: false,
  15. timeLeft: 0
  16. };
  17. extendParams({
  18. autoplay: {
  19. enabled: false,
  20. delay: 3000,
  21. waitForTransition: true,
  22. disableOnInteraction: false,
  23. stopOnLastSlide: false,
  24. reverseDirection: false,
  25. pauseOnMouseEnter: false
  26. }
  27. });
  28. let timeout;
  29. let raf;
  30. let autoplayDelayTotal = params && params.autoplay ? params.autoplay.delay : 3000;
  31. let autoplayDelayCurrent = params && params.autoplay ? params.autoplay.delay : 3000;
  32. let autoplayTimeLeft;
  33. let autoplayStartTime = new Date().getTime();
  34. let wasPaused;
  35. let isTouched;
  36. let pausedByTouch;
  37. let touchStartTimeout;
  38. let slideChanged;
  39. let pausedByInteraction;
  40. let pausedByPointerEnter;
  41. function onTransitionEnd(e) {
  42. if (!swiper || swiper.destroyed || !swiper.wrapperEl) return;
  43. if (e.target !== swiper.wrapperEl) return;
  44. swiper.wrapperEl.removeEventListener('transitionend', onTransitionEnd);
  45. if (pausedByPointerEnter || e.detail && e.detail.bySwiperTouchMove) {
  46. return;
  47. }
  48. resume();
  49. }
  50. const calcTimeLeft = () => {
  51. if (swiper.destroyed || !swiper.autoplay.running) return;
  52. if (swiper.autoplay.paused) {
  53. wasPaused = true;
  54. } else if (wasPaused) {
  55. autoplayDelayCurrent = autoplayTimeLeft;
  56. wasPaused = false;
  57. }
  58. const timeLeft = swiper.autoplay.paused ? autoplayTimeLeft : autoplayStartTime + autoplayDelayCurrent - new Date().getTime();
  59. swiper.autoplay.timeLeft = timeLeft;
  60. emit('autoplayTimeLeft', timeLeft, timeLeft / autoplayDelayTotal);
  61. raf = requestAnimationFrame(() => {
  62. calcTimeLeft();
  63. });
  64. };
  65. const getSlideDelay = () => {
  66. let activeSlideEl;
  67. if (swiper.virtual && swiper.params.virtual.enabled) {
  68. activeSlideEl = swiper.slides.filter(slideEl => slideEl.classList.contains('swiper-slide-active'))[0];
  69. } else {
  70. activeSlideEl = swiper.slides[swiper.activeIndex];
  71. }
  72. if (!activeSlideEl) return undefined;
  73. const currentSlideDelay = parseInt(activeSlideEl.getAttribute('data-swiper-autoplay'), 10);
  74. return currentSlideDelay;
  75. };
  76. const run = delayForce => {
  77. if (swiper.destroyed || !swiper.autoplay.running) return;
  78. cancelAnimationFrame(raf);
  79. calcTimeLeft();
  80. let delay = typeof delayForce === 'undefined' ? swiper.params.autoplay.delay : delayForce;
  81. autoplayDelayTotal = swiper.params.autoplay.delay;
  82. autoplayDelayCurrent = swiper.params.autoplay.delay;
  83. const currentSlideDelay = getSlideDelay();
  84. if (!Number.isNaN(currentSlideDelay) && currentSlideDelay > 0 && typeof delayForce === 'undefined') {
  85. delay = currentSlideDelay;
  86. autoplayDelayTotal = currentSlideDelay;
  87. autoplayDelayCurrent = currentSlideDelay;
  88. }
  89. autoplayTimeLeft = delay;
  90. const speed = swiper.params.speed;
  91. const proceed = () => {
  92. if (!swiper || swiper.destroyed) return;
  93. if (swiper.params.autoplay.reverseDirection) {
  94. if (!swiper.isBeginning || swiper.params.loop || swiper.params.rewind) {
  95. swiper.slidePrev(speed, true, true);
  96. emit('autoplay');
  97. } else if (!swiper.params.autoplay.stopOnLastSlide) {
  98. swiper.slideTo(swiper.slides.length - 1, speed, true, true);
  99. emit('autoplay');
  100. }
  101. } else {
  102. if (!swiper.isEnd || swiper.params.loop || swiper.params.rewind) {
  103. swiper.slideNext(speed, true, true);
  104. emit('autoplay');
  105. } else if (!swiper.params.autoplay.stopOnLastSlide) {
  106. swiper.slideTo(0, speed, true, true);
  107. emit('autoplay');
  108. }
  109. }
  110. if (swiper.params.cssMode) {
  111. autoplayStartTime = new Date().getTime();
  112. requestAnimationFrame(() => {
  113. run();
  114. });
  115. }
  116. };
  117. if (delay > 0) {
  118. clearTimeout(timeout);
  119. timeout = setTimeout(() => {
  120. proceed();
  121. }, delay);
  122. } else {
  123. requestAnimationFrame(() => {
  124. proceed();
  125. });
  126. }
  127. // eslint-disable-next-line
  128. return delay;
  129. };
  130. const start = () => {
  131. autoplayStartTime = new Date().getTime();
  132. swiper.autoplay.running = true;
  133. run();
  134. emit('autoplayStart');
  135. };
  136. const stop = () => {
  137. swiper.autoplay.running = false;
  138. clearTimeout(timeout);
  139. cancelAnimationFrame(raf);
  140. emit('autoplayStop');
  141. };
  142. const pause = (internal, reset) => {
  143. if (swiper.destroyed || !swiper.autoplay.running) return;
  144. clearTimeout(timeout);
  145. if (!internal) {
  146. pausedByInteraction = true;
  147. }
  148. const proceed = () => {
  149. emit('autoplayPause');
  150. if (swiper.params.autoplay.waitForTransition) {
  151. swiper.wrapperEl.addEventListener('transitionend', onTransitionEnd);
  152. } else {
  153. resume();
  154. }
  155. };
  156. swiper.autoplay.paused = true;
  157. if (reset) {
  158. if (slideChanged) {
  159. autoplayTimeLeft = swiper.params.autoplay.delay;
  160. }
  161. slideChanged = false;
  162. proceed();
  163. return;
  164. }
  165. const delay = autoplayTimeLeft || swiper.params.autoplay.delay;
  166. autoplayTimeLeft = delay - (new Date().getTime() - autoplayStartTime);
  167. if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop) return;
  168. if (autoplayTimeLeft < 0) autoplayTimeLeft = 0;
  169. proceed();
  170. };
  171. const resume = () => {
  172. if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop || swiper.destroyed || !swiper.autoplay.running) return;
  173. autoplayStartTime = new Date().getTime();
  174. if (pausedByInteraction) {
  175. pausedByInteraction = false;
  176. run(autoplayTimeLeft);
  177. } else {
  178. run();
  179. }
  180. swiper.autoplay.paused = false;
  181. emit('autoplayResume');
  182. };
  183. const onVisibilityChange = () => {
  184. if (swiper.destroyed || !swiper.autoplay.running) return;
  185. const document = getDocument();
  186. if (document.visibilityState === 'hidden') {
  187. pausedByInteraction = true;
  188. pause(true);
  189. }
  190. if (document.visibilityState === 'visible') {
  191. resume();
  192. }
  193. };
  194. const onPointerEnter = e => {
  195. if (e.pointerType !== 'mouse') return;
  196. pausedByInteraction = true;
  197. pausedByPointerEnter = true;
  198. if (swiper.animating || swiper.autoplay.paused) return;
  199. pause(true);
  200. };
  201. const onPointerLeave = e => {
  202. if (e.pointerType !== 'mouse') return;
  203. pausedByPointerEnter = false;
  204. if (swiper.autoplay.paused) {
  205. resume();
  206. }
  207. };
  208. const attachMouseEvents = () => {
  209. if (swiper.params.autoplay.pauseOnMouseEnter) {
  210. swiper.el.addEventListener('pointerenter', onPointerEnter);
  211. swiper.el.addEventListener('pointerleave', onPointerLeave);
  212. }
  213. };
  214. const detachMouseEvents = () => {
  215. if (swiper.el && typeof swiper.el !== 'string') {
  216. swiper.el.removeEventListener('pointerenter', onPointerEnter);
  217. swiper.el.removeEventListener('pointerleave', onPointerLeave);
  218. }
  219. };
  220. const attachDocumentEvents = () => {
  221. const document = getDocument();
  222. document.addEventListener('visibilitychange', onVisibilityChange);
  223. };
  224. const detachDocumentEvents = () => {
  225. const document = getDocument();
  226. document.removeEventListener('visibilitychange', onVisibilityChange);
  227. };
  228. on('init', () => {
  229. if (swiper.params.autoplay.enabled) {
  230. attachMouseEvents();
  231. attachDocumentEvents();
  232. start();
  233. }
  234. });
  235. on('destroy', () => {
  236. detachMouseEvents();
  237. detachDocumentEvents();
  238. if (swiper.autoplay.running) {
  239. stop();
  240. }
  241. });
  242. on('_freeModeStaticRelease', () => {
  243. if (pausedByTouch || pausedByInteraction) {
  244. resume();
  245. }
  246. });
  247. on('_freeModeNoMomentumRelease', () => {
  248. if (!swiper.params.autoplay.disableOnInteraction) {
  249. pause(true, true);
  250. } else {
  251. stop();
  252. }
  253. });
  254. on('beforeTransitionStart', (_s, speed, internal) => {
  255. if (swiper.destroyed || !swiper.autoplay.running) return;
  256. if (internal || !swiper.params.autoplay.disableOnInteraction) {
  257. pause(true, true);
  258. } else {
  259. stop();
  260. }
  261. });
  262. on('sliderFirstMove', () => {
  263. if (swiper.destroyed || !swiper.autoplay.running) return;
  264. if (swiper.params.autoplay.disableOnInteraction) {
  265. stop();
  266. return;
  267. }
  268. isTouched = true;
  269. pausedByTouch = false;
  270. pausedByInteraction = false;
  271. touchStartTimeout = setTimeout(() => {
  272. pausedByInteraction = true;
  273. pausedByTouch = true;
  274. pause(true);
  275. }, 200);
  276. });
  277. on('touchEnd', () => {
  278. if (swiper.destroyed || !swiper.autoplay.running || !isTouched) return;
  279. clearTimeout(touchStartTimeout);
  280. clearTimeout(timeout);
  281. if (swiper.params.autoplay.disableOnInteraction) {
  282. pausedByTouch = false;
  283. isTouched = false;
  284. return;
  285. }
  286. if (pausedByTouch && swiper.params.cssMode) resume();
  287. pausedByTouch = false;
  288. isTouched = false;
  289. });
  290. on('slideChange', () => {
  291. if (swiper.destroyed || !swiper.autoplay.running) return;
  292. slideChanged = true;
  293. });
  294. Object.assign(swiper.autoplay, {
  295. start,
  296. stop,
  297. pause,
  298. resume
  299. });
  300. }
  301. export { Autoplay as default };