|
1 | 1 | # Nuxt Lenis
|
2 | 2 |
|
3 |
| -This is a Nuxt wrapper for [Lenis](https://lenis.studiofreight.com/) by [Studio Freight](https://studiofreight.com/). Thank them for the incredible tool. |
| 3 | +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. |
4 | 4 |
|
| 5 | +> **Version 2 Notice:** |
| 6 | +> In version 2, the module has been refactored to centrally manage multiple Lenis instances via a Nuxt plugin. Use the provided composable (`useLenis`) for accessing instance methods and reactive scroll state. The component expects an `onScroll` prop for scroll callbacks (instead of using emits). |
5 | 7 |
|
6 |
| -### Please Note |
7 |
| -Because of how Vue/Nuxt `useState` works, we have to recreate the `ScrollState` to a new object. We are porting over all fields we find necessary as you can also grab `Lenis` for all methods and attributes. |
8 |
| - |
| 8 | +--- |
9 | 9 |
|
10 | 10 | ## Getting Started
|
11 | 11 |
|
12 |
| -1. `yarn add nuxt-lenis` |
13 |
| -2. Add `nuxt-lenis` to your modules in nuxt.config |
14 |
| -3. In your `app.vue` file, wrap the nuxt page in the lenis component |
| 12 | +1. **Install the package:** |
| 13 | + |
| 14 | + ```bash |
| 15 | + yarn add nuxt-lenis |
| 16 | + ``` |
| 17 | + |
| 18 | +2. **Add the module in your `nuxt.config`:** |
| 19 | + |
| 20 | + ```js |
| 21 | + export default { |
| 22 | + modules: [ |
| 23 | + 'nuxt-lenis' |
| 24 | + ] |
| 25 | + } |
15 | 26 | ```
|
| 27 | + |
| 28 | +3. **Wrap your page with the Lenis component in `app.vue`:** |
| 29 | + |
| 30 | + ```vue |
| 31 | + <template> |
16 | 32 | <lenis
|
17 | 33 | :options="LenisOptions"
|
18 |
| - @initiated="foo" |
19 |
| - @scroll="fooBar" |
| 34 | + onScroll="handleScroll" |
20 | 35 | >
|
21 | 36 | <NuxtPage />
|
22 | 37 | </lenis>
|
| 38 | + </template> |
| 39 | +
|
| 40 | + <script setup lang="ts"> |
| 41 | + const handleScroll = (scrollData: any) => { |
| 42 | + console.log("Scroll event:", scrollData); |
| 43 | + } |
| 44 | + </script> |
23 | 45 | ```
|
24 | 46 |
|
25 |
| -## Composable |
| 47 | +--- |
| 48 | + |
| 49 | +## Component Usage |
26 | 50 |
|
| 51 | +The `<lenis>` component (located at `src/runtime/components/Lenis.vue`) accepts the following props: |
| 52 | + |
| 53 | +- **id** (String, default: `"default"`): A unique identifier for your Lenis instance. |
| 54 | +- **root** (Boolean, default: `true`): Determines if the window should be used as the scroll container. |
| 55 | +- **options** (Object): Lenis options (e.g., `duration`, `autoRaf`, `direction`). |
| 56 | +- **onScroll** (Function): Callback fired whenever a scrolling event is received. |
| 57 | + |
| 58 | +Example: |
| 59 | + |
| 60 | +```vue |
| 61 | +<template> |
| 62 | + <lenis id="default" :options="LenisOptions" onScroll="handleScroll"> |
| 63 | + <NuxtPage /> |
| 64 | + </lenis> |
| 65 | +</template> |
| 66 | +
|
| 67 | +<script setup lang="ts"> |
| 68 | +const LenisOptions = { |
| 69 | + smooth: true, |
| 70 | + duration: 1.2, |
| 71 | + autoRaf: true, |
| 72 | + direction: 'vertical' |
| 73 | +} |
| 74 | +
|
| 75 | +const handleScroll = (data: any) => { |
| 76 | + console.log("Scroll detected:", data); |
| 77 | +} |
| 78 | +</script> |
27 | 79 | ```
|
28 |
| - <!-- You can pass in true or false into useLenis if you want to use more than one lenis instance. Defaults to single instance (true) --> |
29 |
| - const {scrollState, lenis} = useLenis() |
30 | 80 |
|
31 |
| - watch(scrollState, (val) => { |
32 |
| - console.log("scrollState", val); |
33 |
| - },{deep:true}); |
| 81 | +--- |
| 82 | + |
| 83 | +## Composable Usage |
| 84 | + |
| 85 | +Access the reactive Lenis API via the composable. By default, `useLenis()` returns the following properties: |
34 | 86 |
|
| 87 | +- **createLenis**: Function to create and register a Lenis instance. |
| 88 | +- **getLenis**: Function that returns the Lenis instance (or `null` if not found). |
| 89 | +- **destroyLenis**: Function to destroy an instance. |
| 90 | +- **scrollState**: Function to access the reactive scroll state of an instance. |
| 91 | +- **watchScrollState**: Function to watch changes to the scroll state. |
| 92 | + |
| 93 | +### Single Instance Usage |
| 94 | + |
| 95 | +For many cases, a single instance is sufficient: |
| 96 | + |
| 97 | +```vue |
| 98 | +<script setup lang="ts"> |
| 99 | +import { watch } from 'vue'; |
| 100 | +import { useLenis } from '#imports'; |
| 101 | +
|
| 102 | +const { scrollState, getLenis } = useLenis(); |
| 103 | +
|
| 104 | +// Example: retrieve default instance |
| 105 | +const instance = getLenis(); // returns the Lenis instance or null |
| 106 | +
|
| 107 | +// Watch scroll state changes |
| 108 | +watch(scrollState, (state) => { |
| 109 | + console.log("Scroll state:", state); |
| 110 | +}, { deep: true }); |
| 111 | +</script> |
35 | 112 | ```
|
| 113 | + |
36 | 114 | ### Multiple Instances
|
37 |
| -If you have multiple instances of Lenis you can get each one via an ID set ont he Lenis component |
38 |
| -``` |
39 |
| - <lenis id="base" > |
| 115 | + |
| 116 | +If you need multiple instances, pass `false` (or use different IDs on each `<lenis>` component) and access them by ID: |
| 117 | + |
| 118 | +```vue |
| 119 | +<template> |
| 120 | + <lenis id="main"> |
40 | 121 | <NuxtPage />
|
41 | 122 | </lenis>
|
42 |
| - |
43 |
| - <lenis id="modal" > |
| 123 | + <lenis id="modal"> |
44 | 124 | <NuxtPage />
|
45 | 125 | </lenis>
|
| 126 | +</template> |
| 127 | +
|
| 128 | +<script setup lang="ts"> |
| 129 | +import { useLenis } from '#imports'; |
46 | 130 |
|
47 |
| - <!-- script --> |
48 |
| - const {scrollState, lenis} = useLenis(false) |
| 131 | +// Using multiple instance mode: |
| 132 | +const { scrollState, getLenis } = useLenis(false); |
49 | 133 |
|
50 |
| - scrollState.value.base |
51 |
| - lenis.base |
52 |
| - scrollState.value.modal |
53 |
| - lenis.modal |
| 134 | +// Access the instances by ID |
| 135 | +const mainInstance = getLenis("main"); |
| 136 | +const modalInstance = getLenis("modal"); |
54 | 137 |
|
| 138 | +// Example: Log scroll states for each instance |
| 139 | +console.log("Main scroll state:", scrollState("main")); |
| 140 | +console.log("Modal scroll state:", scrollState("modal")); |
| 141 | +</script> |
55 | 142 | ```
|
| 143 | + |
| 144 | +--- |
| 145 | + |
| 146 | +## Plugin API |
| 147 | + |
| 148 | +The Nuxt plugin (located at `src/runtime/plugin.ts`) exposes the following methods: |
| 149 | + |
| 150 | +- **createLenis(id, options?)** |
| 151 | + Creates a new Lenis instance for a given ID and registers it. |
| 152 | + |
| 153 | +- **getLenis(id?)** |
| 154 | + Retrieves a Lenis instance by its ID (or the default instance if none is specified). |
| 155 | + |
| 156 | +- **destroyLenis(id)** |
| 157 | + Destroys the specified Lenis instance and cleans up its associated state. |
| 158 | + |
| 159 | +- **getScrollState(id?)** |
| 160 | + Returns the current scroll state for the specified instance, which is updated reactively. |
| 161 | + |
| 162 | +The composable (`useLenis`) wraps these methods and provides a streamlined API for your components. |
| 163 | + |
| 164 | +--- |
| 165 | + |
| 166 | +Happy scrolling! |
0 commit comments