jquery-asScrollbar.es.js 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054
  1. /**
  2. * jQuery asScrollbar v0.5.7
  3. * https://github.com/amazingSurge/jquery-asScrollbar
  4. *
  5. * Copyright (c) amazingSurge
  6. * Released under the LGPL-3.0 license
  7. */
  8. import $ from 'jquery';
  9. var DEFAULTS = {
  10. namespace: 'asScrollbar',
  11. skin: null,
  12. handleSelector: null,
  13. handleTemplate: '<div class="{{handle}}"></div>',
  14. barClass: null,
  15. handleClass: null,
  16. disabledClass: 'is-disabled',
  17. draggingClass: 'is-dragging',
  18. hoveringClass: 'is-hovering',
  19. direction: 'vertical',
  20. barLength: null,
  21. handleLength: null,
  22. minHandleLength: 30,
  23. maxHandleLength: null,
  24. mouseDrag: true,
  25. touchDrag: true,
  26. pointerDrag: true,
  27. clickMove: true,
  28. clickMoveStep: 0.3, // 0 - 1
  29. mousewheel: true,
  30. mousewheelSpeed: 50,
  31. keyboard: true,
  32. useCssTransforms3d: true,
  33. useCssTransforms: true,
  34. useCssTransitions: true,
  35. duration: '500',
  36. easing: 'ease' // linear, ease-in, ease-out, ease-in-out
  37. };
  38. const easingBezier = (mX1, mY1, mX2, mY2) => {
  39. 'use strict';
  40. const a = (aA1, aA2) => {
  41. return 1.0 - 3.0 * aA2 + 3.0 * aA1;
  42. };
  43. const b = (aA1, aA2) => {
  44. return 3.0 * aA2 - 6.0 * aA1;
  45. };
  46. const c = (aA1) => {
  47. return 3.0 * aA1;
  48. };
  49. // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
  50. const calcBezier = (aT, aA1, aA2) => {
  51. return ((a(aA1, aA2) * aT + b(aA1, aA2)) * aT + c(aA1)) * aT;
  52. };
  53. // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
  54. const getSlope = (aT, aA1, aA2) => {
  55. return 3.0 * a(aA1, aA2) * aT * aT + 2.0 * b(aA1, aA2) * aT + c(aA1);
  56. };
  57. const getTForX = (aX) => {
  58. // Newton raphson iteration
  59. let aGuessT = aX;
  60. for (let i = 0; i < 4; ++i) {
  61. let currentSlope = getSlope(aGuessT, mX1, mX2);
  62. if (currentSlope === 0.0) {
  63. return aGuessT;
  64. }
  65. let currentX = calcBezier(aGuessT, mX1, mX2) - aX;
  66. aGuessT -= currentX / currentSlope;
  67. }
  68. return aGuessT;
  69. };
  70. if (mX1 === mY1 && mX2 === mY2) {
  71. return {
  72. css: 'linear',
  73. fn(aX) {
  74. return aX;
  75. }
  76. };
  77. }
  78. return {
  79. css: `cubic-bezier(${mX1},${mY1},${mX2},${mY2})`,
  80. fn(aX) {
  81. return calcBezier(getTForX(aX), mY1, mY2);
  82. }
  83. };
  84. };
  85. var EASING = {
  86. ease: easingBezier(0.25, 0.1, 0.25, 1.0),
  87. linear: easingBezier(0.00, 0.0, 1.00, 1.0),
  88. 'ease-in': easingBezier(0.42, 0.0, 1.00, 1.0),
  89. 'ease-out': easingBezier(0.00, 0.0, 0.58, 1.0),
  90. 'ease-in-out': easingBezier(0.42, 0.0, 0.58, 1.0)
  91. };
  92. if (!Date.now) {
  93. Date.now = () => {
  94. return new Date().getTime();
  95. };
  96. }
  97. const vendors = ['webkit', 'moz'];
  98. for (let i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
  99. let vp = vendors[i];
  100. window.requestAnimationFrame = window[`${vp}RequestAnimationFrame`];
  101. window.cancelAnimationFrame = (window[`${vp}CancelAnimationFrame`] || window[`${vp}CancelRequestAnimationFrame`]);
  102. }
  103. if (/iP(ad|hone|od).*OS (6|7|8)/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
  104. let lastTime = 0;
  105. window.requestAnimationFrame = (callback) => {
  106. let now = getTime();
  107. let timePlus = 16;
  108. let nextTime = Math.max(lastTime + timePlus, now);
  109. return setTimeout(() => {
  110. callback(lastTime = nextTime);
  111. },
  112. nextTime - now);
  113. };
  114. window.cancelAnimationFrame = clearTimeout;
  115. }
  116. function isPercentage(n) {
  117. return typeof n === 'string' && n.indexOf('%') !== -1;
  118. }
  119. function convertPercentageToFloat(n) {
  120. return parseFloat(n.slice(0, -1) / 100, 10);
  121. }
  122. function convertMatrixToArray(value) {
  123. if (value && (value.substr(0, 6) === 'matrix')) {
  124. return value.replace(/^.*\((.*)\)$/g, '$1').replace(/px/g, '').split(/, +/);
  125. }
  126. return false;
  127. }
  128. function getTime () {
  129. if (typeof window.performance !== 'undefined' && window.performance.now) {
  130. return window.performance.now();
  131. }
  132. return Date.now();
  133. }
  134. /**
  135. * Css features detect
  136. **/
  137. let support = {};
  138. ((support) => {
  139. /**
  140. * Borrowed from Owl carousel
  141. **/
  142. 'use strict';
  143. const events = {
  144. transition: {
  145. end: {
  146. WebkitTransition: 'webkitTransitionEnd',
  147. MozTransition: 'transitionend',
  148. OTransition: 'oTransitionEnd',
  149. transition: 'transitionend'
  150. }
  151. },
  152. animation: {
  153. end: {
  154. WebkitAnimation: 'webkitAnimationEnd',
  155. MozAnimation: 'animationend',
  156. OAnimation: 'oAnimationEnd',
  157. animation: 'animationend'
  158. }
  159. }
  160. },
  161. prefixes = ['webkit', 'Moz', 'O', 'ms'],
  162. style = $('<support>').get(0).style,
  163. tests = {
  164. csstransforms() {
  165. return Boolean(test('transform'));
  166. },
  167. csstransforms3d() {
  168. return Boolean(test('perspective'));
  169. },
  170. csstransitions() {
  171. return Boolean(test('transition'));
  172. },
  173. cssanimations() {
  174. return Boolean(test('animation'));
  175. }
  176. };
  177. const test = (property, prefixed) => {
  178. let result = false,
  179. upper = property.charAt(0).toUpperCase() + property.slice(1);
  180. if (style[property] !== undefined) {
  181. result = property;
  182. }
  183. if (!result) {
  184. $.each(prefixes, (i, prefix) => {
  185. if (style[prefix + upper] !== undefined) {
  186. result = `-${prefix.toLowerCase()}-${upper}`;
  187. return false;
  188. }
  189. return true;
  190. });
  191. }
  192. if (prefixed) {
  193. return result;
  194. }
  195. if (result) {
  196. return true;
  197. }
  198. return false;
  199. };
  200. const prefixed = (property) => {
  201. return test(property, true);
  202. };
  203. if (tests.csstransitions()) {
  204. /*eslint no-new-wrappers: "off"*/
  205. support.transition = new String(prefixed('transition'));
  206. support.transition.end = events.transition.end[support.transition];
  207. }
  208. if (tests.cssanimations()) {
  209. /*eslint no-new-wrappers: "off"*/
  210. support.animation = new String(prefixed('animation'));
  211. support.animation.end = events.animation.end[support.animation];
  212. }
  213. if (tests.csstransforms()) {
  214. /*eslint no-new-wrappers: "off"*/
  215. support.transform = new String(prefixed('transform'));
  216. support.transform3d = tests.csstransforms3d();
  217. }
  218. if (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch) {
  219. support.touch = true;
  220. } else {
  221. support.touch = false;
  222. }
  223. if (window.PointerEvent || window.MSPointerEvent) {
  224. support.pointer = true;
  225. } else {
  226. support.pointer = false;
  227. }
  228. support.prefixPointerEvent = (pointerEvent) => {
  229. return window.MSPointerEvent ?
  230. `MSPointer${pointerEvent.charAt(9).toUpperCase()}${pointerEvent.substr(10)}` :
  231. pointerEvent;
  232. };
  233. })(support);
  234. const NAMESPACE$1 = 'asScrollbar';
  235. /**
  236. * Plugin constructor
  237. **/
  238. class asScrollbar {
  239. constructor(bar, options = {}) {
  240. this.$bar = $(bar);
  241. options = this.options = $.extend({}, DEFAULTS, options, this.$bar.data('options') || {});
  242. bar.direction = this.options.direction;
  243. this.classes = {
  244. directionClass: `${options.namespace}-${options.direction}`,
  245. barClass: options.barClass? options.barClass: options.namespace,
  246. handleClass: options.handleClass? options.handleClass: `${options.namespace}-handle`
  247. };
  248. if (this.options.direction === 'vertical') {
  249. this.attributes = {
  250. axis: 'Y',
  251. position: 'top',
  252. length: 'height',
  253. clientLength: 'clientHeight'
  254. };
  255. } else if (this.options.direction === 'horizontal') {
  256. this.attributes = {
  257. axis: 'X',
  258. position: 'left',
  259. length: 'width',
  260. clientLength: 'clientWidth'
  261. };
  262. }
  263. // Current state information.
  264. this._states = {};
  265. // Current state information for the drag operation.
  266. this._drag = {
  267. time: null,
  268. pointer: null
  269. };
  270. // Current timeout
  271. this._frameId = null;
  272. // Current handle position
  273. this.handlePosition = 0;
  274. this.easing = EASING[this.options.easing] || EASING.ease;
  275. this.init();
  276. }
  277. init() {
  278. let options = this.options;
  279. this.$handle = this.$bar.find(this.options.handleSelector);
  280. if (this.$handle.length === 0) {
  281. this.$handle = $(options.handleTemplate.replace(/\{\{handle\}\}/g, this.classes.handleClass)).appendTo(this.$bar);
  282. } else {
  283. this.$handle.addClass(this.classes.handleClass);
  284. }
  285. this.$bar.addClass(this.classes.barClass).addClass(this.classes.directionClass).attr('draggable', false);
  286. if (options.skin) {
  287. this.$bar.addClass(options.skin);
  288. }
  289. if (options.barLength !== null) {
  290. this.setBarLength(options.barLength);
  291. }
  292. if (options.handleLength !== null) {
  293. this.setHandleLength(options.handleLength);
  294. }
  295. this.updateLength();
  296. this.bindEvents();
  297. this.trigger('ready');
  298. }
  299. trigger(eventType, ...params) {
  300. let data = [this].concat(params);
  301. // event
  302. this.$bar.trigger(`${NAMESPACE$1}::${eventType}`, data);
  303. // callback
  304. eventType = eventType.replace(/\b\w+\b/g, (word) => {
  305. return word.substring(0, 1).toUpperCase() + word.substring(1);
  306. });
  307. let onFunction = `on${eventType}`;
  308. if (typeof this.options[onFunction] === 'function') {
  309. this.options[onFunction].apply(this, params);
  310. }
  311. }
  312. /**
  313. * Checks whether the carousel is in a specific state or not.
  314. */
  315. is(state) {
  316. return this._states[state] && this._states[state] > 0;
  317. }
  318. /**
  319. * Enters a state.
  320. */
  321. enter(state) {
  322. if (this._states[state] === undefined) {
  323. this._states[state] = 0;
  324. }
  325. this._states[state]++;
  326. }
  327. /**
  328. * Leaves a state.
  329. */
  330. leave(state) {
  331. this._states[state]--;
  332. }
  333. eventName(events) {
  334. if (typeof events !== 'string' || events === '') {
  335. return `.${this.options.namespace}`;
  336. }
  337. events = events.split(' ');
  338. let length = events.length;
  339. for (let i = 0; i < length; i++) {
  340. events[i] = `${events[i]}.${this.options.namespace}`;
  341. }
  342. return events.join(' ');
  343. }
  344. bindEvents() {
  345. if (this.options.mouseDrag) {
  346. this.$handle.on(this.eventName('mousedown'), $.proxy(this.onDragStart, this));
  347. this.$handle.on(this.eventName('dragstart selectstart'), () => {
  348. return false;
  349. });
  350. }
  351. if (this.options.touchDrag && support.touch) {
  352. this.$handle.on(this.eventName('touchstart'), $.proxy(this.onDragStart, this));
  353. this.$handle.on(this.eventName('touchcancel'), $.proxy(this.onDragEnd, this));
  354. }
  355. if (this.options.pointerDrag && support.pointer) {
  356. this.$handle.on(this.eventName(support.prefixPointerEvent('pointerdown')), $.proxy(this.onDragStart, this));
  357. this.$handle.on(this.eventName(support.prefixPointerEvent('pointercancel')), $.proxy(this.onDragEnd, this));
  358. }
  359. if (this.options.clickMove) {
  360. this.$bar.on(this.eventName('mousedown'), $.proxy(this.onClick, this));
  361. }
  362. if (this.options.mousewheel) {
  363. this.$bar.on('mousewheel', (e) => {
  364. let delta;
  365. if (this.options.direction === 'vertical') {
  366. delta = e.deltaFactor * e.deltaY;
  367. } else if (this.options.direction === 'horizontal') {
  368. delta = -1 * e.deltaFactor * e.deltaX;
  369. }
  370. let offset = this.getHandlePosition();
  371. if (offset <= 0 && delta > 0) {
  372. return true;
  373. } else if (offset >= this.barLength && delta < 0) {
  374. return true;
  375. }
  376. offset -= this.options.mousewheelSpeed * delta;
  377. this.move(offset, true);
  378. return false;
  379. });
  380. }
  381. this.$bar.on(this.eventName('mouseenter'), () => {
  382. this.$bar.addClass(this.options.hoveringClass);
  383. this.enter('hovering');
  384. this.trigger('hover');
  385. });
  386. this.$bar.on(this.eventName('mouseleave'), () => {
  387. this.$bar.removeClass(this.options.hoveringClass);
  388. if (!this.is('hovering')) {
  389. return;
  390. }
  391. this.leave('hovering');
  392. this.trigger('hovered');
  393. });
  394. if (this.options.keyboard) {
  395. $(document).on(this.eventName('keydown'), (e) => {
  396. if (e.isDefaultPrevented && e.isDefaultPrevented()) {
  397. return;
  398. }
  399. if (!this.is('hovering')) {
  400. return;
  401. }
  402. let activeElement = document.activeElement;
  403. // go deeper if element is a webcomponent
  404. while (activeElement.shadowRoot) {
  405. activeElement = activeElement.shadowRoot.activeElement;
  406. }
  407. if ($(activeElement).is(':input,select,option,[contenteditable]')) {
  408. return;
  409. }
  410. let by = 0,
  411. to = null;
  412. let down = 40,
  413. end = 35,
  414. home = 36,
  415. left = 37,
  416. pageDown = 34,
  417. pageUp = 33,
  418. right = 39,
  419. spaceBar = 32,
  420. up = 38;
  421. let webkitDown = 63233,
  422. webkitEnd = 63275,
  423. webkitHome = 63273,
  424. webkitLeft = 63234,
  425. webkitPageDown = 63277,
  426. webkitPageUp = 63276,
  427. webkitRight = 63235,
  428. webkitUp = 63232;
  429. switch (e.which) {
  430. case left: // left
  431. case webkitUp:
  432. by = -30;
  433. break;
  434. case up: // up
  435. case webkitDown:
  436. by = -30;
  437. break;
  438. case right: // right
  439. case webkitLeft:
  440. by = 30;
  441. break;
  442. case down: // down
  443. case webkitRight:
  444. by = 30;
  445. break;
  446. case pageUp: // page up
  447. case webkitPageUp:
  448. by = -90;
  449. break;
  450. case spaceBar: // space bar
  451. case pageDown: // page down
  452. case webkitPageDown:
  453. by = -90;
  454. break;
  455. case end: // end
  456. case webkitEnd:
  457. to = '100%';
  458. break;
  459. case home: // home
  460. case webkitHome:
  461. to = 0;
  462. break;
  463. default:
  464. return;
  465. }
  466. if (by || to !== null) {
  467. if (by) {
  468. this.moveBy(by, true);
  469. } else if (to !== null) {
  470. this.moveTo(to, true);
  471. }
  472. e.preventDefault();
  473. }
  474. });
  475. }
  476. }
  477. onClick(event) {
  478. let num = 3;
  479. if (event.which === num) {
  480. return;
  481. }
  482. if (event.target === this.$handle[0]) {
  483. return;
  484. }
  485. this._drag.time = new Date().getTime();
  486. this._drag.pointer = this.pointer(event);
  487. let offset = this.$handle.offset();
  488. let distance = this.distance({
  489. x: offset.left,
  490. y: offset.top
  491. }, this._drag.pointer),
  492. factor = 1;
  493. if (distance > 0) {
  494. distance -= this.handleLength;
  495. } else {
  496. distance = Math.abs(distance);
  497. factor = -1;
  498. }
  499. if (distance > this.barLength * this.options.clickMoveStep) {
  500. distance = this.barLength * this.options.clickMoveStep;
  501. }
  502. this.moveBy(factor * distance, true);
  503. }
  504. /**
  505. * Handles `touchstart` and `mousedown` events.
  506. */
  507. onDragStart(event) {
  508. let num = 3;
  509. if (event.which === num) {
  510. return;
  511. }
  512. // this.$bar.toggleClass(this.options.draggingClass, event.type === 'mousedown');
  513. this.$bar.addClass(this.options.draggingClass);
  514. this._drag.time = new Date().getTime();
  515. this._drag.pointer = this.pointer(event);
  516. let callback = () => {
  517. this.enter('dragging');
  518. this.trigger('drag');
  519. };
  520. if (this.options.mouseDrag) {
  521. $(document).on(this.eventName('mouseup'), $.proxy(this.onDragEnd, this));
  522. $(document).one(this.eventName('mousemove'), $.proxy(() => {
  523. $(document).on(this.eventName('mousemove'), $.proxy(this.onDragMove, this));
  524. callback();
  525. }, this));
  526. }
  527. if (this.options.touchDrag && support.touch) {
  528. $(document).on(this.eventName('touchend'), $.proxy(this.onDragEnd, this));
  529. $(document).one(this.eventName('touchmove'), $.proxy(() => {
  530. $(document).on(this.eventName('touchmove'), $.proxy(this.onDragMove, this));
  531. callback();
  532. }, this));
  533. }
  534. if (this.options.pointerDrag && support.pointer) {
  535. $(document).on(this.eventName(support.prefixPointerEvent('pointerup')), $.proxy(this.onDragEnd, this));
  536. $(document).one(this.eventName(support.prefixPointerEvent('pointermove')), $.proxy(() => {
  537. $(document).on(this.eventName(support.prefixPointerEvent('pointermove')), $.proxy(this.onDragMove, this));
  538. callback();
  539. }, this));
  540. }
  541. $(document).on(this.eventName('blur'), $.proxy(this.onDragEnd, this));
  542. }
  543. /**
  544. * Handles the `touchmove` and `mousemove` events.
  545. */
  546. onDragMove(event) {
  547. let distance = this.distance(this._drag.pointer, this.pointer(event));
  548. if (!this.is('dragging')) {
  549. return;
  550. }
  551. event.preventDefault();
  552. this.moveBy(distance, true);
  553. }
  554. /**
  555. * Handles the `touchend` and `mouseup` events.
  556. */
  557. onDragEnd() {
  558. $(document).off(this.eventName('mousemove mouseup touchmove touchend pointermove pointerup MSPointerMove MSPointerUp blur'));
  559. this.$bar.removeClass(this.options.draggingClass);
  560. this.handlePosition = this.getHandlePosition();
  561. if (!this.is('dragging')) {
  562. return;
  563. }
  564. this.leave('dragging');
  565. this.trigger('dragged');
  566. }
  567. /**
  568. * Gets unified pointer coordinates from event.
  569. * @returns {Object} - Contains `x` and `y` coordinates of current pointer position.
  570. */
  571. pointer(event) {
  572. let result = {
  573. x: null,
  574. y: null
  575. };
  576. event = event.originalEvent || event || window.event;
  577. event = event.touches && event.touches.length ?
  578. event.touches[0] : event.changedTouches && event.changedTouches.length ?
  579. event.changedTouches[0] : event;
  580. if (event.pageX) {
  581. result.x = event.pageX;
  582. result.y = event.pageY;
  583. } else {
  584. result.x = event.clientX;
  585. result.y = event.clientY;
  586. }
  587. return result;
  588. }
  589. /**
  590. * Gets the distance of two pointer.
  591. */
  592. distance(first, second) {
  593. if (this.options.direction === 'vertical') {
  594. return second.y - first.y;
  595. }
  596. return second.x - first.x;
  597. }
  598. setBarLength(length, update) {
  599. if (typeof length !== 'undefined') {
  600. this.$bar.css(this.attributes.length, length);
  601. }
  602. if (update !== false) {
  603. this.updateLength();
  604. }
  605. }
  606. setHandleLength(length, update) {
  607. if (typeof length !== 'undefined') {
  608. if (length < this.options.minHandleLength) {
  609. length = this.options.minHandleLength;
  610. } else if (this.options.maxHandleLength && length > this.options.maxHandleLength) {
  611. length = this.options.maxHandleLength;
  612. }
  613. this.$handle.css(this.attributes.length, length);
  614. if (update !== false) {
  615. this.updateLength(length);
  616. }
  617. }
  618. }
  619. updateLength(length, barLength) {
  620. if (typeof length !== 'undefined') {
  621. this.handleLength = length;
  622. } else {
  623. this.handleLength = this.getHandleLenght();
  624. }
  625. if (typeof barLength !== 'undefined') {
  626. this.barLength = barLength;
  627. } else {
  628. this.barLength = this.getBarLength();
  629. }
  630. }
  631. getBarLength() {
  632. return this.$bar[0][this.attributes.clientLength];
  633. }
  634. getHandleLenght() {
  635. return this.$handle[0][this.attributes.clientLength];
  636. }
  637. getHandlePosition() {
  638. let value;
  639. if (this.options.useCssTransforms && support.transform) {
  640. value = convertMatrixToArray(this.$handle.css(support.transform));
  641. if (!value) {
  642. return 0;
  643. }
  644. if (this.attributes.axis === 'X') {
  645. value = value[12] || value[4];
  646. } else {
  647. value = value[13] || value[5];
  648. }
  649. } else {
  650. value = this.$handle.css(this.attributes.position);
  651. }
  652. return parseFloat(value.replace('px', ''));
  653. }
  654. makeHandlePositionStyle(value) {
  655. let property, x = '0',
  656. y = '0';
  657. if (this.options.useCssTransforms && support.transform) {
  658. if (this.attributes.axis === 'X') {
  659. x = `${value}px`;
  660. } else {
  661. y = `${value}px`;
  662. }
  663. property = support.transform.toString();
  664. if (this.options.useCssTransforms3d && support.transform3d) {
  665. value = `translate3d(${x},${y},0)`;
  666. } else {
  667. value = `translate(${x},${y})`;
  668. }
  669. } else {
  670. property = this.attributes.position;
  671. }
  672. let temp = {};
  673. temp[property] = value;
  674. return temp;
  675. }
  676. setHandlePosition(value) {
  677. let style = this.makeHandlePositionStyle(value);
  678. this.$handle.css(style);
  679. if (!this.is('dragging')) {
  680. this.handlePosition = parseFloat(value);
  681. }
  682. }
  683. moveTo(value, trigger, sync) {
  684. let type = typeof value;
  685. if (type === 'string') {
  686. if (isPercentage(value)) {
  687. value = convertPercentageToFloat(value) * (this.barLength - this.handleLength);
  688. }
  689. value = parseFloat(value);
  690. type = 'number';
  691. }
  692. if (type !== 'number') {
  693. return;
  694. }
  695. this.move(value, trigger, sync);
  696. }
  697. moveBy(value, trigger, sync) {
  698. let type = typeof value;
  699. if (type === 'string') {
  700. if (isPercentage(value)) {
  701. value = convertPercentageToFloat(value) * (this.barLength - this.handleLength);
  702. }
  703. value = parseFloat(value);
  704. type = 'number';
  705. }
  706. if (type !== 'number') {
  707. return;
  708. }
  709. this.move(this.handlePosition + value, trigger, sync);
  710. }
  711. move(value, trigger, sync) {
  712. if (typeof value !== 'number' || this.is('disabled')) {
  713. return;
  714. }
  715. if (value < 0) {
  716. value = 0;
  717. } else if (value + this.handleLength > this.barLength) {
  718. value = this.barLength - this.handleLength;
  719. }
  720. if (!this.is('dragging') && sync !== true) {
  721. this.doMove(value, this.options.duration, this.options.easing, trigger);
  722. } else {
  723. this.setHandlePosition(value);
  724. if (trigger) {
  725. this.trigger('change', value / (this.barLength - this.handleLength));
  726. }
  727. }
  728. }
  729. doMove(value, duration, easing, trigger) {
  730. let property;
  731. this.enter('moving');
  732. duration = duration ? duration : this.options.duration;
  733. easing = easing ? easing : this.options.easing;
  734. let style = this.makeHandlePositionStyle(value);
  735. for (property in style) {
  736. if ({}.hasOwnProperty.call(style, property)) {
  737. break;
  738. }
  739. }
  740. if (this.options.useCssTransitions && support.transition) {
  741. this.enter('transition');
  742. this.prepareTransition(property, duration, easing);
  743. this.$handle.one(support.transition.end, () => {
  744. this.$handle.css(support.transition, '');
  745. if (trigger) {
  746. this.trigger('change', value / (this.barLength - this.handleLength));
  747. }
  748. this.leave('transition');
  749. this.leave('moving');
  750. });
  751. this.setHandlePosition(value);
  752. } else {
  753. this.enter('animating');
  754. let startTime = getTime();
  755. let start = this.getHandlePosition();
  756. let end = value;
  757. let run = (time) => {
  758. let percent = (time - startTime) / this.options.duration;
  759. if (percent > 1) {
  760. percent = 1;
  761. }
  762. percent = this.easing.fn(percent);
  763. let scale = 10;
  764. let current = parseFloat(start + percent * (end - start), scale);
  765. this.setHandlePosition(current);
  766. if (trigger) {
  767. this.trigger('change', current / (this.barLength - this.handleLength));
  768. }
  769. if (percent === 1) {
  770. window.cancelAnimationFrame(this._frameId);
  771. this._frameId = null;
  772. this.leave('animating');
  773. this.leave('moving');
  774. } else {
  775. this._frameId = window.requestAnimationFrame(run);
  776. }
  777. };
  778. this._frameId = window.requestAnimationFrame(run);
  779. }
  780. }
  781. prepareTransition(property, duration, easing, delay) {
  782. let temp = [];
  783. if (property) {
  784. temp.push(property);
  785. }
  786. if (duration) {
  787. if ($.isNumeric(duration)) {
  788. duration = `${duration}ms`;
  789. }
  790. temp.push(duration);
  791. }
  792. if (easing) {
  793. temp.push(easing);
  794. } else {
  795. temp.push(this.easing.css);
  796. }
  797. if (delay) {
  798. temp.push(delay);
  799. }
  800. this.$handle.css(support.transition, temp.join(' '));
  801. }
  802. enable() {
  803. this._states.disabled = 0;
  804. this.$bar.removeClass(this.options.disabledClass);
  805. this.trigger('enable');
  806. }
  807. disable() {
  808. this._states.disabled = 1;
  809. this.$bar.addClass(this.options.disabledClass);
  810. this.trigger('disable');
  811. }
  812. destroy() {
  813. this.$handle.removeClass(this.classes.handleClass);
  814. this.$bar.removeClass(this.classes.barClass).removeClass(this.classes.directionClass).attr('draggable', null);
  815. if (this.options.skin) {
  816. this.$bar.removeClass(this.options.skin);
  817. }
  818. this.$bar.off(this.eventName());
  819. this.$handle.off(this.eventName());
  820. this.trigger('destroy');
  821. }
  822. static registerEasing(name, ...args) {
  823. EASING[name] = easingBezier(...args);
  824. }
  825. static getEasing(name) {
  826. return EASING[name];
  827. }
  828. static setDefaults(options) {
  829. $.extend(DEFAULTS, $.isPlainObject(options) && options);
  830. }
  831. }
  832. var info = {
  833. version:'0.5.7'
  834. };
  835. const NAMESPACE = 'asScrollbar';
  836. const OtherAsScrollbar = $.fn.asScrollbar;
  837. const jQueryAsScrollbar = function(options, ...args) {
  838. if (typeof options === 'string') {
  839. const method = options;
  840. if (/^_/.test(method)) {
  841. return false;
  842. } else if ((/^(get)/.test(method))) {
  843. const instance = this.first().data(NAMESPACE);
  844. if (instance && typeof instance[method] === 'function') {
  845. return instance[method](...args);
  846. }
  847. } else {
  848. return this.each(function() {
  849. const instance = $.data(this, NAMESPACE);
  850. if (instance && typeof instance[method] === 'function') {
  851. instance[method](...args);
  852. }
  853. });
  854. }
  855. }
  856. return this.each(function() {
  857. if (!$(this).data(NAMESPACE)) {
  858. $(this).data(NAMESPACE, new asScrollbar(this, options));
  859. }
  860. });
  861. };
  862. $.fn.asScrollbar = jQueryAsScrollbar;
  863. $.asScrollbar = $.extend({
  864. setDefaults: asScrollbar.setDefaults,
  865. registerEasing: asScrollbar.registerEasing,
  866. getEasing: asScrollbar.getEasing,
  867. noConflict: function() {
  868. $.fn.asScrollbar = OtherAsScrollbar;
  869. return jQueryAsScrollbar;
  870. }
  871. }, info);