現状のHPを無料で診断いたします。
お気軽にお問い合わせください。


お役立ち
ニッティ・グリッティの
お役立ち情報
GSAPをつかったスクロール連動アニメーション
UPDATE :
投稿者 : ニッティ・グリッティ

スクロールと連動するウェブアニメーションは目を惹きますよね
スクロールと連動して、丸の中から画像が現れるような表現もできます (Blake Bowen (@osublake)さんのコードです)
See the Pen ScrollTrigger by Blake Bowen (@osublake) on CodePen.
GSAPというウェブアニメーションの強力なライブラリを使用しているようです
はたしてどんな内容になっているのでしょうか?
今回は、上記のコードをゆっくり読んでいきたいと思います。
html
<img id="img" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/smile.jpg">
<svg id="svg">
<defs>
<mask id="mask">
<rect width="100%" height="100%" fill="white"></rect>
<circle id="circle" cx="50%" cy="50%" r="60" fill="black"></circle>
</mask>
</defs>
<rect id="whiteLayer" width="100%" height="100%" fill="white"></rect>
</svg><rect width="100%" height="100%" fill="black" mask="url(#mask)"></rect>
<div id="content"><br></div>
css
#img {
position: fixed;
top: 50%;
left: 50%;
}
#svg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
}
#content {
height: 2500px;
}
画像が中央に固定配置されていますね
defsでマスクを定義しています。マスクの形は画面と同じサイズの白い四角形の真ん中に黒い円形で、さらにwhitelayerというIDの画面と同じサイズの白い四角形があり、もうひとつ画面と同じ大きさの黒い四角形があります。
次にjavascript部分を読んでいきましょう
console.clear();
const svg = document.querySelector("#svg");
const img = document.querySelector("#img");
const circle = document.querySelector("#circle");
const pad = 4;
let radius = +circle.getAttribute("r");
let imgWidth, imgHeight;
gsap.set(img, {
scale: 2,
xPercent: -50,
yPercent: -50
});
var tl = gsap.timeline({
scrollTrigger: {
start: "top top",
end: "bottom bottom",
scrub: 0.2,
},
defaults: {
duration: 1
}
})
.to(circle, {
attr: {
r: () => radius
}
}, 0)
.to(img, {
scale: 1,
}, 0)
.to("#whiteLayer", {
alpha: 0,
ease: "power1.in",
duration: 1 - 0.25
}, 0.25);
window.addEventListener("load", init);
window.addEventListener("resize", resize);
function init() {
imgWidth = img.naturalWidth;
imgHeight = img.naturalHeight;
resize();
}
function resize() {
tl.progress(0);
const r = svg.getBoundingClientRect();
const rectWidth = r.width + pad;
const rectHeight = r.height + pad;
const rx = rectWidth / imgWidth;
const ry = rectHeight / imgHeight;
const ratio = Math.max(rx, ry);
const width = imgWidth * ratio;
const height = imgHeight * ratio;
const dx = rectWidth / 2;
const dy = rectHeight / 2;
radius = Math.sqrt(dx * dx + dy * dy);
gsap.set(img, { width, height });
tl.invalidate();
ScrollTrigger.refresh();
}
関数は2つ。init と resizeがあります。
initは画像の実際のサイズを取得しresizeを行う。
resizeは、画像のサイズが変わった時に再度初期化とresizeを行っています
ポイントは、resizeのなかの radius = Math.sqrt(dx * dx + dy * dy);
この部分で、画面幅の縦横から半径を算出して、radiusに入れています。
つまり、この画面幅での最大の半径ですね。
const svg = document.querySelector(“#svg”);
const img = document.querySelector(“#img”);
const circle = document.querySelector(“#circle”);
const pad = 4; この部分で各要素を取得しています。
つぎに変数を宣言しています。
let radius = +circle.getAttribute(“r”);
let imgWidth, imgHeight;
+circle.getAttribute(“r”);の+は単項正値演算子というもので、数値に変換する役割を持っています。
つまり、circleのr属性の値を数値に変換しています
(こちらが参考になりました) https://torikatsu923.hatenablog.com/entry/2020/12/04/013358
gsap.set(img, { scale: 2, xPercent: -50, yPercent: -50 });
画像を2倍のサイズで中心に設定しています。
xPercent yPercentは、cssではtranslateX translateYなのでtranslateX(-50%) translateY(-50%)ですね。
さていよいよgsapのメインの処理です。
gsap.timelineで複数の処理をまとめています。
処理1 .to(circle, { attr: { r: () => radius } }, 0)
circleのr属性の値をradiusの値に向けて変化させる →円の直径が大きくなる
処理2 .to(img, { scale: 1, }, 0) 画像の大きさを2倍から1倍に変化させる
処理3 to(“#whiteLayer”, { alpha: 0, ease: “power1.in”, duration: 1 – 0.25 }, 0.25);
id whitelayerの透明度を0にする
これらの処理を行うことでスクロールに連動させたアニメーションを実現しているんですね。

BLOG
お役立ち情報
-
雑に選んでいませんか?フォントでデザインに表情をつけよう!
2024.12.03
CATEGORY
お役立ち情報 -
【初心者さん必見!】使えると超おしゃれ!「ブレンドツール」とは!~イラレの便利機能紹介Part6~
2024.12.02
CATEGORY
お役立ち情報 -
テンプレートで簡単!?もう悩まないプレゼン資料作成!
2024.11.28
CATEGORY
お役立ち情報 -
ホームページ集客のコツとは?コンサルティング会社が紹介!
2023.08.21
CATEGORY
お役立ち情報 -
IT導入補助金のご案内
2023.08.07
CATEGORY
お役立ち情報 -
【3分でわかる】Threads(スレッズ)とは?登録方法やTwitterとの違いをご紹介
2023.07.07
CATEGORY
お役立ち情報