scroll-behaviour.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  4. (factory((global.MobileDragDrop = global.MobileDragDrop || {})));
  5. }(this, (function (exports) { 'use strict';
  6. function isTopLevelEl(el) {
  7. return (el === document.body || el === document.documentElement);
  8. }
  9. function getElementViewportOffset(el, axis) {
  10. var offset;
  11. if (isTopLevelEl(el)) {
  12. offset = (axis === 0) ? el.clientLeft : el.clientTop;
  13. }
  14. else {
  15. var bounds = el.getBoundingClientRect();
  16. offset = (axis === 0) ? bounds.left : bounds.top;
  17. }
  18. return offset;
  19. }
  20. function getElementViewportSize(el, axis) {
  21. var size;
  22. if (isTopLevelEl(el)) {
  23. size = (axis === 0) ? window.innerWidth : window.innerHeight;
  24. }
  25. else {
  26. size = (axis === 0) ? el.clientWidth : el.clientHeight;
  27. }
  28. return size;
  29. }
  30. function getSetElementScroll(el, axis, scroll) {
  31. var prop = (axis === 0) ? "scrollLeft" : "scrollTop";
  32. var isTopLevel = isTopLevelEl(el);
  33. if (arguments.length === 2) {
  34. if (isTopLevel) {
  35. return document.body[prop] || document.documentElement[prop];
  36. }
  37. return el[prop];
  38. }
  39. if (isTopLevel) {
  40. document.documentElement[prop] += scroll;
  41. document.body[prop] += scroll;
  42. }
  43. else {
  44. el[prop] += scroll;
  45. }
  46. }
  47. function isScrollable(el) {
  48. var cs = getComputedStyle(el);
  49. if (el.scrollHeight > el.clientHeight && (cs.overflowY === "scroll" || cs.overflowY === "auto")) {
  50. return true;
  51. }
  52. if (el.scrollWidth > el.clientWidth && (cs.overflowX === "scroll" || cs.overflowX === "auto")) {
  53. return true;
  54. }
  55. return false;
  56. }
  57. function findScrollableParent(el) {
  58. do {
  59. if (!el) {
  60. return undefined;
  61. }
  62. if (isScrollable(el)) {
  63. return el;
  64. }
  65. if (el === document.documentElement) {
  66. return null;
  67. }
  68. } while (el = el.parentNode);
  69. return null;
  70. }
  71. function determineScrollIntention(currentCoordinate, size, threshold) {
  72. if (currentCoordinate < threshold) {
  73. return -1;
  74. }
  75. else if (size - currentCoordinate < threshold) {
  76. return 1;
  77. }
  78. return 0;
  79. }
  80. function determineDynamicVelocity(scrollIntention, currentCoordinate, size, threshold) {
  81. if (scrollIntention === -1) {
  82. return Math.abs(currentCoordinate - threshold);
  83. }
  84. else if (scrollIntention === 1) {
  85. return Math.abs(size - currentCoordinate - threshold);
  86. }
  87. return 0;
  88. }
  89. function isScrollEndReached(axis, scrollIntention, scrollBounds) {
  90. var currentScrollOffset = (axis === 0) ? (scrollBounds.scrollX) : (scrollBounds.scrollY);
  91. if (scrollIntention === 1) {
  92. var maxScrollOffset = (axis === 0) ? (scrollBounds.scrollWidth - scrollBounds.width) : (scrollBounds.scrollHeight -
  93. scrollBounds.height);
  94. return currentScrollOffset >= maxScrollOffset;
  95. }
  96. else if (scrollIntention === -1) {
  97. return (currentScrollOffset <= 0);
  98. }
  99. return true;
  100. }
  101. var _options = {
  102. threshold: 75,
  103. velocityFn: function (velocity, threshold) {
  104. var multiplier = velocity / threshold;
  105. var easeInCubic = multiplier * multiplier * multiplier;
  106. return easeInCubic * threshold;
  107. }
  108. };
  109. var _scrollIntentions = {
  110. horizontal: 0,
  111. vertical: 0
  112. };
  113. var _dynamicVelocity = {
  114. x: 0,
  115. y: 0
  116. };
  117. var _scrollAnimationFrameId;
  118. var _currentCoordinates;
  119. var _hoveredElement;
  120. var _scrollableParent;
  121. var _translateDragImageFn;
  122. function handleDragImageTranslateOverride(event, currentCoordinates, hoveredElement, translateDragImageFn) {
  123. _currentCoordinates = currentCoordinates;
  124. _translateDragImageFn = translateDragImageFn;
  125. if (_hoveredElement !== hoveredElement) {
  126. _hoveredElement = hoveredElement;
  127. _scrollableParent = findScrollableParent(_hoveredElement);
  128. }
  129. var performScrollAnimation = updateScrollIntentions(_currentCoordinates, _scrollableParent, _options.threshold, _scrollIntentions, _dynamicVelocity);
  130. if (performScrollAnimation) {
  131. scheduleScrollAnimation();
  132. }
  133. else if (!!_scrollAnimationFrameId) {
  134. window.cancelAnimationFrame(_scrollAnimationFrameId);
  135. _scrollAnimationFrameId = null;
  136. }
  137. }
  138. function scheduleScrollAnimation() {
  139. if (!!_scrollAnimationFrameId) {
  140. return;
  141. }
  142. _scrollAnimationFrameId = window.requestAnimationFrame(scrollAnimation);
  143. }
  144. function scrollAnimation() {
  145. var scrollDiffX = 0, scrollDiffY = 0, isTopLevel = isTopLevelEl(_scrollableParent);
  146. if (_scrollIntentions.horizontal !== 0) {
  147. scrollDiffX = Math.round(_options.velocityFn(_dynamicVelocity.x, _options.threshold) * _scrollIntentions.horizontal);
  148. getSetElementScroll(_scrollableParent, 0, scrollDiffX);
  149. }
  150. if (_scrollIntentions.vertical !== 0) {
  151. scrollDiffY = Math.round(_options.velocityFn(_dynamicVelocity.y, _options.threshold) * _scrollIntentions.vertical);
  152. getSetElementScroll(_scrollableParent, 1, scrollDiffY);
  153. }
  154. if (isTopLevel) {
  155. _translateDragImageFn(scrollDiffX, scrollDiffY);
  156. }
  157. else {
  158. _translateDragImageFn(0, 0);
  159. }
  160. _scrollAnimationFrameId = null;
  161. if (updateScrollIntentions(_currentCoordinates, _scrollableParent, _options.threshold, _scrollIntentions, _dynamicVelocity)) {
  162. scheduleScrollAnimation();
  163. }
  164. }
  165. function updateScrollIntentions(currentCoordinates, scrollableParent, threshold, scrollIntentions, dynamicVelocity) {
  166. if (!currentCoordinates || !scrollableParent) {
  167. return false;
  168. }
  169. var scrollableParentBounds = {
  170. x: getElementViewportOffset(scrollableParent, 0),
  171. y: getElementViewportOffset(scrollableParent, 1),
  172. width: getElementViewportSize(scrollableParent, 0),
  173. height: getElementViewportSize(scrollableParent, 1),
  174. scrollX: getSetElementScroll(scrollableParent, 0),
  175. scrollY: getSetElementScroll(scrollableParent, 1),
  176. scrollWidth: scrollableParent.scrollWidth,
  177. scrollHeight: scrollableParent.scrollHeight
  178. };
  179. var currentCoordinatesOffset = {
  180. x: currentCoordinates.x - scrollableParentBounds.x,
  181. y: currentCoordinates.y - scrollableParentBounds.y
  182. };
  183. scrollIntentions.horizontal = determineScrollIntention(currentCoordinatesOffset.x, scrollableParentBounds.width, threshold);
  184. scrollIntentions.vertical = determineScrollIntention(currentCoordinatesOffset.y, scrollableParentBounds.height, threshold);
  185. if (scrollIntentions.horizontal && isScrollEndReached(0, scrollIntentions.horizontal, scrollableParentBounds)) {
  186. scrollIntentions.horizontal = 0;
  187. }
  188. else if (scrollIntentions.horizontal) {
  189. dynamicVelocity.x = determineDynamicVelocity(scrollIntentions.horizontal, currentCoordinatesOffset.x, scrollableParentBounds.width, threshold);
  190. }
  191. if (scrollIntentions.vertical && isScrollEndReached(1, scrollIntentions.vertical, scrollableParentBounds)) {
  192. scrollIntentions.vertical = 0;
  193. }
  194. else if (scrollIntentions.vertical) {
  195. dynamicVelocity.y = determineDynamicVelocity(scrollIntentions.vertical, currentCoordinatesOffset.y, scrollableParentBounds.height, threshold);
  196. }
  197. return !!(scrollIntentions.horizontal || scrollIntentions.vertical);
  198. }
  199. var scrollBehaviourDragImageTranslateOverride = handleDragImageTranslateOverride;
  200. exports.scrollBehaviourDragImageTranslateOverride = scrollBehaviourDragImageTranslateOverride;
  201. Object.defineProperty(exports, '__esModule', { value: true });
  202. })));
  203. //# sourceMappingURL=scroll-behaviour.js.map