@adoratorio/hades
Version:
A smooth scrollbar based on Hermes, scroll down 'till hell
81 lines • 3.05 kB
JavaScript
import Boundaries from "../../Boundaries";
class VirtualRender {
context = null;
options;
lastFrame = 0;
REFLOW_THROTTLE = 100;
name = 'VirtualRender';
constructor(options) {
const defaults = {
scrollNode: document.body,
lockX: true,
lockY: false,
renderScroll: true,
infiniteScroll: false,
autoBoundaries: true,
boundaries: new Boundaries(0, 0, 0, 0),
precision: 4,
};
this.options = { ...defaults, ...options };
if (typeof this.options.scrollNode === 'undefined') {
this.options.infiniteScroll = true;
this.options.autoBoundaries = false;
}
this.options.scrollNode.style.webkitBackfaceVisibility = 'hidden';
this.options.scrollNode.style.backfaceVisibility = 'hidden';
}
register(context) {
this.context = context;
}
preFrame(context) {
if (this.options.autoBoundaries) {
const now = performance.now();
if (now - this.lastFrame > this.REFLOW_THROTTLE) {
const containerRect = this.options.scrollNode.getBoundingClientRect();
this.options.boundaries = new Boundaries(0, containerRect.width - window.innerWidth, 0, containerRect.height - window.innerHeight);
this.lastFrame = now;
}
}
}
render(context) {
const { precision } = this.options;
const px = parseFloat((this.options.lockX ? 0 : context.amount.x * -1).toFixed(precision));
const py = parseFloat((this.options.lockY ? 0 : context.amount.y * -1).toFixed(precision));
if (this.options.renderScroll) {
this.options.scrollNode.style.transform = `translate3d(${px}px,${py}px,0)`;
}
}
scroll(context) {
if (!this.options.infiniteScroll) {
context.internalTemp = {
x: Math.min(Math.max(context.internalTemp.x, this.options.boundaries.min.x), this.options.boundaries.max.x),
y: Math.min(Math.max(context.internalTemp.y, this.options.boundaries.min.y), this.options.boundaries.max.y),
};
}
}
startRender() {
this.options.renderScroll = true;
}
stopRender() {
this.options.renderScroll = false;
}
get boundaries() {
return this.options.boundaries;
}
set infiniteScroll(infiniteScroll) {
this.options.infiniteScroll = infiniteScroll;
}
set boundaries(boundaries) {
this.options.boundaries = boundaries;
if (this.context !== null) {
if (this.context.amount.y > this.options.boundaries.max.y) {
this.context.scrollTo({ y: this.options.boundaries.max.y }, 0);
}
if (this.context.amount.x > this.options.boundaries.max.x) {
this.context.scrollTo({ x: this.options.boundaries.max.x }, 0);
}
}
}
}
export default VirtualRender;
//# sourceMappingURL=index.js.map