{"version":3,"file":"scroll-behaviour.js","sources":["scroll-behaviour.ts"],"sourcesContent":["//\n\nimport { DragImageTranslateOverrideFn } from \"./index\";\nimport { Point } from \"./internal/dom-utils\";\n\ninterface ScrollIntentions {\n horizontal:ScrollIntention;\n vertical:ScrollIntention;\n}\n\ninterface IScrollBounds {\n x:number;\n y:number;\n width:number;\n height:number;\n scrollX:number;\n scrollY:number;\n scrollHeight:number;\n scrollWidth:number;\n}\n\nconst enum ScrollIntention {\n NONE = 0,\n LEFT_OR_TOP = -1,\n RIGHT_OR_BOTTOM = 1\n}\n\nconst enum ScrollAxis {\n HORIZONTAL,\n VERTICAL\n}\n\nfunction isTopLevelEl( el:HTMLElement ):boolean {\n\n return (el === document.body || el === document.documentElement);\n}\n\nfunction getElementViewportOffset( el:HTMLElement, axis:ScrollAxis ) {\n let offset:number;\n\n if( isTopLevelEl( el ) ) {\n offset = (axis === ScrollAxis.HORIZONTAL) ? el.clientLeft : el.clientTop;\n }\n else {\n const bounds = el.getBoundingClientRect();\n offset = (axis === ScrollAxis.HORIZONTAL) ? bounds.left : bounds.top;\n }\n\n return offset;\n}\n\nfunction getElementViewportSize( el:HTMLElement, axis:ScrollAxis ) {\n let size:number;\n\n if( isTopLevelEl( el ) ) {\n size = (axis === ScrollAxis.HORIZONTAL) ? window.innerWidth : window.innerHeight;\n }\n else {\n size = (axis === ScrollAxis.HORIZONTAL) ? el.clientWidth : el.clientHeight;\n }\n\n return size;\n}\n\nfunction getSetElementScroll( el:HTMLElement, axis:ScrollAxis, scroll?:number ) {\n const prop = (axis === ScrollAxis.HORIZONTAL) ? \"scrollLeft\" : \"scrollTop\";\n\n // abstracting away compatibility issues on scroll properties of document/body\n const isTopLevel = isTopLevelEl( el );\n\n if( arguments.length === 2 ) {\n\n if( isTopLevel ) {\n return document.body[ prop ] || document.documentElement[ prop ];\n }\n\n return el[ prop ];\n }\n\n if( isTopLevel ) {\n document.documentElement[ prop ] += scroll;\n document.body[ prop ] += scroll;\n }\n else {\n el[ prop ] += scroll;\n }\n}\n\n//TODO check if scroll end is reached according to scroll intention? this is needed to implement scroll chaining\nfunction isScrollable( el:HTMLElement ):boolean {\n const cs = getComputedStyle( el );\n\n if( el.scrollHeight > el.clientHeight && (cs.overflowY === \"scroll\" || cs.overflowY === \"auto\") ) {\n return true;\n }\n\n if( el.scrollWidth > el.clientWidth && (cs.overflowX === \"scroll\" || cs.overflowX === \"auto\") ) {\n return true;\n }\n\n return false;\n}\n\nfunction findScrollableParent( el:HTMLElement ):HTMLElement {\n do {\n if( !el ) {\n return undefined;\n }\n if( isScrollable( el ) ) {\n return el;\n }\n if( el === document.documentElement ) {\n return null;\n }\n } while( el = el.parentNode );\n return null;\n}\n\nfunction determineScrollIntention( currentCoordinate:number, size:number, threshold:number ):ScrollIntention {\n\n // LEFT / TOP\n if( currentCoordinate < threshold ) {\n return ScrollIntention.LEFT_OR_TOP;\n }\n // RIGHT / BOTTOM\n else if( size - currentCoordinate < threshold ) {\n return ScrollIntention.RIGHT_OR_BOTTOM;\n }\n // NONE\n return ScrollIntention.NONE;\n}\n\nfunction determineDynamicVelocity( scrollIntention:ScrollIntention, currentCoordinate:number, size:number, threshold:number ):number {\n\n if( scrollIntention === ScrollIntention.LEFT_OR_TOP ) {\n\n return Math.abs( currentCoordinate - threshold );\n }\n else if( scrollIntention === ScrollIntention.RIGHT_OR_BOTTOM ) {\n\n return Math.abs( size - currentCoordinate - threshold );\n }\n\n return 0;\n}\n\nfunction isScrollEndReached( axis:ScrollAxis, scrollIntention:ScrollIntention, scrollBounds:IScrollBounds ) {\n\n const currentScrollOffset = (axis === ScrollAxis.HORIZONTAL) ? (scrollBounds.scrollX) : (scrollBounds.scrollY);\n\n // wants to scroll to the right/bottom\n if( scrollIntention === ScrollIntention.RIGHT_OR_BOTTOM ) {\n\n const maxScrollOffset = (axis === ScrollAxis.HORIZONTAL) ? (scrollBounds.scrollWidth - scrollBounds.width) : (scrollBounds.scrollHeight -\n scrollBounds.height);\n\n // is already at the right/bottom edge\n return currentScrollOffset >= maxScrollOffset;\n }\n // wants to scroll to the left/top\n else if( scrollIntention === ScrollIntention.LEFT_OR_TOP ) {\n\n // is already at left/top edge\n return (currentScrollOffset <= 0);\n }\n // no scroll\n return true;\n}\n\n//\n\nlet _options:ScrollOptions = {\n threshold: 75,\n // simplified cubic-ease-in function\n velocityFn: function( velocity:number, threshold:number ) {\n const multiplier = velocity / threshold;\n const easeInCubic = multiplier * multiplier * multiplier;\n return easeInCubic * threshold;\n }\n};\n\nlet _scrollIntentions:ScrollIntentions = {\n horizontal: ScrollIntention.NONE,\n vertical: ScrollIntention.NONE\n};\n\nlet _dynamicVelocity:Point = {\n x: 0,\n y: 0\n};\n\nlet _scrollAnimationFrameId:any;\nlet _currentCoordinates:Point;\nlet _hoveredElement:HTMLElement;\nlet _scrollableParent:HTMLElement;\nlet _translateDragImageFn:( offsetX:number, offsetY:number ) => void;\n\n/**\n * core handler function\n */\nfunction handleDragImageTranslateOverride( event:TouchEvent,\n currentCoordinates:Point,\n hoveredElement:HTMLElement,\n translateDragImageFn:( scrollDiffX:number, scrollDiffY:number ) => void ):void {\n\n _currentCoordinates = currentCoordinates;\n _translateDragImageFn = translateDragImageFn;\n\n // update parent if hovered element changed\n if( _hoveredElement !== hoveredElement ) {\n\n _hoveredElement = hoveredElement;\n _scrollableParent = findScrollableParent( _hoveredElement );\n }\n\n // update scroll intention and check if we should scroll at all\n //TODO implement scroll chaining? if scroll end is reached continue to look for scrollable parent\n const performScrollAnimation = updateScrollIntentions( _currentCoordinates, _scrollableParent, _options.threshold, _scrollIntentions, _dynamicVelocity );\n\n // no animation in progress but scroll is intended\n if( performScrollAnimation ) {\n\n // setup scroll animation frame\n scheduleScrollAnimation();\n }\n else if( !!_scrollAnimationFrameId ) {\n\n window.cancelAnimationFrame( _scrollAnimationFrameId );\n _scrollAnimationFrameId = null;\n }\n}\n\n//\n\nfunction scheduleScrollAnimation() {\n\n // prevent scheduling when already scheduled\n if( !!_scrollAnimationFrameId ) {\n\n return;\n }\n\n _scrollAnimationFrameId = window.requestAnimationFrame( scrollAnimation );\n}\n\nfunction scrollAnimation() {\n\n let scrollDiffX = 0,\n scrollDiffY = 0,\n isTopLevel = isTopLevelEl( _scrollableParent );\n\n if( _scrollIntentions.horizontal !== ScrollIntention.NONE ) {\n\n scrollDiffX = Math.round( _options.velocityFn( _dynamicVelocity.x, _options.threshold ) * _scrollIntentions.horizontal );\n getSetElementScroll( _scrollableParent, ScrollAxis.HORIZONTAL, scrollDiffX );\n }\n\n if( _scrollIntentions.vertical !== ScrollIntention.NONE ) {\n\n scrollDiffY = Math.round( _options.velocityFn( _dynamicVelocity.y, _options.threshold ) * _scrollIntentions.vertical );\n getSetElementScroll( _scrollableParent, ScrollAxis.VERTICAL, scrollDiffY );\n }\n\n if( isTopLevel ) {\n // on top level element scrolling we need to translate the drag image as much as we scroll\n _translateDragImageFn( scrollDiffX, scrollDiffY );\n }\n else {\n // just scroll the container and update the drag image position without offset\n _translateDragImageFn( 0, 0 );\n }\n\n // reset to make sure we can re-schedule scroll animation\n _scrollAnimationFrameId = null;\n\n // check if we should continue scrolling\n //TODO implement scroll chaining? if scroll end is reached continue to look for scrollable parent\n if( updateScrollIntentions( _currentCoordinates, _scrollableParent, _options.threshold, _scrollIntentions, _dynamicVelocity ) ) {\n\n // re-schedule animation frame callback\n scheduleScrollAnimation();\n }\n}\n\n//\n\n//\n\nfunction updateScrollIntentions( currentCoordinates:Point,\n scrollableParent:HTMLElement,\n threshold:number,\n scrollIntentions:ScrollIntentions,\n dynamicVelocity:Point ):boolean {\n\n if( !currentCoordinates || !scrollableParent ) {\n\n // when coordinates become undefined drag operation stopped. stop scrolling also.\n return false;\n }\n\n const scrollableParentBounds:IScrollBounds = {\n x: getElementViewportOffset( scrollableParent, ScrollAxis.HORIZONTAL ),\n y: getElementViewportOffset( scrollableParent, ScrollAxis.VERTICAL ),\n width: getElementViewportSize( scrollableParent, ScrollAxis.HORIZONTAL ),\n height: getElementViewportSize( scrollableParent, ScrollAxis.VERTICAL ),\n scrollX: getSetElementScroll( scrollableParent, ScrollAxis.HORIZONTAL ),\n scrollY: getSetElementScroll( scrollableParent, ScrollAxis.VERTICAL ),\n scrollWidth: scrollableParent.scrollWidth,\n scrollHeight: scrollableParent.scrollHeight\n };\n\n const currentCoordinatesOffset = {\n x: currentCoordinates.x - scrollableParentBounds.x,\n y: currentCoordinates.y - scrollableParentBounds.y\n };\n\n scrollIntentions.horizontal = determineScrollIntention( currentCoordinatesOffset.x, scrollableParentBounds.width, threshold );\n scrollIntentions.vertical = determineScrollIntention( currentCoordinatesOffset.y, scrollableParentBounds.height, threshold );\n\n if( scrollIntentions.horizontal && isScrollEndReached( ScrollAxis.HORIZONTAL, scrollIntentions.horizontal, scrollableParentBounds ) ) {\n\n // if scroll end is reached, reset to none\n scrollIntentions.horizontal = ScrollIntention.NONE;\n }\n else if( scrollIntentions.horizontal ) {\n\n dynamicVelocity.x = determineDynamicVelocity( scrollIntentions.horizontal, currentCoordinatesOffset.x, scrollableParentBounds.width, threshold );\n }\n\n if( scrollIntentions.vertical && isScrollEndReached( ScrollAxis.VERTICAL, scrollIntentions.vertical, scrollableParentBounds ) ) {\n\n // if scroll end is reached, reset to none\n scrollIntentions.vertical = ScrollIntention.NONE;\n }\n else if( scrollIntentions.vertical ) {\n\n dynamicVelocity.y = determineDynamicVelocity( scrollIntentions.vertical, currentCoordinatesOffset.y, scrollableParentBounds.height, threshold );\n }\n\n return !!(scrollIntentions.horizontal || scrollIntentions.vertical);\n}\n\n//\n\n//\n\nexport interface ScrollOptions {\n // threshold in px. when distance between scrollable element edge and touch position is smaller start programmatic scroll.\n // defaults to 75px\n threshold?:number;\n // function to customize the scroll velocity\n // velocity param: distance to scrollable element edge\n // threshold: the threshold used to determine when scrolling should start\n // defaults to cubic-ease-in.\n velocityFn:( velocity:number, threshold:number ) => number;\n}\n\nexport const scrollBehaviourDragImageTranslateOverride:DragImageTranslateOverrideFn = handleDragImageTranslateOverride;\n\n//\n"],"names":[],"mappings":"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"}