From 105384fd07e66c129775049bdb994ffbbe3a9109 Mon Sep 17 00:00:00 2001 From: Sam Barnett Date: Wed, 22 Apr 2026 14:35:13 +0800 Subject: [PATCH 1/2] feat: add lock and unlock methods --- packages/core/src/lenis.ts | 42 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/packages/core/src/lenis.ts b/packages/core/src/lenis.ts index 63f90fe8..1ba6dcad 100644 --- a/packages/core/src/lenis.ts +++ b/packages/core/src/lenis.ts @@ -31,6 +31,7 @@ export class Lenis { private _isScrolling: Scrolling = false // true when scroll is animating private _isStopped = false // true if user should not be able to scroll - enable/disable programmatically private _isLocked = false // same as isStopped but enabled/disabled when scroll reaches target + private _forceLocked = false // manual override for lock()/unlock() private _preventNextNativeScrollEvent = false private _resetVelocityTimeout: ReturnType | null = null private _rafId: number | null = null @@ -565,6 +566,12 @@ export class Lenis { return } + if (this.isLocked && this.actualScroll !== this.scroll) { + this.preventNextNativeScrollEvent() + this.setScroll(this.scroll) + return + } + if (this.isScrolling === false || this.isScrolling === 'native') { const lastScroll = this.animatedScroll this.animatedScroll = this.targetScroll = this.actualScroll @@ -643,6 +650,20 @@ export class Lenis { this.emit() } + /** + * Lock lenis scroll + */ + lock() { + this.forceLocked = true + } + + /** + * Unlock lenis scroll + */ + unlock() { + this.forceLocked = false + } + /** * RequestAnimationFrame for lenis * @@ -1082,13 +1103,30 @@ export class Lenis { * Check if lenis is locked */ get isLocked() { - return this._isLocked + return this._forceLocked || this._isLocked } private set isLocked(value: boolean) { + const isLocked = this.isLocked + if (this._isLocked !== value) { this._isLocked = value - this.updateClassName() + + if (isLocked !== this.isLocked) { + this.updateClassName() + } + } + } + + private set forceLocked(value: boolean) { + const isLocked = this.isLocked + + if (this._forceLocked !== value) { + this._forceLocked = value + + if (isLocked !== this.isLocked) { + this.updateClassName() + } } } From 2ddd0de0c98307263de165025b23891cebe87490 Mon Sep 17 00:00:00 2001 From: Sam Barnett Date: Wed, 22 Apr 2026 14:36:24 +0800 Subject: [PATCH 2/2] Add playground tests for lock/unlock methods --- playground/core/test.ts | 11 ++++++++++- playground/react/style.css | 1 + playground/www/pages/core.astro | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/playground/core/test.ts b/playground/core/test.ts index b300ff10..30ff6794 100644 --- a/playground/core/test.ts +++ b/playground/core/test.ts @@ -102,7 +102,7 @@ const debugEl = document.createElement('div') debugEl.style.cssText = ` position: fixed; top: env(safe-area-inset-top, 8px); - left: 8px; + right: 8px; z-index: 9999; padding: 8px 10px; font: 12px/1.3 ui-monospace, Menlo, monospace; @@ -124,6 +124,7 @@ const renderDebug = (e: Lenis) => { `progress ${(e.progress * 100).toFixed(1)}%`, `direction ${e.direction}`, `isScrolling ${e.isScrolling}`, + `isLocked ${e.isLocked}`, ].join('\n') } @@ -216,6 +217,14 @@ document.getElementById('start')?.addEventListener('click', () => { // document.documentElement.style.overflow = 'auto' lenis.start() }) +document.getElementById('lock')?.addEventListener('click', () => { + // document.documentElement.style.overflow = 'auto' + lenis.lock() +}) +document.getElementById('unlock')?.addEventListener('click', () => { + // document.documentElement.style.overflow = 'auto' + lenis.unlock() +}) document.getElementById('scroll-start')?.addEventListener('click', () => { lenis.scrollTo(100, { diff --git a/playground/react/style.css b/playground/react/style.css index 5389d675..ceb1e33c 100644 --- a/playground/react/style.css +++ b/playground/react/style.css @@ -54,6 +54,7 @@ html:not(.lenis) { background: #222; color: #fff; border-radius: 4px; + margin-right: 4px; } .debug-panel button:hover { diff --git a/playground/www/pages/core.astro b/playground/www/pages/core.astro index 144a4516..e882deb7 100644 --- a/playground/www/pages/core.astro +++ b/playground/www/pages/core.astro @@ -10,6 +10,8 @@ import Layout from '../layouts/Layout.astro' + +