Closed2

framer-motionのuseScrollが分からない

masa5714masa5714

offsetオプション

どこから始めて、どこで終わるかを決めることができる。
ただの魔法である。

const { scrollYProgress } = useScroll({
  target: ref,
  offset: ["end end", "start start"]
});

offset: ["どこから開始(A)", "どこで終了(B)"] という形。
ちなみに配列だが「どこで終了(B)」が無いと動かない模様なので注意。

◆どこから開始(A)
左側のend: refが付与された要素の末尾
右側のend: ブラウザ下。(position:fixed時のbottom:0に相当する位置のこと。)

それぞれが交わるタイミングで開始される。

◆どこで終了(B)
左側のstart: refが付与された要素の先端
右側のstart: ブラウザの上端。(position:fixed時のtop:0に相当する位置のこと。)

それぞれが交わるタイミングで終了する。

masa5714masa5714

position: stickyで固定されたタイミングでスタイルを適用したい

どうやってやるのがベストか分からないが一応動かせたのでメモ。

const ref = useRef(null);
const { scrollYProgress } = useScroll({
  target: ref,
  offset: ["start start", "end end"]
});

const [isSticky, setIsSticky] = useState(false);

useMotionValueEvent(scrollYProgress, "change", (e) => {
  e === 0 ? setIsSticky(true) : setIsSticky(false);
});

return (
  <div ref={ref} className={`sticky top-0 ${clsx(isSticky ? "opacity-0": "")}`}>この要素がsticky</div>
);

stickyのタイミングで opacity: 0 が適用されるはず。

useMotionValueEvent はいわば addEventListener みたいなもの。
scrollYProgress で対象要素までの位置を測っているイメージ。
対象要素までの距離が無くなった、つまり0のときにsticky状態であると判定している。

この投稿を検索から見つけた方、いい感じの実装方法あれば、このスクラップにコメント追加して頂けると嬉しいです!


無理矢理感満載だけどとりあえず動いたのでおk

いちお、React Developer Toolsでプロファイリングしてみたが、無駄なレンダリングはされていないようなので良しとしたい。

リサイズ処理を自分らで勝手にやってくれるのは嬉しい。

▲出来上がったもの:GIFで比率ミスった

このスクラップは2024/03/10にクローズされました