【ScrollTrigger】リサイズ時などにプロパティ内で動的に関数を再計算させる方法

こんにちは。フロントエンドエンジニアのノートです。

フロントエンド
エンジニア

ノート

一年ぶりぐらいに記事を書く気がします。

フロントエンド
エンジニア

ノート

ちなみに記事を書くのをサボっている間に入籍しました。

フロントエンド
エンジニア

ノート

はじめに

今回はScrollTriggerの実装をする際、

 

リサイズ処理などのイベントでプロパティに別の値を指定したいのにもかかわらず、
プロパティ内で関数が動的に動かず、値が初期値のままという状態になったので、

 

その実例と、失敗の備忘録も兼ねて、解説していきたいと思います。

失敗例

では、まず失敗例がこちらです。

リサイズをしてブレイクポイントが変更されると、ヘッダーの高さが変更されたことにより、

「スクロールを固定したstartの初期値 – レスポンシブによるヘッダーの高さの変更分」の余白が空いてしまい、

背景の黒色の余白が見えてしまいます。

 

▷DEMO

See the Pen ScrollTrigger Resize function by LOGICAL STUDIO PR部 (@ls_pr) on CodePen.

※codepenのResultタブ以外を押して、Resultの画面サイズを半分にするとリサイズ処理がかかって現象が確認できると思います。(PC推奨)

 

▷ソースコード

// ScrollTrigger init
const initScrollTrigger = () => {
  const timeline = gsap.timeline();
  timeline.to(".circle", {opacity: 1})
    .fromTo(".circle", 
            {scale: 0},
            {scale: 25, stagger: 0.2}
           )
    .fromTo(".circle-text", 
            {scale: 1.4, opacity: 0},
            {scale: 1, opacity: 1}
           )
  const scrollTriggerInctance = new ScrollTrigger({
    animation: timeline,
    trigger: '#pin-container',
    start: `top ${getHeaderHeight()}`,
    end: `+=${getContentHeight(true)}`,
    pin: true,
    scrub: 0.5,
    anticipatePin: 1.5,
  })
}

※今回の記事内で重要な部分である、ScrollTrigger生成用の関数内のみのソースを抜粋しています。

 

こちらの関数が再計算されない問題ですが、

リサイズ時に、ScrollTriggerの初期化やrefreshをすれば、、と思い、
色々試しましたが再計算されず。。

↑もしかしたら、正しく初期化やrefreshなどできれば再度、値がセットされるかもしれませんが。。今回は未検証です。

 

ちなみに、、デバッグをして

・初期値は正しく指定されている

・リサイズ時に関数内の値は返ってきている

ということは確認できていましたので、関数自体は正常に動作しています。

 

関数が正常に動いているということは、

start: `top ${getHeaderHeight()}`

 

やはり上記プロパティ内での値の再指定ができていないようです。

ただ、コチラの記事にも下記の通り書かれている通り、
プロパティ内で関数で指定した際は動的に再計算されるはずなのです。

関数指定の場合

指定した関数は、ScrollTriggerの作成時やスクローラーのリサイズ時、つまり、位置が計算されるたびに呼び出されます。

この関数は、文字列もしくは数をリターンしなければいけません。これを利用することで、動的に値を計算することが容易になります。

 

なぜ再計算されないのでしょうか。。謎は深まるばかりで多くの時間とやる気が削がれていきました。

【結論】コールバックとして関数用の記述をしよう

探し尽くした結果、、奇跡的にGSAPのフォーラムに、
関数が動的に再計算されないという同じ悩みを抱えている同志がおり、
コチラのスレ内で今回の問題が解決できそうなそれっぽい回答がありました。

 

同志とGreenSock公式、ありがとう。

 

 

結論、

プロパティの値形式が関数の際は、コールバックとして関数用の記述をしようね

ということでした。

 

ですので、下記の修正を加えて再挑戦してみます。

start: () =>`top ${getHeaderHeight()}`

完成系

解決策も分かったところで、修正したのがこちらになります。

See the Pen ScrollTrigger Resize function(success) by LOGICAL STUDIO PR部 (@ls_pr) on CodePen.

 

もうリサイズしても黒い余白が出ないと思いますので、これで完成です。

リサイズ時にプロパティ内に関数で値が再計算されるようになりました。

最後に

でも、onLeaveやonRefreshなどのデフォルトの値形式が関数のものは、
ドキュメントでも下記のようにコールバックの記述になっているので、

onLeave: ({progress, direction, isActive}) => console.log(progress, direction, isActive)

 

普通に考えれば、プロパティ内で値形式を関数にするのであれば、
コールバックの記述は必要ですよね、、と思いましたので、すごく初歩的なミスだった気がします。

 

とりあえず、わからなかったらドキュメントとフォーラムなどをしっかり漁ろうということでした。

 

現在ロジカルスタジオでは、デザイナー、エンジニア、ディレクターを募集しています。

ご興味のある方はぜひ、下記リンクの採用サイトからご応募ください。

ロジカルスタジオ 採用サイトはこちら