All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
package.dist.delegate.ScrollEnablement.js Maven / Gradle / Ivy
import { supportsTouch } from "../Device.js";
import EventProvider from "../EventProvider.js";
import scroll from "../animations/scroll.js";
const scrollEventName = "scroll";
const touchEndEventName = supportsTouch() ? "touchend" : "mouseup";
class ScrollEnablement extends EventProvider {
constructor(containerComponent) {
super();
this.supportsTouch = supportsTouch();
this.containerComponent = containerComponent;
this.mouseMove = this.ontouchmove.bind(this);
this.mouseUp = this.ontouchend.bind(this);
this.touchStart = this.ontouchstart.bind(this);
this.supportsTouch = supportsTouch();
// On Android devices touchmove is thrown one more time than neccessary (together with touchend)
// so we have to cache the previus coordinates in order to provide correct parameters in the
// event for Android
this.cachedValue = { dragX: 0, dragY: 0 };
// In components like Carousel you need to know if the user has clicked on something or swiped
// in order to throw the needed event or not
this.startX = 0;
this.startY = 0;
if (this.supportsTouch) {
containerComponent.addEventListener("touchstart", this.touchStart, { passive: true });
containerComponent.addEventListener("touchmove", this.mouseMove, { passive: true });
containerComponent.addEventListener("touchend", this.mouseUp, { passive: true });
}
else {
containerComponent.addEventListener("mousedown", this.touchStart, { passive: true });
}
}
set scrollContainer(container) {
this._container = container;
}
get scrollContainer() {
return this._container;
}
/**
* Scrolls the container to the left/top position, retrying retryCount times, if the container is not yet painted
*
* @param left
* @param top
* @param retryCount
* @param retryInterval
* @returns {Promise} resolved when scrolled successfully
*/
async scrollTo(left, top, retryCount = 0, retryInterval = 0) {
let containerPainted = this.scrollContainer.clientHeight > 0 && this.scrollContainer.clientWidth > 0;
/* eslint-disable no-loop-func, no-await-in-loop */
while (!containerPainted && retryCount > 0) {
await new Promise(resolve => {
setTimeout(() => {
containerPainted = this.scrollContainer.clientHeight > 0 && this.scrollContainer.clientWidth > 0;
retryCount--;
resolve();
}, retryInterval);
});
}
/* eslint-disable no-loop-func, no-await-in-loop */
this._container.scrollLeft = left;
this._container.scrollTop = top;
}
move(dx, dy, disableAnimation) {
if (disableAnimation) {
this._container.scrollLeft += dx;
this._container.scrollTop += dy;
return;
}
if (this._container) {
return scroll(this._container, dx, dy);
}
}
getScrollLeft() {
return this._container.scrollLeft;
}
getScrollTop() {
return this._container.scrollTop;
}
_isTouchInside(event) {
let touch = null;
if (this.supportsTouch && event instanceof TouchEvent) {
touch = event.touches[0];
}
const rect = this._container.getBoundingClientRect();
const x = this.supportsTouch ? touch.clientX : event.x;
const y = this.supportsTouch ? touch.clientY : event.y;
return x >= rect.left && x <= rect.right
&& y >= rect.top && y <= rect.bottom;
}
ontouchstart(event) {
let touch = null;
if (this.supportsTouch && event instanceof TouchEvent) {
touch = event.touches[0];
}
if (!touch) {
document.addEventListener("mouseup", this.mouseUp, { passive: true });
document.addEventListener("mousemove", this.mouseMove, { passive: true });
}
else {
// Needed only on mobile
this.startX = touch.pageX;
this.startY = touch.pageY;
}
if (touch) {
this._prevDragX = touch.pageX;
this._prevDragY = touch.pageY;
}
if (event instanceof MouseEvent) {
this._prevDragX = event.x;
this._prevDragY = event.y;
}
this._canScroll = this._isTouchInside(event);
}
ontouchmove(event) {
if (!this._canScroll) {
return;
}
const container = this._container;
const touch = this.supportsTouch ? event.touches[0] : null;
const dragX = this.supportsTouch ? touch.pageX : event.x;
const dragY = this.supportsTouch ? touch.pageY : event.y;
container.scrollLeft += this._prevDragX - dragX;
container.scrollTop += this._prevDragY - dragY;
this.fireEvent(scrollEventName, {
isLeft: dragX > this._prevDragX,
isRight: dragX < this._prevDragX,
});
this.cachedValue.dragX = this._prevDragX;
this.cachedValue.dragY = this._prevDragY;
this._prevDragX = dragX;
this._prevDragY = dragY;
}
ontouchend(event) {
if (this.supportsTouch) {
const deltaX = Math.abs(event.changedTouches[0].pageX - this.startX);
const deltaY = Math.abs(event.changedTouches[0].pageY - this.startY);
if (deltaX < 10 && deltaY < 10) {
return;
}
}
if (!this._canScroll) {
return;
}
const container = this._container;
const dragX = this.supportsTouch ? event.changedTouches[0].pageX : event.x;
const dragY = this.supportsTouch ? event.changedTouches[0].pageY : event.y;
container.scrollLeft += this._prevDragX - dragX;
container.scrollTop += this._prevDragY - dragY;
const useCachedValues = dragX === this._prevDragX;
const _dragX = useCachedValues ? this.cachedValue.dragX : dragX;
// const _dragY = useCachedValues ? this.cachedValue.dragY : dragY; add if needed
this.fireEvent(touchEndEventName, {
isLeft: _dragX < this._prevDragX,
isRight: _dragX > this._prevDragX,
});
this._prevDragX = dragX;
this._prevDragY = dragY;
if (!this.supportsTouch) {
document.removeEventListener("mousemove", this.mouseMove);
document.removeEventListener("mouseup", this.mouseUp);
}
}
}
export default ScrollEnablement;
//# sourceMappingURL=ScrollEnablement.js.map