😄
Lenisで慣性スクロールを作るメモ
Lenisで慣性スクロールを作るメモ
Lenis.js
を使用したら、慣性スクロールという挙動が簡単に実装できると聞いたので、お試しにページを作るメモ
初期設定
インストール
npm i lenis
CSSファイル
おすすめで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-smooth iframe {
pointer-events: none;
}
基本的な書き方
useLenis
はLenis
インスタンスを返すらしい。
root
属性はページ全体のスクロール制御を行うように示す
options
- lerp: スクロール効果の線形補完値を示す。値が低いほどスクロールがスムーズになる。
- duration: スクロール効果の継続時間
- smoothTouch: スマホなどタッチデバイス対応
その他
import { ReactLenis, useLenis } from 'lenis/react'
function Layout() {
const lenis = useLenis(({ scroll }) => {
// called every scroll
})
return (
<ReactLenis root>
{ /* content */ }
</ReactLenis>
)
}
お試しページを作る
スクロールすると、プログレスバーが表示されあとどのくらいページがスクロールできるかを示すページを作ってみる
前提条件
Reactで実装します。TailwindCSSもあらかじめインストールされているものとします。
必要パッケージ・ライブラリのインストール
- lenis
- react-markdown
- @tailwindcss/typography(プラグインの設定は参考ページを見てください)
コード
useLenis
の使い方がまだいまいち分からないので、ドキュメントを読まなければいけない
- useEffect内でスクロールの進捗率を計算し、stateに保存
- SSRで取得したマークダウンの文字列を
react-markdown
で解析してHTMLとして表示する。@tailwindcss/typography
でさくっとスタイルを調整する。
import { cn } from '@/utils/cn';
import { ReactLenis, useLenis } from 'lenis/react'
import { useRef, useState } from 'react';
import { readFileSync } from 'fs';
import { join } from 'path';
import { cwd } from 'process';
import { getYamlHeaderFromString } from '@/utils/get-yaml-header';
import Markdown from "react-markdown"
interface Props {
content: string;
}
const Code3 = (props: Props) => {
const {
content
} = props;
const [scrolled, setScrolled] = useState<number>(0);
useLenis(({ scroll }) => {
const scrollHeight =
(document.documentElement && document.documentElement.scrollHeight) ||
document.body.scrollHeight;
const clientHeight =
document.documentElement.clientHeight || window.innerHeight;
setScrolled(scroll / (scrollHeight - clientHeight));
});
return (
<main className="min-h-screen min-w-screen overflow-hidden relative">
<ReactLenis
root
options={{
lerp: 0.1,
duration: 3,
smoothWheel: true
}}
>
<div className={cn('w-full flex flex-col relative')}>
<div
className={cn('h-1 block bg-teal-500 fixed origin-[0%] top-0 left-0')}
style={{
width: `calc(100%*${scrolled})`
}}
/>
<div className={cn(
"m-auto py-16 flex flex-col justify-center [&>*]:mb-12 font-yumin prose",
)} >
<Markdown
>
{content}
</Markdown>
</div>
</div>
</ReactLenis>
</main>
)
}
export const getServerSideProps = () => {
const fileContent = readFileSync(
join(cwd(), "src", "contents", "demo.md"),
"utf-8",
);
const { content } = getYamlHeaderFromString(fileContent);
return {
props: {
content: content,
},
};
};
export default Code3;
実際の画面
あまり慣性スクロールになっているか映像ではわかりにくい
参考
最後に
間違っていることあればコメントに書いていただけると幸いです。
よろしくお願いいたします。
Discussion