@studio-freight/lenis v1.0.42
Introduction
This is our take on smooth scroll, lightweight, hard-working, smooth as butter scroll. See Demo.
Installation
JavaScript
using a package manager:
npm i @studio-freight/lenis
import Lenis from '@studio-freight/lenis'
using scripts:
<script src="https://unpkg.com/@studio-freight/lenis@1.0.42/dist/lenis.min.js"></script>
Setup
Basic:
const lenis = new Lenis()
lenis.on('scroll', (e) => {
console.log(e)
})
function raf(time) {
lenis.raf(time)
requestAnimationFrame(raf)
}
requestAnimationFrame(raf)
GSAP ScrollTrigger:
const lenis = new Lenis()
lenis.on('scroll', (e) => {
console.log(e)
})
lenis.on('scroll', ScrollTrigger.update)
gsap.ticker.add((time)=>{
lenis.raf(time * 1000)
})
gsap.ticker.lagSmoothing(0)
React:
See documentation for react-lenis.
Instance settings
Option | Type | Default | Description |
---|---|---|---|
wrapper | HTMLElement, Window | window | The element that will be used as the scroll container |
content | HTMLElement | document.documentElement | The element that contains the content that will be scrolled, usually wrapper 's direct child |
eventsTarget | HTMLElement, Window | wrapper | The element that will listen to wheel and touch events |
lerp | number | 0.1 | Linear interpolation (lerp) intensity (between 0 and 1) |
duration | number | 1.2 | The duration of scroll animation (in seconds). Useless if lerp defined |
easing | function | (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)) | The easing function to use for the scroll animation, our default is custom but you can pick one from Easings.net. Useless if lerp defined |
orientation | string | vertical | The orientation of the scrolling. Can be vertical or horizontal |
gestureOrientation | string | vertical | The orientation of the gestures. Can be vertical , horizontal or both |
smoothWheel | boolean | true | Whether or not to enable smooth scrolling for mouse wheel events |
syncTouch | boolean | false | Mimic touch device scroll while allowing scroll sync (can be unstable on iOS<16) |
syncTouchLerp | number | 0.075 | Lerp applied during syncTouch inertia |
touchInertiaMultiplier | number | 35 | Manage the the strength of syncTouch inertia |
wheelMultiplier | number | 1 | The multiplier to use for mouse wheel events |
touchMultiplier | number | 1 | The multiplier to use for touch events |
normalizeWheel | boolean | false | Normalize wheel inputs across browsers (not reliable atm) |
infinite | boolean | false | Enable infinite scrolling! (See example) |
autoResize | boolean | true | Resize instance automatically based on ResizeObserver . If false you must resize manually using .resize() |
Instance Props
Property | Type | Description |
---|---|---|
animatedScroll | number | Current scroll value |
dimensions | object | Dimensions instance |
direction | number | 1 : scrolling up, -1 : scrolling down |
emitter | object | Emitter instance |
options | object | Instance options |
targetScroll | number | Target scroll value |
time | number | Time elapsed since instance creation |
actualScroll | number | Current scroll value registered by the browser |
velocity | number | Current scroll velocity |
isHorizontal (getter) | boolean | Whether or not the instance is horizontal |
isScrolling (getter) | boolean | Whether or not the scroll is being animated |
isSmooth (getter) | boolean | Whether or not the scroll is animated |
isStopped (getter) | boolean | Whether or not the user should be able to scroll |
limit (getter) | number | Maximum scroll value |
progress (getter) | number | Scroll progress from 0 to 1 |
rootElement (getter) | HTMLElement | Element on which Lenis is instanced |
scroll (getter) | number | Current scroll value (handles infinite scroll if activated) |
className (getter) | string | rootElement className |
Instance Methods
Method | Description | Arguments |
---|---|---|
raf(time) | Must be called every frame for internal usage. | time : in ms |
scrollTo(target, options) | Scroll to target. | target : goal to reachnumber : value to scroll in pixelsstring : CSS selector or keyword (top , left , start , bottom , right , end )HTMLElement : DOM elementoptions offset (number ): equivalent to scroll-padding-top lerp (number ): animation lerp intensityduration (number ): animation duration (in seconds)easing (function ): animation easingimmediate (boolean ): ignore duration, easing and lerplock (boolean ): whether or not to prevent the user from scrolling until the target is reachedforce (boolean ): reach target even if instance is stoppedonComplete (function ): called when the target is reached |
on(id, function) | id can be any of the following instance events to listen. | |
stop() | Pauses the scroll | |
start() | Resumes the scroll | |
resize() | Compute internal sizes, it has to be used if autoResize option is false . | |
destroy() | Destroys the instance and removes all events. |
Instance Events
Event | Callback Arguments |
---|---|
scroll | Lenis instance |
Recommended CSS
html.lenis, html.lenis body {
height: auto;
}
.lenis.lenis-smooth {
scroll-behavior: auto !important;
}
.lenis.lenis-smooth [data-lenis-prevent] {
overscroll-behavior: contain;
}
.lenis.lenis-stopped {
overflow: hidden;
}
.lenis.lenis-scrolling iframe {
pointer-events: none;
}
Considerations
Nested scroll
<div data-lenis-prevent>scroll content</div>
<div data-lenis-prevent-wheel>scroll content</div>
<div data-lenis-prevent-touch>scroll content</div>
Anchor links
<a href="#anchor" onclick="lenis.scrollTo('#anchor')">scroll to anchor</a>
Limitations
- no support for CSS scroll-snap
- capped to 60fps on Safari (source) and 30fps on low power mode
- smooth scroll will stop working over iframe since they don't forward wheel events
- position fixed seems to lag on MacOS Safari pre-M1 (source)
Tutorials
- Scroll Animation Ideas for Image Grids by Codrops
- How to Animate SVG Shapes on Scroll by Codrops
- The BEST smooth scrolling library for your Webflow website! (Lenis) by Diego Toda de Oliveira
- Easy smooth scroll in @Webflow with Lenis + GSAP ScrollTrigger tutorial by También Studio
Plugins
- Loconative-scroll by Quentin Hocde
- react-lenis by darkroom.engineering
- r3f-scroll-rig by 14islands
- Lenis Scroll Snap Plugin by Funkhaus
- locomotive-scroll by Locomotive
- vue-lenis by ZEOKKU
- nuxt-lenis by Milkshake Studio
Lenis in use
- Lunchbox by Studio Freight
- Easol by Studio Freight
- Dragonfly by Studio Freight
- Yuga Labs by Antinomy Studio
- Quentin Hocde's Portfolio by Quentin Hocde
- Houses Of by Félix P. & Shelby Kay
- Shelby Kay's Portfolio by Shelby Kay
- Heights Agency Portfolio by Francesco Michelini
- Goodship by Studio Freight
- Flayks' Portfolio by Félix P. & Shelby Kay
- Matt Rothenberg's portfolio by Matt Rothenberg
- Edoardo Lunardi's portfolio by Edoardo Lunardi
- DeSo by Studio Freight
- Francesco Michelini's portfolio by Francesco Michelini
Authors
This set of hooks is curated and maintained by the darkroom.engineering team:
- Clément Roche (@clementroche_) – darkroom.engineering
- Guido Fier (@uido15) – darkroom.engineering
- Leandro Soengas (@lsoengas) - darkroom.engineering
- Franco Arza (@arzafran) - darkroom.engineering
License
8 months ago
8 months ago
8 months ago
9 months ago
9 months ago
9 months ago
9 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago