slide.esm.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. /*!
  2. * better-scroll / slide
  3. * (c) 2016-2021 ustbhuangyi
  4. * Released under the MIT License.
  5. */
  6. function warn(msg) {
  7. console.error("[BScroll warn]: " + msg);
  8. }
  9. // ssr support
  10. var inBrowser = typeof window !== 'undefined';
  11. var ua = inBrowser && navigator.userAgent.toLowerCase();
  12. !!(ua && /wechatdevtools/.test(ua));
  13. ua && ua.indexOf('android') > 0;
  14. /* istanbul ignore next */
  15. ((function () {
  16. if (typeof ua === 'string') {
  17. var regex = /os (\d\d?_\d(_\d)?)/;
  18. var matches = regex.exec(ua);
  19. if (!matches)
  20. return false;
  21. var parts = matches[1].split('_').map(function (item) {
  22. return parseInt(item, 10);
  23. });
  24. // ios version >= 13.4 issue 982
  25. return !!(parts[0] === 13 && parts[1] >= 4);
  26. }
  27. return false;
  28. }))();
  29. /* istanbul ignore next */
  30. var supportsPassive = false;
  31. /* istanbul ignore next */
  32. if (inBrowser) {
  33. var EventName = 'test-passive';
  34. try {
  35. var opts = {};
  36. Object.defineProperty(opts, 'passive', {
  37. get: function () {
  38. supportsPassive = true;
  39. },
  40. }); // https://github.com/facebook/flow/issues/285
  41. window.addEventListener(EventName, function () { }, opts);
  42. }
  43. catch (e) { }
  44. }
  45. var extend = function (target, source) {
  46. for (var key in source) {
  47. target[key] = source[key];
  48. }
  49. return target;
  50. };
  51. function between(x, min, max) {
  52. if (x < min) {
  53. return min;
  54. }
  55. if (x > max) {
  56. return max;
  57. }
  58. return x;
  59. }
  60. var elementStyle = (inBrowser &&
  61. document.createElement('div').style);
  62. var vendor = (function () {
  63. /* istanbul ignore if */
  64. if (!inBrowser) {
  65. return false;
  66. }
  67. var transformNames = [
  68. {
  69. key: 'standard',
  70. value: 'transform',
  71. },
  72. {
  73. key: 'webkit',
  74. value: 'webkitTransform',
  75. },
  76. {
  77. key: 'Moz',
  78. value: 'MozTransform',
  79. },
  80. {
  81. key: 'O',
  82. value: 'OTransform',
  83. },
  84. {
  85. key: 'ms',
  86. value: 'msTransform',
  87. },
  88. ];
  89. for (var _i = 0, transformNames_1 = transformNames; _i < transformNames_1.length; _i++) {
  90. var obj = transformNames_1[_i];
  91. if (elementStyle[obj.value] !== undefined) {
  92. return obj.key;
  93. }
  94. }
  95. /* istanbul ignore next */
  96. return false;
  97. })();
  98. /* istanbul ignore next */
  99. function prefixStyle(style) {
  100. if (vendor === false) {
  101. return style;
  102. }
  103. if (vendor === 'standard') {
  104. if (style === 'transitionEnd') {
  105. return 'transitionend';
  106. }
  107. return style;
  108. }
  109. return vendor + style.charAt(0).toUpperCase() + style.substr(1);
  110. }
  111. vendor && vendor !== 'standard' ? '-' + vendor.toLowerCase() + '-' : '';
  112. var transform = prefixStyle('transform');
  113. var transition = prefixStyle('transition');
  114. inBrowser && prefixStyle('perspective') in elementStyle;
  115. ({
  116. transform: transform,
  117. transition: transition,
  118. transitionTimingFunction: prefixStyle('transitionTimingFunction'),
  119. transitionDuration: prefixStyle('transitionDuration'),
  120. transitionDelay: prefixStyle('transitionDelay'),
  121. transformOrigin: prefixStyle('transformOrigin'),
  122. transitionEnd: prefixStyle('transitionEnd'),
  123. transitionProperty: prefixStyle('transitionProperty'),
  124. });
  125. function prepend(el, target) {
  126. var firstChild = target.firstChild;
  127. if (firstChild) {
  128. before(el, firstChild);
  129. }
  130. else {
  131. target.appendChild(el);
  132. }
  133. }
  134. function before(el, target) {
  135. var parentNode = target.parentNode;
  136. parentNode.insertBefore(el, target);
  137. }
  138. function removeChild(el, child) {
  139. el.removeChild(child);
  140. }
  141. var ease = {
  142. // easeOutQuint
  143. swipe: {
  144. style: 'cubic-bezier(0.23, 1, 0.32, 1)',
  145. fn: function (t) {
  146. return 1 + --t * t * t * t * t;
  147. }
  148. },
  149. // easeOutQuard
  150. swipeBounce: {
  151. style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
  152. fn: function (t) {
  153. return t * (2 - t);
  154. }
  155. },
  156. // easeOutQuart
  157. bounce: {
  158. style: 'cubic-bezier(0.165, 0.84, 0.44, 1)',
  159. fn: function (t) {
  160. return 1 - --t * t * t * t;
  161. }
  162. }
  163. };
  164. var PagesMatrix = /** @class */ (function () {
  165. function PagesMatrix(scroll) {
  166. this.scroll = scroll;
  167. this.init();
  168. }
  169. PagesMatrix.prototype.init = function () {
  170. var scroller = this.scroll.scroller;
  171. var scrollBehaviorX = scroller.scrollBehaviorX, scrollBehaviorY = scroller.scrollBehaviorY;
  172. this.wrapperWidth = scrollBehaviorX.wrapperSize;
  173. this.wrapperHeight = scrollBehaviorY.wrapperSize;
  174. this.scrollerHeight = scrollBehaviorY.contentSize;
  175. this.scrollerWidth = scrollBehaviorX.contentSize;
  176. this.pages = this.buildPagesMatrix(this.wrapperWidth, this.wrapperHeight);
  177. this.pageLengthOfX = this.pages ? this.pages.length : 0;
  178. this.pageLengthOfY = this.pages && this.pages[0] ? this.pages[0].length : 0;
  179. };
  180. PagesMatrix.prototype.getPageStats = function (pageX, pageY) {
  181. return this.pages[pageX][pageY];
  182. };
  183. PagesMatrix.prototype.getNearestPageIndex = function (x, y) {
  184. var pageX = 0;
  185. var pageY = 0;
  186. var l = this.pages.length;
  187. for (; pageX < l - 1; pageX++) {
  188. if (x >= this.pages[pageX][0].cx) {
  189. break;
  190. }
  191. }
  192. l = this.pages[pageX].length;
  193. for (; pageY < l - 1; pageY++) {
  194. if (y >= this.pages[0][pageY].cy) {
  195. break;
  196. }
  197. }
  198. return {
  199. pageX: pageX,
  200. pageY: pageY,
  201. };
  202. };
  203. // (n x 1) matrix for horizontal scroll or
  204. // (1 * n) matrix for vertical scroll
  205. PagesMatrix.prototype.buildPagesMatrix = function (stepX, stepY) {
  206. var pages = [];
  207. var x = 0;
  208. var y;
  209. var cx;
  210. var cy;
  211. var i = 0;
  212. var l;
  213. var maxScrollPosX = this.scroll.scroller.scrollBehaviorX.maxScrollPos;
  214. var maxScrollPosY = this.scroll.scroller.scrollBehaviorY.maxScrollPos;
  215. cx = Math.round(stepX / 2);
  216. cy = Math.round(stepY / 2);
  217. while (x > -this.scrollerWidth) {
  218. pages[i] = [];
  219. l = 0;
  220. y = 0;
  221. while (y > -this.scrollerHeight) {
  222. pages[i][l] = {
  223. x: Math.max(x, maxScrollPosX),
  224. y: Math.max(y, maxScrollPosY),
  225. width: stepX,
  226. height: stepY,
  227. cx: x - cx,
  228. cy: y - cy,
  229. };
  230. y -= stepY;
  231. l++;
  232. }
  233. x -= stepX;
  234. i++;
  235. }
  236. return pages;
  237. };
  238. return PagesMatrix;
  239. }());
  240. var BASE_PAGE = {
  241. pageX: 0,
  242. pageY: 0,
  243. x: 0,
  244. y: 0,
  245. };
  246. var SlidePages = /** @class */ (function () {
  247. function SlidePages(scroll, slideOptions) {
  248. this.scroll = scroll;
  249. this.slideOptions = slideOptions;
  250. this.slideX = false;
  251. this.slideY = false;
  252. this.currentPage = extend({}, BASE_PAGE);
  253. }
  254. SlidePages.prototype.refresh = function () {
  255. this.pagesMatrix = new PagesMatrix(this.scroll);
  256. this.checkSlideLoop();
  257. this.currentPage = this.getAdjustedCurrentPage();
  258. };
  259. SlidePages.prototype.getAdjustedCurrentPage = function () {
  260. var _a = this.currentPage, pageX = _a.pageX, pageY = _a.pageY;
  261. // page index should be handled
  262. // because page counts may reduce
  263. pageX = Math.min(pageX, this.pagesMatrix.pageLengthOfX - 1);
  264. pageY = Math.min(pageY, this.pagesMatrix.pageLengthOfY - 1);
  265. // loop scene should also be respected
  266. // because clonedNode will cause pageLength increasing
  267. if (this.loopX) {
  268. pageX = Math.min(pageX, this.pagesMatrix.pageLengthOfX - 2);
  269. }
  270. if (this.loopY) {
  271. pageY = Math.min(pageY, this.pagesMatrix.pageLengthOfY - 2);
  272. }
  273. var _b = this.pagesMatrix.getPageStats(pageX, pageY), x = _b.x, y = _b.y;
  274. return { pageX: pageX, pageY: pageY, x: x, y: y };
  275. };
  276. SlidePages.prototype.setCurrentPage = function (newPage) {
  277. this.currentPage = newPage;
  278. };
  279. SlidePages.prototype.getInternalPage = function (pageX, pageY) {
  280. if (pageX >= this.pagesMatrix.pageLengthOfX) {
  281. pageX = this.pagesMatrix.pageLengthOfX - 1;
  282. }
  283. else if (pageX < 0) {
  284. pageX = 0;
  285. }
  286. if (pageY >= this.pagesMatrix.pageLengthOfY) {
  287. pageY = this.pagesMatrix.pageLengthOfY - 1;
  288. }
  289. else if (pageY < 0) {
  290. pageY = 0;
  291. }
  292. var _a = this.pagesMatrix.getPageStats(pageX, pageY), x = _a.x, y = _a.y;
  293. return {
  294. pageX: pageX,
  295. pageY: pageY,
  296. x: x,
  297. y: y,
  298. };
  299. };
  300. SlidePages.prototype.getInitialPage = function (showFirstPage, firstInitialised) {
  301. if (showFirstPage === void 0) { showFirstPage = false; }
  302. if (firstInitialised === void 0) { firstInitialised = false; }
  303. var _a = this.slideOptions, startPageXIndex = _a.startPageXIndex, startPageYIndex = _a.startPageYIndex;
  304. var firstPageX = this.loopX ? 1 : 0;
  305. var firstPageY = this.loopY ? 1 : 0;
  306. var pageX = showFirstPage ? firstPageX : this.currentPage.pageX;
  307. var pageY = showFirstPage ? firstPageY : this.currentPage.pageY;
  308. if (firstInitialised) {
  309. pageX = this.loopX ? startPageXIndex + 1 : startPageXIndex;
  310. pageY = this.loopY ? startPageYIndex + 1 : startPageYIndex;
  311. }
  312. else {
  313. pageX = showFirstPage ? firstPageX : this.currentPage.pageX;
  314. pageY = showFirstPage ? firstPageY : this.currentPage.pageY;
  315. }
  316. var _b = this.pagesMatrix.getPageStats(pageX, pageY), x = _b.x, y = _b.y;
  317. return {
  318. pageX: pageX,
  319. pageY: pageY,
  320. x: x,
  321. y: y,
  322. };
  323. };
  324. SlidePages.prototype.getExposedPage = function (page) {
  325. var exposedPage = extend({}, page);
  326. // only pageX or pageY need fix
  327. if (this.loopX) {
  328. exposedPage.pageX = this.fixedPage(exposedPage.pageX, this.pagesMatrix.pageLengthOfX - 2);
  329. }
  330. if (this.loopY) {
  331. exposedPage.pageY = this.fixedPage(exposedPage.pageY, this.pagesMatrix.pageLengthOfY - 2);
  332. }
  333. return exposedPage;
  334. };
  335. SlidePages.prototype.getExposedPageByPageIndex = function (pageIndexX, pageIndexY) {
  336. var page = {
  337. pageX: pageIndexX,
  338. pageY: pageIndexY,
  339. };
  340. if (this.loopX) {
  341. page.pageX = pageIndexX + 1;
  342. }
  343. if (this.loopY) {
  344. page.pageY = pageIndexY + 1;
  345. }
  346. var _a = this.pagesMatrix.getPageStats(page.pageX, page.pageY), x = _a.x, y = _a.y;
  347. return {
  348. x: x,
  349. y: y,
  350. pageX: pageIndexX,
  351. pageY: pageIndexY,
  352. };
  353. };
  354. SlidePages.prototype.getWillChangedPage = function (page) {
  355. page = extend({}, page);
  356. // Page need fix
  357. if (this.loopX) {
  358. page.pageX = this.fixedPage(page.pageX, this.pagesMatrix.pageLengthOfX - 2);
  359. page.x = this.pagesMatrix.getPageStats(page.pageX + 1, 0).x;
  360. }
  361. if (this.loopY) {
  362. page.pageY = this.fixedPage(page.pageY, this.pagesMatrix.pageLengthOfY - 2);
  363. page.y = this.pagesMatrix.getPageStats(0, page.pageY + 1).y;
  364. }
  365. return page;
  366. };
  367. SlidePages.prototype.fixedPage = function (page, realPageLen) {
  368. var pageIndex = [];
  369. for (var i = 0; i < realPageLen; i++) {
  370. pageIndex.push(i);
  371. }
  372. pageIndex.unshift(realPageLen - 1);
  373. pageIndex.push(0);
  374. return pageIndex[page];
  375. };
  376. SlidePages.prototype.getPageStats = function () {
  377. return this.pagesMatrix.getPageStats(this.currentPage.pageX, this.currentPage.pageY);
  378. };
  379. SlidePages.prototype.getValidPageIndex = function (x, y) {
  380. var lastX = this.pagesMatrix.pageLengthOfX - 1;
  381. var lastY = this.pagesMatrix.pageLengthOfY - 1;
  382. var firstX = 0;
  383. var firstY = 0;
  384. if (this.loopX) {
  385. x += 1;
  386. firstX = firstX + 1;
  387. lastX = lastX - 1;
  388. }
  389. if (this.loopY) {
  390. y += 1;
  391. firstY = firstY + 1;
  392. lastY = lastY - 1;
  393. }
  394. x = between(x, firstX, lastX);
  395. y = between(y, firstY, lastY);
  396. return {
  397. pageX: x,
  398. pageY: y,
  399. };
  400. };
  401. SlidePages.prototype.nextPageIndex = function () {
  402. return this.getPageIndexByDirection("positive" /* Positive */);
  403. };
  404. SlidePages.prototype.prevPageIndex = function () {
  405. return this.getPageIndexByDirection("negative" /* Negative */);
  406. };
  407. SlidePages.prototype.getNearestPage = function (x, y) {
  408. var pageIndex = this.pagesMatrix.getNearestPageIndex(x, y);
  409. var pageX = pageIndex.pageX, pageY = pageIndex.pageY;
  410. var newX = this.pagesMatrix.getPageStats(pageX, 0).x;
  411. var newY = this.pagesMatrix.getPageStats(0, pageY).y;
  412. return {
  413. x: newX,
  414. y: newY,
  415. pageX: pageX,
  416. pageY: pageY,
  417. };
  418. };
  419. SlidePages.prototype.getPageByDirection = function (page, directionX, directionY) {
  420. var pageX = page.pageX, pageY = page.pageY;
  421. if (pageX === this.currentPage.pageX) {
  422. pageX = between(pageX + directionX, 0, this.pagesMatrix.pageLengthOfX - 1);
  423. }
  424. if (pageY === this.currentPage.pageY) {
  425. pageY = between(pageY + directionY, 0, this.pagesMatrix.pageLengthOfY - 1);
  426. }
  427. var x = this.pagesMatrix.getPageStats(pageX, 0).x;
  428. var y = this.pagesMatrix.getPageStats(0, pageY).y;
  429. return {
  430. x: x,
  431. y: y,
  432. pageX: pageX,
  433. pageY: pageY,
  434. };
  435. };
  436. SlidePages.prototype.resetLoopPage = function () {
  437. if (this.loopX) {
  438. if (this.currentPage.pageX === 0) {
  439. return {
  440. pageX: this.pagesMatrix.pageLengthOfX - 2,
  441. pageY: this.currentPage.pageY,
  442. };
  443. }
  444. if (this.currentPage.pageX === this.pagesMatrix.pageLengthOfX - 1) {
  445. return {
  446. pageX: 1,
  447. pageY: this.currentPage.pageY,
  448. };
  449. }
  450. }
  451. if (this.loopY) {
  452. if (this.currentPage.pageY === 0) {
  453. return {
  454. pageX: this.currentPage.pageX,
  455. pageY: this.pagesMatrix.pageLengthOfY - 2,
  456. };
  457. }
  458. if (this.currentPage.pageY === this.pagesMatrix.pageLengthOfY - 1) {
  459. return {
  460. pageX: this.currentPage.pageX,
  461. pageY: 1,
  462. };
  463. }
  464. }
  465. };
  466. SlidePages.prototype.getPageIndexByDirection = function (direction) {
  467. var x = this.currentPage.pageX;
  468. var y = this.currentPage.pageY;
  469. if (this.slideX) {
  470. x = direction === "negative" /* Negative */ ? x - 1 : x + 1;
  471. }
  472. if (this.slideY) {
  473. y = direction === "negative" /* Negative */ ? y - 1 : y + 1;
  474. }
  475. return {
  476. pageX: x,
  477. pageY: y,
  478. };
  479. };
  480. SlidePages.prototype.checkSlideLoop = function () {
  481. this.wannaLoop = this.slideOptions.loop;
  482. if (this.pagesMatrix.pageLengthOfX > 1) {
  483. this.slideX = true;
  484. }
  485. else {
  486. this.slideX = false;
  487. }
  488. if (this.pagesMatrix.pages[0] && this.pagesMatrix.pageLengthOfY > 1) {
  489. this.slideY = true;
  490. }
  491. else {
  492. this.slideY = false;
  493. }
  494. this.loopX = this.wannaLoop && this.slideX;
  495. this.loopY = this.wannaLoop && this.slideY;
  496. if (this.slideX && this.slideY) {
  497. warn('slide does not support two direction at the same time.');
  498. }
  499. };
  500. return SlidePages;
  501. }());
  502. var sourcePrefix = 'plugins.slide';
  503. var propertiesMap = [
  504. {
  505. key: 'next',
  506. name: 'next',
  507. },
  508. {
  509. key: 'prev',
  510. name: 'prev',
  511. },
  512. {
  513. key: 'goToPage',
  514. name: 'goToPage',
  515. },
  516. {
  517. key: 'getCurrentPage',
  518. name: 'getCurrentPage',
  519. },
  520. {
  521. key: 'startPlay',
  522. name: 'startPlay',
  523. },
  524. {
  525. key: 'pausePlay',
  526. name: 'pausePlay',
  527. },
  528. ];
  529. var propertiesConfig = propertiesMap.map(function (item) {
  530. return {
  531. key: item.key,
  532. sourceKey: sourcePrefix + "." + item.name,
  533. };
  534. });
  535. var samePage = function (p1, p2) {
  536. return p1.pageX === p2.pageX && p1.pageY === p2.pageY;
  537. };
  538. var Slide = /** @class */ (function () {
  539. function Slide(scroll) {
  540. this.scroll = scroll;
  541. this.cachedClonedPageDOM = [];
  542. this.resetLooping = false;
  543. this.autoplayTimer = 0;
  544. if (!this.satisfyInitialization()) {
  545. return;
  546. }
  547. this.init();
  548. }
  549. Slide.prototype.satisfyInitialization = function () {
  550. if (this.scroll.scroller.content.children.length <= 0) {
  551. warn("slide need at least one slide page to be initialised." +
  552. "please check your DOM layout.");
  553. return false;
  554. }
  555. return true;
  556. };
  557. Slide.prototype.init = function () {
  558. this.willChangeToPage = extend({}, BASE_PAGE);
  559. this.handleBScroll();
  560. this.handleOptions();
  561. this.handleHooks();
  562. this.createPages();
  563. };
  564. Slide.prototype.createPages = function () {
  565. this.pages = new SlidePages(this.scroll, this.options);
  566. };
  567. Slide.prototype.handleBScroll = function () {
  568. this.scroll.registerType(['slideWillChange', 'slidePageChanged']);
  569. this.scroll.proxy(propertiesConfig);
  570. };
  571. Slide.prototype.handleOptions = function () {
  572. var userOptions = (this.scroll.options.slide === true
  573. ? {}
  574. : this.scroll.options.slide);
  575. var defaultOptions = {
  576. loop: true,
  577. threshold: 0.1,
  578. speed: 400,
  579. easing: ease.bounce,
  580. listenFlick: true,
  581. autoplay: true,
  582. interval: 3000,
  583. startPageXIndex: 0,
  584. startPageYIndex: 0,
  585. };
  586. this.options = extend(defaultOptions, userOptions);
  587. };
  588. Slide.prototype.handleLoop = function (prevSlideContent) {
  589. var loop = this.options.loop;
  590. var slideContent = this.scroll.scroller.content;
  591. var currentSlidePagesLength = slideContent.children.length;
  592. // only should respect loop scene
  593. if (loop) {
  594. if (slideContent !== prevSlideContent) {
  595. this.resetLoopChangedStatus();
  596. this.removeClonedSlidePage(prevSlideContent);
  597. currentSlidePagesLength > 1 &&
  598. this.cloneFirstAndLastSlidePage(slideContent);
  599. }
  600. else {
  601. // many pages reduce to one page
  602. if (currentSlidePagesLength === 3 && this.initialised) {
  603. this.removeClonedSlidePage(slideContent);
  604. this.moreToOnePageInLoop = true;
  605. this.oneToMorePagesInLoop = false;
  606. }
  607. else if (currentSlidePagesLength > 1) {
  608. // one page increases to many page
  609. if (this.initialised && this.cachedClonedPageDOM.length === 0) {
  610. this.oneToMorePagesInLoop = true;
  611. this.moreToOnePageInLoop = false;
  612. }
  613. else {
  614. this.removeClonedSlidePage(slideContent);
  615. this.resetLoopChangedStatus();
  616. }
  617. this.cloneFirstAndLastSlidePage(slideContent);
  618. }
  619. else {
  620. this.resetLoopChangedStatus();
  621. }
  622. }
  623. }
  624. };
  625. Slide.prototype.resetLoopChangedStatus = function () {
  626. this.moreToOnePageInLoop = false;
  627. this.oneToMorePagesInLoop = false;
  628. };
  629. Slide.prototype.handleHooks = function () {
  630. var _this = this;
  631. var scrollHooks = this.scroll.hooks;
  632. var scrollerHooks = this.scroll.scroller.hooks;
  633. var listenFlick = this.options.listenFlick;
  634. this.prevContent = this.scroll.scroller.content;
  635. this.hooksFn = [];
  636. // scroll
  637. this.registerHooks(this.scroll, this.scroll.eventTypes.beforeScrollStart, this.pausePlay);
  638. this.registerHooks(this.scroll, this.scroll.eventTypes.scrollEnd, this.modifyCurrentPage);
  639. this.registerHooks(this.scroll, this.scroll.eventTypes.scrollEnd, this.startPlay);
  640. // for mousewheel event
  641. if (this.scroll.eventTypes.mousewheelMove) {
  642. this.registerHooks(this.scroll, this.scroll.eventTypes.mousewheelMove, function () {
  643. // prevent default action of mousewheelMove
  644. return true;
  645. });
  646. this.registerHooks(this.scroll, this.scroll.eventTypes.mousewheelEnd, function (delta) {
  647. if (delta.directionX === 1 /* Positive */ ||
  648. delta.directionY === 1 /* Positive */) {
  649. _this.next();
  650. }
  651. if (delta.directionX === -1 /* Negative */ ||
  652. delta.directionY === -1 /* Negative */) {
  653. _this.prev();
  654. }
  655. });
  656. }
  657. // scrollHooks
  658. this.registerHooks(scrollHooks, scrollHooks.eventTypes.refresh, this.refreshHandler);
  659. this.registerHooks(scrollHooks, scrollHooks.eventTypes.destroy, this.destroy);
  660. // scroller
  661. this.registerHooks(scrollerHooks, scrollerHooks.eventTypes.beforeRefresh, function () {
  662. _this.handleLoop(_this.prevContent);
  663. _this.setSlideInlineStyle();
  664. });
  665. this.registerHooks(scrollerHooks, scrollerHooks.eventTypes.momentum, this.modifyScrollMetaHandler);
  666. this.registerHooks(scrollerHooks, scrollerHooks.eventTypes.scroll, this.scrollHandler);
  667. // a click operation will clearTimer, so restart a new one
  668. this.registerHooks(scrollerHooks, scrollerHooks.eventTypes.checkClick, this.startPlay);
  669. if (listenFlick) {
  670. this.registerHooks(scrollerHooks, scrollerHooks.eventTypes.flick, this.flickHandler);
  671. }
  672. };
  673. Slide.prototype.startPlay = function () {
  674. var _this = this;
  675. var _a = this.options, interval = _a.interval, autoplay = _a.autoplay;
  676. if (autoplay) {
  677. clearTimeout(this.autoplayTimer);
  678. this.autoplayTimer = window.setTimeout(function () {
  679. _this.next();
  680. }, interval);
  681. }
  682. };
  683. Slide.prototype.pausePlay = function () {
  684. if (this.options.autoplay) {
  685. clearTimeout(this.autoplayTimer);
  686. }
  687. };
  688. Slide.prototype.setSlideInlineStyle = function () {
  689. var styleConfigurations = [
  690. {
  691. direction: 'scrollX',
  692. sizeType: 'offsetWidth',
  693. styleType: 'width',
  694. },
  695. {
  696. direction: 'scrollY',
  697. sizeType: 'offsetHeight',
  698. styleType: 'height',
  699. },
  700. ];
  701. var _a = this.scroll.scroller, slideContent = _a.content, slideWrapper = _a.wrapper;
  702. var scrollOptions = this.scroll.options;
  703. styleConfigurations.forEach(function (_a) {
  704. var direction = _a.direction, sizeType = _a.sizeType, styleType = _a.styleType;
  705. // wanna scroll in this direction
  706. if (scrollOptions[direction]) {
  707. var size = slideWrapper[sizeType];
  708. var children = slideContent.children;
  709. var length_1 = children.length;
  710. for (var i = 0; i < length_1; i++) {
  711. var slidePageDOM = children[i];
  712. slidePageDOM.style[styleType] = size + 'px';
  713. }
  714. slideContent.style[styleType] = size * length_1 + 'px';
  715. }
  716. });
  717. };
  718. Slide.prototype.next = function (time, easing) {
  719. var _a = this.pages.nextPageIndex(), pageX = _a.pageX, pageY = _a.pageY;
  720. this.goTo(pageX, pageY, time, easing);
  721. };
  722. Slide.prototype.prev = function (time, easing) {
  723. var _a = this.pages.prevPageIndex(), pageX = _a.pageX, pageY = _a.pageY;
  724. this.goTo(pageX, pageY, time, easing);
  725. };
  726. Slide.prototype.goToPage = function (pageX, pageY, time, easing) {
  727. var pageIndex = this.pages.getValidPageIndex(pageX, pageY);
  728. this.goTo(pageIndex.pageX, pageIndex.pageY, time, easing);
  729. };
  730. Slide.prototype.getCurrentPage = function () {
  731. return this.exposedPage || this.pages.getInitialPage(false, true);
  732. };
  733. Slide.prototype.setCurrentPage = function (page) {
  734. this.pages.setCurrentPage(page);
  735. this.exposedPage = this.pages.getExposedPage(page);
  736. };
  737. Slide.prototype.nearestPage = function (x, y) {
  738. var _a = this.scroll.scroller, scrollBehaviorX = _a.scrollBehaviorX, scrollBehaviorY = _a.scrollBehaviorY;
  739. var maxScrollPosX = scrollBehaviorX.maxScrollPos, minScrollPosX = scrollBehaviorX.minScrollPos;
  740. var maxScrollPosY = scrollBehaviorY.maxScrollPos, minScrollPosY = scrollBehaviorY.minScrollPos;
  741. return this.pages.getNearestPage(between(x, maxScrollPosX, minScrollPosX), between(y, maxScrollPosY, minScrollPosY));
  742. };
  743. Slide.prototype.satisfyThreshold = function (x, y) {
  744. var _a = this.scroll.scroller, scrollBehaviorX = _a.scrollBehaviorX, scrollBehaviorY = _a.scrollBehaviorY;
  745. var satisfied = true;
  746. if (Math.abs(x - scrollBehaviorX.absStartPos) <= this.thresholdX &&
  747. Math.abs(y - scrollBehaviorY.absStartPos) <= this.thresholdY) {
  748. satisfied = false;
  749. }
  750. return satisfied;
  751. };
  752. Slide.prototype.refreshHandler = function (content) {
  753. var _this = this;
  754. if (!this.satisfyInitialization()) {
  755. return;
  756. }
  757. this.pages.refresh();
  758. this.computeThreshold();
  759. var contentChanged = (this.contentChanged = this.prevContent !== content);
  760. if (contentChanged) {
  761. this.prevContent = content;
  762. }
  763. var initPage = this.pages.getInitialPage(this.oneToMorePagesInLoop || this.moreToOnePageInLoop, contentChanged || !this.initialised);
  764. if (this.initialised) {
  765. this.goTo(initPage.pageX, initPage.pageY, 0);
  766. }
  767. else {
  768. this.registerHooks(this.scroll.hooks, this.scroll.hooks.eventTypes.beforeInitialScrollTo, function (position) {
  769. _this.initialised = true;
  770. position.x = initPage.x;
  771. position.y = initPage.y;
  772. });
  773. }
  774. this.startPlay();
  775. };
  776. Slide.prototype.computeThreshold = function () {
  777. var threshold = this.options.threshold;
  778. // Integer
  779. if (threshold % 1 === 0) {
  780. this.thresholdX = threshold;
  781. this.thresholdY = threshold;
  782. }
  783. else {
  784. // decimal
  785. var _a = this.pages.getPageStats(), width = _a.width, height = _a.height;
  786. this.thresholdX = Math.round(width * threshold);
  787. this.thresholdY = Math.round(height * threshold);
  788. }
  789. };
  790. Slide.prototype.cloneFirstAndLastSlidePage = function (slideContent) {
  791. var children = slideContent.children;
  792. var preprendDOM = children[children.length - 1].cloneNode(true);
  793. var appendDOM = children[0].cloneNode(true);
  794. prepend(preprendDOM, slideContent);
  795. slideContent.appendChild(appendDOM);
  796. this.cachedClonedPageDOM = [preprendDOM, appendDOM];
  797. };
  798. Slide.prototype.removeClonedSlidePage = function (slideContent) {
  799. // maybe slideContent has removed from DOM Tree
  800. var slidePages = (slideContent && slideContent.children) || [];
  801. if (slidePages.length) {
  802. this.cachedClonedPageDOM.forEach(function (el) {
  803. removeChild(slideContent, el);
  804. });
  805. }
  806. this.cachedClonedPageDOM = [];
  807. };
  808. Slide.prototype.modifyCurrentPage = function (point) {
  809. var _a = this.getCurrentPage(), prevExposedPageX = _a.pageX, prevExposedPageY = _a.pageY;
  810. var newPage = this.nearestPage(point.x, point.y);
  811. this.setCurrentPage(newPage);
  812. /* istanbul ignore if */
  813. if (this.contentChanged) {
  814. this.contentChanged = false;
  815. return true;
  816. }
  817. var _b = this.getCurrentPage(), currentExposedPageX = _b.pageX, currentExposedPageY = _b.pageY;
  818. this.pageWillChangeTo(newPage);
  819. // loop is true, and one page becomes many pages when call bs.refresh
  820. if (this.oneToMorePagesInLoop) {
  821. this.oneToMorePagesInLoop = false;
  822. return true;
  823. }
  824. // loop is true, and many page becomes one page when call bs.refresh
  825. // if prevPage > 0, dispatch slidePageChanged and scrollEnd events
  826. /* istanbul ignore if */
  827. if (this.moreToOnePageInLoop &&
  828. prevExposedPageX === 0 &&
  829. prevExposedPageY === 0) {
  830. this.moreToOnePageInLoop = false;
  831. return true;
  832. }
  833. if (prevExposedPageX !== currentExposedPageX ||
  834. prevExposedPageY !== currentExposedPageY) {
  835. // only trust pageX & pageY when loop is true
  836. var page = this.pages.getExposedPageByPageIndex(currentExposedPageX, currentExposedPageY);
  837. this.scroll.trigger(this.scroll.eventTypes.slidePageChanged, page);
  838. }
  839. // triggered by resetLoop
  840. if (this.resetLooping) {
  841. this.resetLooping = false;
  842. return;
  843. }
  844. var changePage = this.pages.resetLoopPage();
  845. if (changePage) {
  846. this.resetLooping = true;
  847. this.goTo(changePage.pageX, changePage.pageY, 0);
  848. // stop user's scrollEnd
  849. // since it is a seamless scroll
  850. return true;
  851. }
  852. };
  853. Slide.prototype.goTo = function (pageX, pageY, time, easing) {
  854. var newPage = this.pages.getInternalPage(pageX, pageY);
  855. var scrollEasing = easing || this.options.easing || ease.bounce;
  856. var x = newPage.x, y = newPage.y;
  857. var deltaX = x - this.scroll.scroller.scrollBehaviorX.currentPos;
  858. var deltaY = y - this.scroll.scroller.scrollBehaviorY.currentPos;
  859. /* istanbul ignore if */
  860. if (!deltaX && !deltaY) {
  861. this.scroll.scroller.togglePointerEvents(true);
  862. return;
  863. }
  864. time = time === undefined ? this.getEaseTime(deltaX, deltaY) : time;
  865. this.scroll.scroller.scrollTo(x, y, time, scrollEasing);
  866. };
  867. Slide.prototype.flickHandler = function () {
  868. var _a = this.scroll.scroller, scrollBehaviorX = _a.scrollBehaviorX, scrollBehaviorY = _a.scrollBehaviorY;
  869. var currentPosX = scrollBehaviorX.currentPos, startPosX = scrollBehaviorX.startPos, directionX = scrollBehaviorX.direction;
  870. var currentPosY = scrollBehaviorY.currentPos, startPosY = scrollBehaviorY.startPos, directionY = scrollBehaviorY.direction;
  871. var _b = this.pages.currentPage, pageX = _b.pageX, pageY = _b.pageY;
  872. var time = this.getEaseTime(currentPosX - startPosX, currentPosY - startPosY);
  873. this.goTo(pageX + directionX, pageY + directionY, time);
  874. };
  875. Slide.prototype.getEaseTime = function (deltaX, deltaY) {
  876. return (this.options.speed ||
  877. Math.max(Math.max(Math.min(Math.abs(deltaX), 1000), Math.min(Math.abs(deltaY), 1000)), 300));
  878. };
  879. Slide.prototype.modifyScrollMetaHandler = function (scrollMeta) {
  880. var _a = this.scroll.scroller, scrollBehaviorX = _a.scrollBehaviorX, scrollBehaviorY = _a.scrollBehaviorY, animater = _a.animater;
  881. var newX = scrollMeta.newX;
  882. var newY = scrollMeta.newY;
  883. var newPage = this.satisfyThreshold(newX, newY) || animater.forceStopped
  884. ? this.pages.getPageByDirection(this.nearestPage(newX, newY), scrollBehaviorX.direction, scrollBehaviorY.direction)
  885. : this.pages.currentPage;
  886. scrollMeta.time = this.getEaseTime(scrollMeta.newX - newPage.x, scrollMeta.newY - newPage.y);
  887. scrollMeta.newX = newPage.x;
  888. scrollMeta.newY = newPage.y;
  889. scrollMeta.easing = this.options.easing || ease.bounce;
  890. };
  891. Slide.prototype.scrollHandler = function (_a) {
  892. var x = _a.x, y = _a.y;
  893. if (this.satisfyThreshold(x, y)) {
  894. var newPage = this.nearestPage(x, y);
  895. this.pageWillChangeTo(newPage);
  896. }
  897. };
  898. Slide.prototype.pageWillChangeTo = function (newPage) {
  899. var changeToPage = this.pages.getWillChangedPage(newPage);
  900. if (!samePage(this.willChangeToPage, changeToPage)) {
  901. this.willChangeToPage = changeToPage;
  902. this.scroll.trigger(this.scroll.eventTypes.slideWillChange, this.willChangeToPage);
  903. }
  904. };
  905. Slide.prototype.registerHooks = function (hooks, name, handler) {
  906. hooks.on(name, handler, this);
  907. this.hooksFn.push([hooks, name, handler]);
  908. };
  909. Slide.prototype.destroy = function () {
  910. var slideContent = this.scroll.scroller.content;
  911. var _a = this.options, loop = _a.loop, autoplay = _a.autoplay;
  912. if (loop) {
  913. this.removeClonedSlidePage(slideContent);
  914. }
  915. if (autoplay) {
  916. clearTimeout(this.autoplayTimer);
  917. }
  918. this.hooksFn.forEach(function (item) {
  919. var hooks = item[0];
  920. var hooksName = item[1];
  921. var handlerFn = item[2];
  922. if (hooks.eventTypes[hooksName]) {
  923. hooks.off(hooksName, handlerFn);
  924. }
  925. });
  926. this.hooksFn.length = 0;
  927. };
  928. Slide.pluginName = 'slide';
  929. return Slide;
  930. }());
  931. export default Slide;