@adoratorio/hades
Version:
A smooth scrollbar based on Hermes, scroll down 'till hell
95 lines • 3.77 kB
JavaScript
class DragAndScroll {
context = null;
options;
eventNode = null;
mouseDownHandler;
mouseMoveHandler;
mouseUpHandler;
isDragging = false;
prevPoint = { x: 0, y: 0 };
name = 'DragAndScroll';
constructor(options) {
const defaults = {
proxyNode: null,
changeCursor: false,
multiplier: 1,
autoHandleEvents: true,
smooth: true,
invert: false,
};
this.options = { ...defaults, ...options };
this.mouseDownHandler = (e) => this.mouseDown(e);
this.mouseMoveHandler = (e) => this.mouseMove(e);
this.mouseUpHandler = (e) => this.mouseUp(e);
}
register(context) {
this.context = context;
if (this.options.autoHandleEvents)
this.attach();
}
attach() {
if (this.isTouchDevice)
return;
let node = this.context?.root;
if (this.options.proxyNode)
node = this.options.proxyNode;
if (typeof node === 'undefined' || node === null) {
throw new Error('No context or proxyNode specified for DragAndScroll plugin');
}
this.eventNode = node;
if (this.eventNode === window)
this.options.changeCursor = false;
if (this.options.changeCursor)
this.eventNode.style.cursor = 'grab';
this.eventNode?.addEventListener('mousedown', this.mouseDownHandler);
this.eventNode?.addEventListener('mousemove', this.mouseMoveHandler);
this.eventNode?.addEventListener('mouseup', this.mouseUpHandler);
this.eventNode?.addEventListener('mouseleave', this.mouseUpHandler);
}
detach() {
this.eventNode?.removeEventListener('mousedown', this.mouseDownHandler);
this.eventNode?.removeEventListener('mousemove', this.mouseMoveHandler);
this.eventNode?.removeEventListener('mouseup', this.mouseUpHandler);
this.eventNode?.removeEventListener('mouseleave', this.mouseUpHandler);
}
mouseDown(event) {
this.isDragging = true;
this.prevPoint = { x: event.clientX, y: event.clientY };
if (this.options.changeCursor)
this.eventNode.style.cursor = 'grabbing';
}
mouseMove(event) {
const point = { x: event.clientX, y: event.clientY };
if (this.isDragging && this.context !== null) {
const delta = {
x: (this.prevPoint.x - point.x) * this.options.multiplier,
y: (this.prevPoint.y - point.y) * this.options.multiplier,
};
let tempAmount = {
x: this.context.internalAmount.x + (!this.options.invert ? delta.x : delta.y),
y: this.context.internalAmount.y + (!this.options.invert ? delta.y : delta.x),
};
if (this.context && this.context.getRenderer()) {
const renderer = this.context.getRenderer();
tempAmount.x = Math.min(Math.max(renderer.boundaries.min.x, tempAmount.x), renderer.boundaries.max.x);
tempAmount.y = Math.min(Math.max(renderer.boundaries.min.y, tempAmount.y), renderer.boundaries.max.y);
}
this.context?.scrollTo(tempAmount, this.options.smooth ? this.context.easing.duration : 0);
}
this.prevPoint = point;
}
mouseUp(event) {
this.isDragging = false;
if (this.options.changeCursor)
this.eventNode.style.cursor = 'grab';
}
destroy() {
if (this.options.autoHandleEvents)
this.detach();
}
get isTouchDevice() {
return (('ontouchstart' in window) || (navigator.maxTouchPoints > 0));
}
}
export default DragAndScroll;
//# sourceMappingURL=index.js.map