突然ですが、GSAPというライブラリを聞いた事はありますか?
今回使うサンプル
GSAPとは
アニメーションを実装するために特化したライブラリですね。
GSAPを導入する(NPMで導入する)
$ npm install gsap
また、TypeScriptの型定義ファイルもgsapパッケージに同梱されているので、@types
の導入は不要です。
GSAPを導入する(CDNで導入する)
GSAPをサクッと導入したい場合は下記scriptタグをコピペしてください。
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.0/gsap.min.js"></script>
GSAPの基本的な書き方
基本的にGSAPを扱うときは下記のメソッドを使います。
gsap.set();
gsap.to();
それぞれ解説していきます。
①要素の状態をセットするgsap.set()
まず、はじめにアニメーションさせたい要素にアニメーション前の状態をセットします。
gsap.set(対象のDOM, {
プロパティ
})
②要素をある状態に変化させるgsap.to()
アニメーションをここで定義します。
gsap.to(対象のDOM, {
プロパティ
})
例(フェード系)
フェード系はCSSで言うところのopacity
を使います。GSAPでも同じなので早速簡単な例を見ていきましょう。
今回例として取り上げさせていただくのはよくあるローディング画面です。使用しているプロパティはopacity
とduration
です。
それ以外のプロパティはご自身で確かめてください。
See the Pen gsap-opacity-sample by Watataku (@watataku8911) on CodePen.
プロパティ | 説明 | 単位 | デフォルト値(括弧内はデフォルト値) |
---|---|---|---|
duration | 時間 | 数値(秒) | 省略化(1.0) |
ease | 加減速 | 文字列か関数 | 省略化(power2.inOut) |
repeat | リピート回数 | 数値(秒) | 省略化(0) |
repeatDelay | リピートするまでの遅延 | 数値 | 省略化(0) |
delay | 遅延秒数 | 数値(秒) | 省略化(0) |
overwrite | 上書きするか | 真偽値 | 省略化(false) |
paused | 一時停止した状態にするか | 真偽値 | 省略化(false) |
yoyo | リピート時に反復挙動にするか | 真偽値 or "auto" | 省略化(false) |
repeatプロパティを-1
に指定すると無限に繰り返すになる。
例(スライド系)
スライド系を実装する場合はCSSプロパティのtransform
を使いますよね?
GSAPでも同じです。GSAPではCSSのtransform
を直感的に記述できます。
See the Pen gsap-slide-sample by Watataku (@watataku8911) on CodePen.
※演出上の都合で、全てのボックスに`duration`と`repeat`をかけていますGSAP | CSS | 説明 |
---|---|---|
x: 20 | transform: transformX(20px) | 水平方向への移動(px) |
y: 20 | transform: transformY(20px) | 垂直方向への移動(px) |
rotate: 360 | transform: rotate(360deg) | 回転角度(角度) |
scale: 2 | transform: scale(2, 2) | 拡大・縮小(1.0が等倍) |
scaleX: 2 | transform: scaleX(2) | 水平方向だけ拡大・縮小 |
scale:Y 2 | transform: scaleY(2) | 垂直方向だけ拡大・縮小 |
xPercent: -50 | transform: translateX(-50%) | 水平方向への移動(要素の幅に対する割合) |
yPercent: -50 | transform: translateY(-50%) | 垂直方向への移動(要素の幅に対する割合) |
タイムライン
アニメーションを繋げたい時に使います。
const tl = gsap.timeline();
tl.to(".selector1", {
selector1のアニメーション
}).to(".selector2", {
selector2のアニメーション
});
selector1のアニメーションが終了後、selector2、3とアニメーションする。
イージング
本題
ここで、ようやく図のようなサンプルを作っていきます。
今回はHTMLとCSSは解説しませんがコードだけ貼っておきます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div class="c-loader-bg js-loader-bg">
<div class="c-loader-dot js-loader-dot-wrap">
<span></span>
<span></span>
<span></span>
</div>
</div>
<!-- ヘッダー -->
<header class="c-header js-header">
<div class="c-temp">
<p class="text">[ GSAP DEMO ]</p>
<p class="link">
<a href="https://b-risk.jp/blog/2022/05/gsap/" class="button"
>Button</a
>
</p>
</div>
</header>
<div class="cursor"></div>
<div class="shapes">
<div class="shape shape1"></div>
<div class="shape shape2"></div>
</div>
<div class="l-inner">
<div class="c-mv_title-wrap">
<div class="c-mv_title">
<h1 class="c-mv_title-item js-mv_title-item">Hello Would!!</h1>
</div>
</div>
</div>
<script type="module" src="/main.js"></script>
</body>
</html>
JS
まず、はじめに要素を取得しておきます。
const jsLoaderBg = ".js-loader-bg";
const jsDot = ".js-loader-dot-wrap > span";
const shapes = ".shape";
const jsText = ".js-mv_title-item span";
const jsHeader = ".js-header";
次に、アニメーションをセットし「アニメーション始めま〜す」と宣言します。
gsap.set([shapes, jsText], {
opacity: 0,
y: 30,
});
gsap.set(jsHeader, {
opacity: 0,
y: -50,
});
gsap.set(jsDot, {
opacity: 0,
y: -50,
});
最後に、gsap.to()
でアニメーションの処理を書いていきます。
const tl = gsap.timeline();
/* ドットが左から0.5秒おきに降ってくる */
tl.to(
jsDot,
{
opacity: 1,
y: 0,
duration: 0.8,
delay: 0.8,
stagger: {
amount: 0.5, //0.5秒おきに
from: "start", // 左から
ease: "power4.inOut",
},
}
)
/* 全てのドット(今回3つ)が出尽くした後ドットを消す */
.to(jsDot, {
opacity: 0,
})
/* ドットが消えた後カーテンが上から開く */
.to(jsLoaderBg, {
y: "100%",
delay: 0.5,
})
/* カーテンが開くと0.2秒後に下から円が登場 */
.to(
shapes,
{
opacity: 1,
y: 0,
duration: 0.8,
stagger: {
amount: 0.6,
from: "start",
ease: "sine.in",
},
},
"+=0.2" // dealy: 0.5と同じ
)
/* 円が登場後「HelloWould」が1文字ずつ登場 */
.to(
jsText,
{
opacity: 1,
y: 0,
stagger: {
amount: 1,
from: "start",
ease: "sine.in",
},
},
"-=0.1" // 前のアニメーションが完了する0.1秒前に実行する書き方
)
/* 文字が登場後ヘッダーが上から参上!! */
.to(jsHeader, {
opacity: 1,
y: 0,
});
CSSはGithubをご覧ください。
文字列を分割しspanで囲む
これはGSAPと直接関わりはないのですが、Hello Would
と一文字一文字アニメーションさせるためにspanタグ
で囲みます。
/* 文字列を分割しspanで囲む */
(function () {
const jsText = document.querySelectorAll(".js-mv_title-item");
jsText.forEach((target) => {
let newText = "";
const text = target.textContent;
const result = text.split("");
for (let i = 0; i < result.length; i++) {
newText += "<span>" + result[i] + "</span>";
}
target.innerHTML = newText;
});
})();
今回のサンプルの全体的なコード
最後に
このようにGSAPを扱うと複雑なアニメーションの処理も簡単に実装する事ができ、リッチなサイトが簡単に作れるので是非使って見てください。
この記事を読んでGSAPについて少しでもわかっていただけたら幸いです。