nuxt-lenis
Version:
This is a Nuxt wrapper for [Lenis](https://lenis.studiofreight.com/) (by [Studio Freight](https://studiofreight.com/)) – providing smooth scrolling with support for multiple instances in a type-safe and reactive way.
87 lines (86 loc) • 2.64 kB
JavaScript
import { defineNuxtPlugin } from "#app";
import { reactive, ref } from "vue";
import { Lenis } from "#imports";
export default defineNuxtPlugin((nuxtApp) => {
const instances = reactive(/* @__PURE__ */ new Map());
const scrollStates = reactive(/* @__PURE__ */ new Map());
const defaultInstance = ref(null);
const createLenis = (id, options = {}) => {
if (instances.has(id)) {
console.warn(`[Lenis] Instance with ID "${id}" already exists.`);
return instances.get(id);
}
const lenis = new Lenis(options);
instances.set(id, lenis);
scrollStates.set(id, {
scroll: 0,
animatedScroll: 0,
velocity: 0,
progress: 0,
limit: 0,
isScrolling: false,
isStopped: true,
isTouching: false,
isHorizontal: false,
isLocked: false,
isSmooth: false,
rootElement: null,
direction: 1,
lastVelocity: 0,
targetScroll: 0
});
lenis.on("scroll", (scrollData) => {
scrollStates.set(id, {
limit: scrollData.limit,
animatedScroll: scrollData.animatedScroll,
scroll: scrollData.scroll,
velocity: scrollData.velocity,
progress: scrollData.progress,
isScrolling: scrollData.isScrolling,
isStopped: scrollData.isStopped,
isTouching: scrollData.isTouching,
isHorizontal: scrollData.isHorizontal,
isLocked: scrollData.isLocked,
isSmooth: scrollData.isSmooth,
rootElement: scrollData.rootElement,
direction: scrollData.direction,
lastVelocity: scrollData.lastVelocity,
targetScroll: scrollData.targetScroll
});
});
if (!defaultInstance.value) {
defaultInstance.value = id;
}
return lenis;
};
const getLenis = (id) => {
const targetId = id || defaultInstance.value;
if (!targetId || !instances.has(targetId)) {
console.warn(`[Lenis] No instance found for ID "${targetId}".`);
return null;
}
return instances.get(targetId);
};
const destroyLenis = (id) => {
if (!instances.has(id)) {
console.warn(`[Lenis] No instance found for ID "${id}".`);
return;
}
instances.get(id)?.destroy();
instances.delete(id);
scrollStates.delete(id);
if (defaultInstance.value === id) {
defaultInstance.value = instances.size > 0 ? Array.from(instances.keys())[0] : null;
}
};
const getScrollState = (id) => {
const targetId = id || defaultInstance.value;
return scrollStates.get(targetId) || null;
};
nuxtApp.provide("lenis", {
createLenis,
getLenis,
destroyLenis,
getScrollState
});
});