Skip to content

Instantly share code, notes, and snippets.

@kobitoDevelopment
Last active September 27, 2023 06:37
Show Gist options
  • Save kobitoDevelopment/dc231c7718976f8b2caaad310ab6366f to your computer and use it in GitHub Desktop.
Save kobitoDevelopment/dc231c7718976f8b2caaad310ab6366f to your computer and use it in GitHub Desktop.
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.6.1/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.6.1/ScrollTrigger.min.js"></script>
npm install gsap
import {gsap} from "gsap";
import ScrollTrigger from "gsap/ScrollTrigger.js";
gsap.registerPlugin(ScrollTrigger);
/* アニメーション対象要素の初期値を設定 開始 */
gsap.set(".moveItem", { scale: 0 });
//初期状態としてtransform:scale(0);が適用される
//※「transform:」scale(0);の「transform:」が省略できる訳ではないので、GSAPが用意している変形プロパティのみ省略記述可能
/* アニメーション対象要素の初期値を設定 終了 */
/* アニメーション内容を記述 開始 */
gsap.to(".moveItem", {
//同一トリガーで複数要素をアニメーションさせる場合は gsap.to(".moveItem1",".moveItem2" {
/* アニメーション完了後の状態を記述 開始 */
//cssに用意されている「プロパティ:値,」を記述してもOK(全てのプロパティはサポートしていない)
x: 100, //x軸を100px移動
x: 100 + "%", // 単位を指定することも可能
y: -100, //y軸を-100px移動
color: "#ff0000", //CSSプロパティも一部指定可能
backgroundColor: "#00ff", // ハイフンを含む場合は先頭を大文字に
scale: 1, //transform:scale(1)
duration: 2, //何秒かけてアニメーションを100%まで進めるか設定可能
delay: 2, //何秒後にアニメーションを発火するか設定可能
ease: "power1.out", // 用意されているイージング詳細は公式:https://greensock.com/docs/v3/Eases
/* アニメーション完了後の状態を記述 終了 */
scrollTrigger: {
trigger: ".moveTrigger",
//この要素が画面に入ったらgsap.toで記述した要素がアニメーションを開始する(トリガー設定)
//pin:true,の場合はこの要素がendの数値スクロール分固定される
start: "top top",
//トリガー要素のどの部分が画面に入ったらアニメーションを発火するか設定
//top top の場合はトリガー要素が画面に入ったら
//top center の場合はトリガー要素が画面の中心に入ったら発火
end: "+=900",
//アニメーション終了位置を設定。この数値のスクロール量でアニメーションが 0% -> 100% に到達
pin: true,
//トリガー要素を固定する場合はtrue
scrub: true,
//スクロールとアニメーションを連動させる場合はtrue。数字をセットすることで◯秒遅れでスクロールと連動させる(慣性スクロール)
markers: true,
//デバッグ用マーカーを表示する場合はtrue(triggerの位置、アニメーション開始・終了位置を表示可能)
once:true,
//一度だけ実行したい場合に記述
},
});
/* アニメーション内容を記述 終了 */
/* 1つのトリガーで複数の要素をアニメーションさせるがタイミングはずらす 開始 */
gsap.to(".moveItems", { //アニメーションさせたい複数の要素に付与されているclass名
x: 100,
scrollTrigger: {
trigger: ".moveTrigger",
start: "top top",
},
stagger: {
from: "start", //start = 要素順にアニメーション。 start、center、edges、random、endで指定可能
amount: 0.4, //0.4秒ずらしてアニメーション
},
});
/* 1つのトリガーで複数の要素をアニメーションさせるがタイミングはずらす 終了 */
/* トリガーとアニメーションの対象要素が同一の場合 開始 */
ScrollTrigger.batch(".moveItems", {
// トリガーを通過した場合
onEnter: function (elem) {
gsap.to(elem, { opacity: 1, y: 0 });
},
// トリガーを完全に通過した場合
onLeave: function (elem) {
gsap.to(elem, { opacity: 0, y: 0 });
},
// トリガーを完全に通過した後、通過した方向から再度トリガーを通過した場合
onEnterBack: function (elem) {
gsap.to(elem, { opacity: 1, y: 0 });
},
// トリガーを完全に通過した後、トリガーより上に戻って再度トリガーを通過した場合
onLeaveBack: function (elem) {
gsap.to(elem, { opacity: 0, y: 0 });
},
start: "top 50%",
});
/* トリガーとアニメーションの対象要素が同一の場合 終了 */
/* トリガー通過で対象要素にclassを追加 開始 */
ScrollTrigger.create({
trigger: ".moveTrigger", //class付与のトリガーとなる要素
start: "top center",
end: "bottom center",
toggleClass: { targets: ".moveItem1, .moveItem2", className: "is-show" },
/*
targets: classを付与したい要素を記述(複数可)
className: 付与したいclassを記述
*/
once: true, // 着脱を繰り返したくない場合(一度だけclass付与)
});
/* トリガー通過で対象要素にclassを追加 終了 */
/* アニメーションタイムラインを作成する 開始 */
const customAnimation = gsap.timeline({
scrollTrigger: {
trigger: ".moveTrigger",
start: "top center",
},
});
// トリガー到達時にアニメーションする1つ目の要素
customAnimation.to(
".moveItem1", //アニメーションする要素
{
keyframes: [
{ duration: 0.5, x: 100, y: 200 }, //このアニメーション完了後、下のアニメーションが発火
{ duration: 1, x: 0, y: 0 },
],
}
);
// トリガー到達時にアニメーションする2つ目の要素
customAnimation.to(
".moveItem2", //アニメーションする要素
{
keyframes: [
{ duration: 0.5, x: -100, y: -200 }, //このアニメーション完了後、下のアニメーションが発火
{ duration: 1, x: 0, y: 0 },
],
},
"<"
/*
"<" 直前の要素と同じタイミングでアニメーション
"2" 2秒後にアニメーション
"+=1" 要素自身を基準に1秒後にアニメーション
"-=3" 要素自身を基準に3秒前にアニメーション
"<4" 直前の要素を基準に4秒後にアニメーション
">2" 直後の要素を基準に2秒後にアニメーション
*/
);
/* アニメーションタイムラインを作成する 終了 */
/* アニメーションタイムラインを作成する 開始 */
const customAnimation = gsap.timeline({
repeat: -1, // アニメーションを繰り返す回数。-1で無限回
repeatDelay: 0.6, // アニメーションループの間隔を設定
// repeatとtoggleActionsは共存しない
scrollTrigger: {
trigger: ".moveTrigger",
start: "top center",
toggleActions: "play pause resume reset", // アニメーション開始位置、終了位置通過後の処理
/*
□ 指定可能なオプション
play … アニメーションをスタートさせる
pause … 一時停止
resume … アニメーションを再開させる
reset … アニメーション開始直前の状態に戻す
restart … 始めに戻ってアニメーションを開始
complete … アニメーション直後の状態にする
reverse … アニメーションを逆再生する
none … 何も指定しない
□ 指定順
onEnter onLeave onEnterBack onLeaveBack
*/
},
});
// トリガー到達時にアニメーションする1つ目の要素
customAnimation.to(
".moveItem1", //アニメーションする要素
{
keyframes: [
{ duration: 0.5, x: 100, y: 200 }, //このアニメーション完了後、下のアニメーションが発火
{ duration: 1, x: 0, y: 0 },
],
}
);
// トリガー到達時にアニメーションする2つ目の要素
customAnimation.to(
".moveItem2", //アニメーションする要素
{
keyframes: [
{ duration: 0.5, x: -100, y: -200 }, //このアニメーション完了後、下のアニメーションが発火
{ duration: 1, x: 0, y: 0 },
],
},
"<"
/*
"<" 直前の要素と同じタイミングでアニメーション
"2" 2秒後にアニメーション(2=2sの場合と2000=2sの場合を試して見極める)
"+=1" 要素自身を基準に1秒後にアニメーション
"-=3" 要素自身を基準に3秒前にアニメーション
"<4" 直前の要素を基準に4秒後にアニメーション
">2" 直後の要素を基準に2秒後にアニメーション
*/
);
/* アニメーションタイムラインを作成する 終了 */
/* イベントトリガーでアニメーションを発火させる 開始 */
// tweenを作成
const createTween = gsap.to(".moveItem2", {
y: -100, //y軸を-100px移動
paused: true, // アニメーションを停止状態に
});
// トリガーを設定
const trigger = document.querySelector(".moveItem1");
trigger.addEventListener("click", function () {
// 作成した tweenを発火
createTween.play();
/*
pause()... 停止
play()... 再生(pause時はその場所から続きを再生)
restart()... 最初から再生
resume()... 続きから再生
reverse()... 逆再生
*/
});
/* イベントトリガーでアニメーションを発火させる 終了 */
/* 画面幅によってアニメーションを出し分ける 開始 */
ScrollTrigger.matchMedia({
// 960px以上
"(min-width: 960px)": function () {
gsap.to(".moveItem", {
autoAlpha: 1,
x: 1000,
scrollTrigger: {
trigger: ".moveTrigger",
start: "top center",
},
});
},
// 600px以上959px以下
"(min-width: 600px) and (max-width: 959px)": function () {
gsap.to(".moveItem", {
autoAlpha: 1,
x: 800,
scrollTrigger: {
trigger: ".moveTrigger",
start: "top center",
},
});
},
// 599px以下
"(max-width: 599px)": function () {
gsap.to(".moveItem", {
autoAlpha: 1,
x: 300,
scrollTrigger: {
trigger: ".moveTrigger",
start: "top center",
},
});
},
// メディアのサイズに関係なく、すべてに適用する
all: function () {
gsap.set(".moveItem", { autoAlpha: 0 });
},
});
/* 画面幅によってアニメーションを出し分ける 終了 */
/* スクロール量をページ読み込み完了時に再計算 開始 */
window.addEventListener("load", function () {
ScrollTrigger.refresh();
});
/* スクロール量をページ読み込み完了時に再計算 終了 */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment