scroll-bar.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. /*!
  2. * better-scroll / scroll-bar
  3. * (c) 2016-2021 ustbhuangyi
  4. * Released under the MIT License.
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  8. typeof define === 'function' && define.amd ? define(factory) :
  9. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ScrollBar = factory());
  10. }(this, (function () { 'use strict';
  11. /*! *****************************************************************************
  12. Copyright (c) Microsoft Corporation.
  13. Permission to use, copy, modify, and/or distribute this software for any
  14. purpose with or without fee is hereby granted.
  15. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  16. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  17. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  18. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  19. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  20. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  21. PERFORMANCE OF THIS SOFTWARE.
  22. ***************************************************************************** */
  23. var __assign = function() {
  24. __assign = Object.assign || function __assign(t) {
  25. for (var s, i = 1, n = arguments.length; i < n; i++) {
  26. s = arguments[i];
  27. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
  28. }
  29. return t;
  30. };
  31. return __assign.apply(this, arguments);
  32. };
  33. function __spreadArrays() {
  34. for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
  35. for (var r = Array(s), k = 0, i = 0; i < il; i++)
  36. for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
  37. r[k] = a[j];
  38. return r;
  39. }
  40. function warn(msg) {
  41. console.error("[BScroll warn]: " + msg);
  42. }
  43. // ssr support
  44. var inBrowser = typeof window !== 'undefined';
  45. var ua = inBrowser && navigator.userAgent.toLowerCase();
  46. !!(ua && /wechatdevtools/.test(ua));
  47. ua && ua.indexOf('android') > 0;
  48. /* istanbul ignore next */
  49. ((function () {
  50. if (typeof ua === 'string') {
  51. var regex = /os (\d\d?_\d(_\d)?)/;
  52. var matches = regex.exec(ua);
  53. if (!matches)
  54. return false;
  55. var parts = matches[1].split('_').map(function (item) {
  56. return parseInt(item, 10);
  57. });
  58. // ios version >= 13.4 issue 982
  59. return !!(parts[0] === 13 && parts[1] >= 4);
  60. }
  61. return false;
  62. }))();
  63. /* istanbul ignore next */
  64. var supportsPassive = false;
  65. /* istanbul ignore next */
  66. if (inBrowser) {
  67. var EventName = 'test-passive';
  68. try {
  69. var opts = {};
  70. Object.defineProperty(opts, 'passive', {
  71. get: function () {
  72. supportsPassive = true;
  73. },
  74. }); // https://github.com/facebook/flow/issues/285
  75. window.addEventListener(EventName, function () { }, opts);
  76. }
  77. catch (e) { }
  78. }
  79. function getNow() {
  80. return window.performance &&
  81. window.performance.now &&
  82. window.performance.timing
  83. ? window.performance.now() + window.performance.timing.navigationStart
  84. : +new Date();
  85. }
  86. var extend = function (target, source) {
  87. for (var key in source) {
  88. target[key] = source[key];
  89. }
  90. return target;
  91. };
  92. function between(x, min, max) {
  93. if (x < min) {
  94. return min;
  95. }
  96. if (x > max) {
  97. return max;
  98. }
  99. return x;
  100. }
  101. var elementStyle = (inBrowser &&
  102. document.createElement('div').style);
  103. var vendor = (function () {
  104. /* istanbul ignore if */
  105. if (!inBrowser) {
  106. return false;
  107. }
  108. var transformNames = [
  109. {
  110. key: 'standard',
  111. value: 'transform',
  112. },
  113. {
  114. key: 'webkit',
  115. value: 'webkitTransform',
  116. },
  117. {
  118. key: 'Moz',
  119. value: 'MozTransform',
  120. },
  121. {
  122. key: 'O',
  123. value: 'OTransform',
  124. },
  125. {
  126. key: 'ms',
  127. value: 'msTransform',
  128. },
  129. ];
  130. for (var _i = 0, transformNames_1 = transformNames; _i < transformNames_1.length; _i++) {
  131. var obj = transformNames_1[_i];
  132. if (elementStyle[obj.value] !== undefined) {
  133. return obj.key;
  134. }
  135. }
  136. /* istanbul ignore next */
  137. return false;
  138. })();
  139. /* istanbul ignore next */
  140. function prefixStyle(style) {
  141. if (vendor === false) {
  142. return style;
  143. }
  144. if (vendor === 'standard') {
  145. if (style === 'transitionEnd') {
  146. return 'transitionend';
  147. }
  148. return style;
  149. }
  150. return vendor + style.charAt(0).toUpperCase() + style.substr(1);
  151. }
  152. function addEvent(el, type, fn, capture) {
  153. var useCapture = supportsPassive
  154. ? {
  155. passive: false,
  156. capture: !!capture,
  157. }
  158. : !!capture;
  159. el.addEventListener(type, fn, useCapture);
  160. }
  161. function removeEvent(el, type, fn, capture) {
  162. el.removeEventListener(type, fn, {
  163. capture: !!capture,
  164. });
  165. }
  166. vendor && vendor !== 'standard' ? '-' + vendor.toLowerCase() + '-' : '';
  167. var transform = prefixStyle('transform');
  168. var transition = prefixStyle('transition');
  169. inBrowser && prefixStyle('perspective') in elementStyle;
  170. var style = {
  171. transform: transform,
  172. transition: transition,
  173. transitionTimingFunction: prefixStyle('transitionTimingFunction'),
  174. transitionDuration: prefixStyle('transitionDuration'),
  175. transitionDelay: prefixStyle('transitionDelay'),
  176. transformOrigin: prefixStyle('transformOrigin'),
  177. transitionEnd: prefixStyle('transitionEnd'),
  178. transitionProperty: prefixStyle('transitionProperty'),
  179. };
  180. var EventEmitter = /** @class */ (function () {
  181. function EventEmitter(names) {
  182. this.events = {};
  183. this.eventTypes = {};
  184. this.registerType(names);
  185. }
  186. EventEmitter.prototype.on = function (type, fn, context) {
  187. if (context === void 0) { context = this; }
  188. this.hasType(type);
  189. if (!this.events[type]) {
  190. this.events[type] = [];
  191. }
  192. this.events[type].push([fn, context]);
  193. return this;
  194. };
  195. EventEmitter.prototype.once = function (type, fn, context) {
  196. var _this = this;
  197. if (context === void 0) { context = this; }
  198. this.hasType(type);
  199. var magic = function () {
  200. var args = [];
  201. for (var _i = 0; _i < arguments.length; _i++) {
  202. args[_i] = arguments[_i];
  203. }
  204. _this.off(type, magic);
  205. var ret = fn.apply(context, args);
  206. if (ret === true) {
  207. return ret;
  208. }
  209. };
  210. magic.fn = fn;
  211. this.on(type, magic);
  212. return this;
  213. };
  214. EventEmitter.prototype.off = function (type, fn) {
  215. if (!type && !fn) {
  216. this.events = {};
  217. return this;
  218. }
  219. if (type) {
  220. this.hasType(type);
  221. if (!fn) {
  222. this.events[type] = [];
  223. return this;
  224. }
  225. var events = this.events[type];
  226. if (!events) {
  227. return this;
  228. }
  229. var count = events.length;
  230. while (count--) {
  231. if (events[count][0] === fn ||
  232. (events[count][0] && events[count][0].fn === fn)) {
  233. events.splice(count, 1);
  234. }
  235. }
  236. return this;
  237. }
  238. };
  239. EventEmitter.prototype.trigger = function (type) {
  240. var args = [];
  241. for (var _i = 1; _i < arguments.length; _i++) {
  242. args[_i - 1] = arguments[_i];
  243. }
  244. this.hasType(type);
  245. var events = this.events[type];
  246. if (!events) {
  247. return;
  248. }
  249. var len = events.length;
  250. var eventsCopy = __spreadArrays(events);
  251. var ret;
  252. for (var i = 0; i < len; i++) {
  253. var event_1 = eventsCopy[i];
  254. var fn = event_1[0], context = event_1[1];
  255. if (fn) {
  256. ret = fn.apply(context, args);
  257. if (ret === true) {
  258. return ret;
  259. }
  260. }
  261. }
  262. };
  263. EventEmitter.prototype.registerType = function (names) {
  264. var _this = this;
  265. names.forEach(function (type) {
  266. _this.eventTypes[type] = type;
  267. });
  268. };
  269. EventEmitter.prototype.destroy = function () {
  270. this.events = {};
  271. this.eventTypes = {};
  272. };
  273. EventEmitter.prototype.hasType = function (type) {
  274. var types = this.eventTypes;
  275. var isType = types[type] === type;
  276. if (!isType) {
  277. warn("EventEmitter has used unknown event type: \"" + type + "\", should be oneof [" +
  278. ("" + Object.keys(types).map(function (_) { return JSON.stringify(_); })) +
  279. "]");
  280. }
  281. };
  282. return EventEmitter;
  283. }());
  284. var EventRegister = /** @class */ (function () {
  285. function EventRegister(wrapper, events) {
  286. this.wrapper = wrapper;
  287. this.events = events;
  288. this.addDOMEvents();
  289. }
  290. EventRegister.prototype.destroy = function () {
  291. this.removeDOMEvents();
  292. this.events = [];
  293. };
  294. EventRegister.prototype.addDOMEvents = function () {
  295. this.handleDOMEvents(addEvent);
  296. };
  297. EventRegister.prototype.removeDOMEvents = function () {
  298. this.handleDOMEvents(removeEvent);
  299. };
  300. EventRegister.prototype.handleDOMEvents = function (eventOperation) {
  301. var _this = this;
  302. var wrapper = this.wrapper;
  303. this.events.forEach(function (event) {
  304. eventOperation(wrapper, event.name, _this, !!event.capture);
  305. });
  306. };
  307. EventRegister.prototype.handleEvent = function (e) {
  308. var eventType = e.type;
  309. this.events.some(function (event) {
  310. if (event.name === eventType) {
  311. event.handler(e);
  312. return true;
  313. }
  314. return false;
  315. });
  316. };
  317. return EventRegister;
  318. }());
  319. var EventHandler = /** @class */ (function () {
  320. function EventHandler(indicator, options) {
  321. this.indicator = indicator;
  322. this.options = options;
  323. this.hooks = new EventEmitter(['touchStart', 'touchMove', 'touchEnd']);
  324. this.registerEvents();
  325. }
  326. EventHandler.prototype.registerEvents = function () {
  327. var _a = this.options, disableMouse = _a.disableMouse, disableTouch = _a.disableTouch;
  328. var startEvents = [];
  329. var moveEvents = [];
  330. var endEvents = [];
  331. if (!disableMouse) {
  332. startEvents.push({
  333. name: 'mousedown',
  334. handler: this.start.bind(this),
  335. });
  336. moveEvents.push({
  337. name: 'mousemove',
  338. handler: this.move.bind(this),
  339. });
  340. endEvents.push({
  341. name: 'mouseup',
  342. handler: this.end.bind(this),
  343. });
  344. }
  345. if (!disableTouch) {
  346. startEvents.push({
  347. name: 'touchstart',
  348. handler: this.start.bind(this),
  349. });
  350. moveEvents.push({
  351. name: 'touchmove',
  352. handler: this.move.bind(this),
  353. });
  354. endEvents.push({
  355. name: 'touchend',
  356. handler: this.end.bind(this),
  357. }, {
  358. name: 'touchcancel',
  359. handler: this.end.bind(this),
  360. });
  361. }
  362. this.startEventRegister = new EventRegister(this.indicator.indicatorEl, startEvents);
  363. this.moveEventRegister = new EventRegister(window, moveEvents);
  364. this.endEventRegister = new EventRegister(window, endEvents);
  365. };
  366. EventHandler.prototype.BScrollIsDisabled = function () {
  367. return !this.indicator.scroll.enabled;
  368. };
  369. EventHandler.prototype.start = function (e) {
  370. if (this.BScrollIsDisabled()) {
  371. return;
  372. }
  373. var point = (e.touches ? e.touches[0] : e);
  374. e.preventDefault();
  375. e.stopPropagation();
  376. this.initiated = true;
  377. this.lastPoint = point[this.indicator.keysMap.point];
  378. this.hooks.trigger(this.hooks.eventTypes.touchStart);
  379. };
  380. EventHandler.prototype.move = function (e) {
  381. if (!this.initiated) {
  382. return;
  383. }
  384. var point = (e.touches ? e.touches[0] : e);
  385. var pointPos = point[this.indicator.keysMap.point];
  386. e.preventDefault();
  387. e.stopPropagation();
  388. var delta = pointPos - this.lastPoint;
  389. this.lastPoint = pointPos;
  390. this.hooks.trigger(this.hooks.eventTypes.touchMove, delta);
  391. };
  392. EventHandler.prototype.end = function (e) {
  393. if (!this.initiated) {
  394. return;
  395. }
  396. this.initiated = false;
  397. e.preventDefault();
  398. e.stopPropagation();
  399. this.hooks.trigger(this.hooks.eventTypes.touchEnd);
  400. };
  401. EventHandler.prototype.destroy = function () {
  402. this.startEventRegister.destroy();
  403. this.moveEventRegister.destroy();
  404. this.endEventRegister.destroy();
  405. };
  406. return EventHandler;
  407. }());
  408. var Indicator = /** @class */ (function () {
  409. function Indicator(scroll, options) {
  410. this.scroll = scroll;
  411. this.options = options;
  412. this.hooksFn = [];
  413. this.wrapper = options.wrapper;
  414. this.direction = options.direction;
  415. this.indicatorEl = this.wrapper.children[0];
  416. this.keysMap = this.getKeysMap();
  417. this.handleFade();
  418. this.handleHooks();
  419. }
  420. Indicator.prototype.handleFade = function () {
  421. if (this.options.fade) {
  422. this.wrapper.style.opacity = '0';
  423. }
  424. };
  425. Indicator.prototype.handleHooks = function () {
  426. var _this = this;
  427. var _a = this.options, fade = _a.fade, interactive = _a.interactive, scrollbarTrackClickable = _a.scrollbarTrackClickable;
  428. var scroll = this.scroll;
  429. var scrollHooks = scroll.hooks;
  430. var translaterHooks = scroll.scroller.translater.hooks;
  431. var animaterHooks = scroll.scroller.animater.hooks;
  432. this.registerHooks(scrollHooks, scrollHooks.eventTypes.refresh, this.refresh);
  433. this.registerHooks(translaterHooks, translaterHooks.eventTypes.translate, function (pos) {
  434. var hasScrollKey = _this.keysMap.hasScroll;
  435. if (_this.scroll[hasScrollKey]) {
  436. _this.updatePosition(pos);
  437. }
  438. });
  439. this.registerHooks(animaterHooks, animaterHooks.eventTypes.time, this.transitionTime);
  440. this.registerHooks(animaterHooks, animaterHooks.eventTypes.timeFunction, this.transitionTimingFunction);
  441. if (fade) {
  442. this.registerHooks(scroll, scroll.eventTypes.scrollEnd, function () {
  443. _this.fade();
  444. });
  445. this.registerHooks(scroll, scroll.eventTypes.scrollStart, function () {
  446. _this.fade(true);
  447. });
  448. // for mousewheel event
  449. if (scroll.eventTypes.mousewheelStart &&
  450. scroll.eventTypes.mousewheelEnd) {
  451. this.registerHooks(scroll, scroll.eventTypes.mousewheelStart, function () {
  452. _this.fade(true);
  453. });
  454. this.registerHooks(scroll, scroll.eventTypes.mousewheelMove, function () {
  455. _this.fade(true);
  456. });
  457. this.registerHooks(scroll, scroll.eventTypes.mousewheelEnd, function () {
  458. _this.fade();
  459. });
  460. }
  461. }
  462. if (interactive) {
  463. var _b = this.scroll.options, disableMouse = _b.disableMouse, disableTouch = _b.disableTouch;
  464. this.eventHandler = new EventHandler(this, {
  465. disableMouse: disableMouse,
  466. disableTouch: disableTouch,
  467. });
  468. var eventHandlerHooks = this.eventHandler.hooks;
  469. this.registerHooks(eventHandlerHooks, eventHandlerHooks.eventTypes.touchStart, this.startHandler);
  470. this.registerHooks(eventHandlerHooks, eventHandlerHooks.eventTypes.touchMove, this.moveHandler);
  471. this.registerHooks(eventHandlerHooks, eventHandlerHooks.eventTypes.touchEnd, this.endHandler);
  472. }
  473. if (scrollbarTrackClickable) {
  474. this.bindClick();
  475. }
  476. };
  477. Indicator.prototype.registerHooks = function (hooks, name, handler) {
  478. hooks.on(name, handler, this);
  479. this.hooksFn.push([hooks, name, handler]);
  480. };
  481. Indicator.prototype.bindClick = function () {
  482. var wrapper = this.wrapper;
  483. this.clickEventRegister = new EventRegister(wrapper, [
  484. {
  485. name: 'click',
  486. handler: this.handleClick.bind(this),
  487. },
  488. ]);
  489. };
  490. Indicator.prototype.handleClick = function (e) {
  491. var newPos = this.calculateclickOffsetPos(e);
  492. var _a = this.scroll, x = _a.x, y = _a.y;
  493. x = this.direction === "horizontal" /* Horizontal */ ? newPos : x;
  494. y = this.direction === "vertical" /* Vertical */ ? newPos : y;
  495. this.scroll.scrollTo(x, y, this.options.scrollbarTrackOffsetTime);
  496. };
  497. Indicator.prototype.calculateclickOffsetPos = function (e) {
  498. var _a = this.keysMap, poinKey = _a.point, domRectKey = _a.domRect;
  499. var scrollbarTrackOffsetType = this.options.scrollbarTrackOffsetType;
  500. var clickPointOffset = e[poinKey] - this.wrapperRect[domRectKey];
  501. var scrollToWhere = clickPointOffset < this.currentPos ? -1 /* Up */ : 1 /* Down */;
  502. var delta = 0;
  503. var currentPos = this.currentPos;
  504. if (scrollbarTrackOffsetType === "step" /* Step */) {
  505. delta = this.scrollInfo.baseSize * scrollToWhere;
  506. }
  507. else {
  508. delta = 0;
  509. currentPos = clickPointOffset;
  510. }
  511. return this.newPos(currentPos, delta, this.scrollInfo);
  512. };
  513. Indicator.prototype.getKeysMap = function () {
  514. if (this.direction === "vertical" /* Vertical */) {
  515. return {
  516. hasScroll: 'hasVerticalScroll',
  517. size: 'height',
  518. wrapperSize: 'clientHeight',
  519. scrollerSize: 'scrollerHeight',
  520. maxScrollPos: 'maxScrollY',
  521. pos: 'y',
  522. point: 'pageY',
  523. translateProperty: 'translateY',
  524. domRect: 'top',
  525. };
  526. }
  527. return {
  528. hasScroll: 'hasHorizontalScroll',
  529. size: 'width',
  530. wrapperSize: 'clientWidth',
  531. scrollerSize: 'scrollerWidth',
  532. maxScrollPos: 'maxScrollX',
  533. pos: 'x',
  534. point: 'pageX',
  535. translateProperty: 'translateX',
  536. domRect: 'left',
  537. };
  538. };
  539. Indicator.prototype.fade = function (visible) {
  540. var _a = this.options, fadeInTime = _a.fadeInTime, fadeOutTime = _a.fadeOutTime;
  541. var time = visible ? fadeInTime : fadeOutTime;
  542. var wrapper = this.wrapper;
  543. wrapper.style[style.transitionDuration] = time + 'ms';
  544. wrapper.style.opacity = visible ? '1' : '0';
  545. };
  546. Indicator.prototype.refresh = function () {
  547. var hasScrollKey = this.keysMap.hasScroll;
  548. var scroll = this.scroll;
  549. var x = scroll.x, y = scroll.y;
  550. this.wrapperRect = this.wrapper.getBoundingClientRect();
  551. if (this.canScroll(scroll[hasScrollKey])) {
  552. var _a = this.keysMap, wrapperSizeKey = _a.wrapperSize, scrollerSizeKey = _a.scrollerSize, maxScrollPosKey = _a.maxScrollPos;
  553. this.scrollInfo = this.refreshScrollInfo(this.wrapper[wrapperSizeKey], scroll[scrollerSizeKey], scroll[maxScrollPosKey], this.indicatorEl[wrapperSizeKey]);
  554. this.updatePosition({
  555. x: x,
  556. y: y,
  557. });
  558. }
  559. };
  560. Indicator.prototype.transitionTime = function (time) {
  561. if (time === void 0) { time = 0; }
  562. this.indicatorEl.style[style.transitionDuration] = time + 'ms';
  563. };
  564. Indicator.prototype.transitionTimingFunction = function (easing) {
  565. this.indicatorEl.style[style.transitionTimingFunction] = easing;
  566. };
  567. Indicator.prototype.canScroll = function (hasScroll) {
  568. this.wrapper.style.display = hasScroll ? 'block' : 'none';
  569. return hasScroll;
  570. };
  571. Indicator.prototype.refreshScrollInfo = function (wrapperSize, scrollerSize, maxScrollPos, indicatorElSize) {
  572. var baseSize = Math.max(Math.round((wrapperSize * wrapperSize) / (scrollerSize || wrapperSize || 1)), this.options.minSize);
  573. if (this.options.isCustom) {
  574. baseSize = indicatorElSize;
  575. }
  576. var maxIndicatorScrollPos = wrapperSize - baseSize;
  577. // sizeRatio is negative
  578. var sizeRatio = maxIndicatorScrollPos / maxScrollPos;
  579. return {
  580. baseSize: baseSize,
  581. maxScrollPos: maxIndicatorScrollPos,
  582. minScrollPos: 0,
  583. sizeRatio: sizeRatio,
  584. };
  585. };
  586. Indicator.prototype.updatePosition = function (point) {
  587. var _a = this.caculatePosAndSize(point, this.scrollInfo), pos = _a.pos, size = _a.size;
  588. this.refreshStyle(size, pos);
  589. this.currentPos = pos;
  590. };
  591. Indicator.prototype.caculatePosAndSize = function (point, scrollInfo) {
  592. var posKey = this.keysMap.pos;
  593. var sizeRatio = scrollInfo.sizeRatio, baseSize = scrollInfo.baseSize, maxScrollPos = scrollInfo.maxScrollPos, minScrollPos = scrollInfo.minScrollPos;
  594. var minSize = this.options.minSize;
  595. var pos = Math.round(sizeRatio * point[posKey]);
  596. var size;
  597. // when out of boundary, slow down size reduction
  598. if (pos < minScrollPos) {
  599. size = Math.max(baseSize + pos * 3, minSize);
  600. pos = minScrollPos;
  601. }
  602. else if (pos > maxScrollPos) {
  603. size = Math.max(baseSize - (pos - maxScrollPos) * 3, minSize);
  604. pos = maxScrollPos + baseSize - size;
  605. }
  606. else {
  607. size = baseSize;
  608. }
  609. return {
  610. pos: pos,
  611. size: size,
  612. };
  613. };
  614. Indicator.prototype.refreshStyle = function (size, pos) {
  615. var _a = this.keysMap, translatePropertyKey = _a.translateProperty, sizeKey = _a.size;
  616. var translateZ = this.scroll.options.translateZ;
  617. this.indicatorEl.style[sizeKey] = size + "px";
  618. this.indicatorEl.style[style.transform] = translatePropertyKey + "(" + pos + "px)" + translateZ;
  619. };
  620. Indicator.prototype.startHandler = function () {
  621. this.moved = false;
  622. this.startTime = getNow();
  623. this.transitionTime();
  624. this.scroll.scroller.hooks.trigger(this.scroll.scroller.hooks.eventTypes.beforeScrollStart);
  625. };
  626. Indicator.prototype.moveHandler = function (delta) {
  627. if (!this.moved && !this.indicatorNotMoved(delta)) {
  628. this.moved = true;
  629. this.scroll.scroller.hooks.trigger(this.scroll.scroller.hooks.eventTypes.scrollStart);
  630. }
  631. if (this.moved) {
  632. var newPos = this.newPos(this.currentPos, delta, this.scrollInfo);
  633. this.syncBScroll(newPos);
  634. }
  635. };
  636. Indicator.prototype.endHandler = function () {
  637. if (this.moved) {
  638. var _a = this.scroll, x = _a.x, y = _a.y;
  639. this.scroll.scroller.hooks.trigger(this.scroll.scroller.hooks.eventTypes.scrollEnd, {
  640. x: x,
  641. y: y,
  642. });
  643. }
  644. };
  645. Indicator.prototype.indicatorNotMoved = function (delta) {
  646. var currentPos = this.currentPos;
  647. var _a = this.scrollInfo, maxScrollPos = _a.maxScrollPos, minScrollPos = _a.minScrollPos;
  648. var notMoved = (currentPos === minScrollPos && delta <= 0) ||
  649. (currentPos === maxScrollPos && delta >= 0);
  650. return notMoved;
  651. };
  652. Indicator.prototype.syncBScroll = function (newPos) {
  653. var timestamp = getNow();
  654. var _a = this.scroll, x = _a.x, y = _a.y, options = _a.options, scroller = _a.scroller, maxScrollY = _a.maxScrollY, minScrollY = _a.minScrollY, maxScrollX = _a.maxScrollX, minScrollX = _a.minScrollX;
  655. var probeType = options.probeType, momentumLimitTime = options.momentumLimitTime;
  656. var position = { x: x, y: y };
  657. if (this.direction === "vertical" /* Vertical */) {
  658. position.y = between(newPos, maxScrollY, minScrollY);
  659. }
  660. else {
  661. position.x = between(newPos, maxScrollX, minScrollX);
  662. }
  663. scroller.translater.translate(position);
  664. // dispatch scroll in interval time
  665. if (timestamp - this.startTime > momentumLimitTime) {
  666. this.startTime = timestamp;
  667. if (probeType === 1 /* Throttle */) {
  668. scroller.hooks.trigger(scroller.hooks.eventTypes.scroll, position);
  669. }
  670. }
  671. // dispatch scroll all the time
  672. if (probeType > 1 /* Throttle */) {
  673. scroller.hooks.trigger(scroller.hooks.eventTypes.scroll, position);
  674. }
  675. };
  676. Indicator.prototype.newPos = function (currentPos, delta, scrollInfo) {
  677. var maxScrollPos = scrollInfo.maxScrollPos, sizeRatio = scrollInfo.sizeRatio, minScrollPos = scrollInfo.minScrollPos;
  678. var newPos = currentPos + delta;
  679. newPos = between(newPos, minScrollPos, maxScrollPos);
  680. return Math.round(newPos / sizeRatio);
  681. };
  682. Indicator.prototype.destroy = function () {
  683. var _a = this.options, interactive = _a.interactive, scrollbarTrackClickable = _a.scrollbarTrackClickable, isCustom = _a.isCustom;
  684. if (interactive) {
  685. this.eventHandler.destroy();
  686. }
  687. if (scrollbarTrackClickable) {
  688. this.clickEventRegister.destroy();
  689. }
  690. if (!isCustom) {
  691. this.wrapper.parentNode.removeChild(this.wrapper);
  692. }
  693. this.hooksFn.forEach(function (item) {
  694. var hooks = item[0];
  695. var hooksName = item[1];
  696. var handlerFn = item[2];
  697. hooks.off(hooksName, handlerFn);
  698. });
  699. this.hooksFn.length = 0;
  700. };
  701. return Indicator;
  702. }());
  703. var ScrollBar = /** @class */ (function () {
  704. function ScrollBar(scroll) {
  705. this.scroll = scroll;
  706. this.handleOptions();
  707. this.createIndicators();
  708. this.handleHooks();
  709. }
  710. ScrollBar.prototype.handleHooks = function () {
  711. var _this = this;
  712. var scroll = this.scroll;
  713. scroll.hooks.on(scroll.hooks.eventTypes.destroy, function () {
  714. for (var _i = 0, _a = _this.indicators; _i < _a.length; _i++) {
  715. var indicator = _a[_i];
  716. indicator.destroy();
  717. }
  718. });
  719. };
  720. ScrollBar.prototype.handleOptions = function () {
  721. var userOptions = (this.scroll.options.scrollbar === true
  722. ? {}
  723. : this.scroll.options.scrollbar);
  724. var defaultOptions = {
  725. fade: true,
  726. fadeInTime: 250,
  727. fadeOutTime: 500,
  728. interactive: false,
  729. customElements: [],
  730. minSize: 8,
  731. scrollbarTrackClickable: false,
  732. scrollbarTrackOffsetType: "step" /* Step */,
  733. scrollbarTrackOffsetTime: 300,
  734. };
  735. this.options = extend(defaultOptions, userOptions);
  736. };
  737. ScrollBar.prototype.createIndicators = function () {
  738. var indicatorOptions;
  739. var scroll = this.scroll;
  740. var indicators = [];
  741. var scrollDirectionConfigKeys = ['scrollX', 'scrollY'];
  742. var indicatorDirections = [
  743. "horizontal" /* Horizontal */,
  744. "vertical" /* Vertical */,
  745. ];
  746. var customScrollbarEls = this.options.customElements;
  747. for (var i = 0; i < scrollDirectionConfigKeys.length; i++) {
  748. var key = scrollDirectionConfigKeys[i];
  749. // wanna scroll in specified direction
  750. if (scroll.options[key]) {
  751. var customElement = customScrollbarEls.shift();
  752. var direction = indicatorDirections[i];
  753. var isCustom = false;
  754. var scrollbarWrapper = customElement
  755. ? customElement
  756. : this.createScrollbarElement(direction);
  757. // internal scrollbar
  758. if (scrollbarWrapper !== customElement) {
  759. scroll.wrapper.appendChild(scrollbarWrapper);
  760. }
  761. else {
  762. // custom scrollbar passed by users
  763. isCustom = true;
  764. }
  765. indicatorOptions = __assign(__assign({ wrapper: scrollbarWrapper, direction: direction }, this.options), { isCustom: isCustom });
  766. indicators.push(new Indicator(scroll, indicatorOptions));
  767. }
  768. }
  769. this.indicators = indicators;
  770. };
  771. ScrollBar.prototype.createScrollbarElement = function (direction, scrollbarTrackClickable) {
  772. if (scrollbarTrackClickable === void 0) { scrollbarTrackClickable = this.options.scrollbarTrackClickable; }
  773. var scrollbarWrapperEl = document.createElement('div');
  774. var scrollbarIndicatorEl = document.createElement('div');
  775. scrollbarWrapperEl.style.cssText =
  776. 'position:absolute;z-index:9999;overflow:hidden;';
  777. scrollbarIndicatorEl.style.cssText =
  778. 'box-sizing:border-box;position:absolute;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);border-radius:3px;';
  779. scrollbarIndicatorEl.className = 'bscroll-indicator';
  780. if (direction === "horizontal" /* Horizontal */) {
  781. scrollbarWrapperEl.style.cssText +=
  782. 'height:7px;left:2px;right:2px;bottom:0;';
  783. scrollbarIndicatorEl.style.height = '100%';
  784. scrollbarWrapperEl.className = 'bscroll-horizontal-scrollbar';
  785. }
  786. else {
  787. scrollbarWrapperEl.style.cssText +=
  788. 'width:7px;bottom:2px;top:2px;right:1px;';
  789. scrollbarIndicatorEl.style.width = '100%';
  790. scrollbarWrapperEl.className = 'bscroll-vertical-scrollbar';
  791. }
  792. if (!scrollbarTrackClickable) {
  793. scrollbarWrapperEl.style.cssText += 'pointer-events:none;';
  794. }
  795. scrollbarWrapperEl.appendChild(scrollbarIndicatorEl);
  796. return scrollbarWrapperEl;
  797. };
  798. ScrollBar.pluginName = 'scrollbar';
  799. return ScrollBar;
  800. }());
  801. return ScrollBar;
  802. })));