@adoratorio/hades
Version:
A smooth scrollbar based on Hermes, scroll down 'till hell
97 lines • 3.67 kB
JavaScript
import { isScrollableElement } from "../../utils";
import Boundaries from "../../Boundaries";
class LenisRender {
context = null;
options;
nativeScrollHandler;
isValidEvent = false;
interval = null;
name = 'LenisRender';
constructor(options) {
const defaults = {
scrollNode: window,
renderScroll: true,
};
this.options = { ...defaults, ...options };
this.nativeScrollHandler = (e) => this.nativeScroll(e);
if (typeof this.options.scrollNode === 'undefined') {
throw new Error('Invalid Scroll Node for Lenis Renderer');
}
this.options.scrollNode.addEventListener('scroll', this.nativeScrollHandler);
}
register(context) {
this.context = context;
}
wheel(context, event) {
if (event.originalEvent.target.parentNode !== this.options.scrollNode &&
isScrollableElement(event.originalEvent.target))
return true;
if (event.type === 'wheel') {
event.originalEvent.preventDefault();
this.isValidEvent = true;
}
else {
this.isValidEvent = false;
}
return false;
}
render(context) {
if (this.options.renderScroll && this.isValidEvent) {
this.options.scrollNode.scrollTo(context.amount.x, context.amount.y);
}
}
scroll(context, event) {
const isWindow = this.options.scrollNode === window;
const node = (isWindow ? document.body : this.options.scrollNode);
const bound = {
x: node.scrollWidth - (isWindow ? window.innerWidth : node.clientWidth),
y: node.scrollHeight - (isWindow ? window.innerHeight : node.clientHeight),
};
context.internalTemp = {
x: Math.min(Math.max(context.internalTemp.x, 0), bound.x),
y: Math.min(Math.max(context.internalTemp.y, 0), bound.y),
};
}
nativeScroll(event) {
if (this.context && !this.isValidEvent) {
const propX = this.options.scrollNode === window ? 'scrollX' : 'scrollLeft';
const propY = this.options.scrollNode === window ? 'scrollY' : 'scrollTop';
this.context.scrollTo({
x: this.options.scrollNode[propX],
y: this.options.scrollNode[propY],
}, 0, true);
}
if (window) {
if (this.interval)
window.clearInterval(this.interval);
this.interval = window.setTimeout(() => { this.isValidEvent = false; }, 100);
}
}
scrollTo(context) {
this.isValidEvent = true;
}
destroy(context) {
this.options.scrollNode.removeEventListener('scroll', this.nativeScrollHandler);
}
startRender() {
this.options.renderScroll = true;
}
stopRender() {
this.options.renderScroll = false;
}
swapScrollNode(node) {
node.addEventListener('scroll', this.nativeScrollHandler);
this.options.scrollNode.removeEventListener('scroll', this.nativeScrollHandler);
this.options.scrollNode = node;
}
get boundaries() {
if (this.options.scrollNode instanceof Window) {
return new Boundaries(0, document.body.scrollWidth - document.body.clientWidth, 0, document.body.scrollHeight - document.body.clientHeight);
}
else {
return new Boundaries(0, this.options.scrollNode.scrollLeft - this.options.scrollNode.clientWidth, 0, this.options.scrollNode.scrollHeight - this.options.scrollNode.clientHeight);
}
}
}
export default LenisRender;
//# sourceMappingURL=index.js.map