<p class="scroll-anim-03 js-scroll-anim-03">スクロールアニメーション03</p>
p.scroll-anim-03.js-scroll-anim-03 #{ text }
{
"text": "スクロールアニメーション03"
}
$BLOCK_NAME: '.scroll-anim-03';
// 変数
$easing_default: cubic-bezier(0.45, 0.25, 0.15, 1);
$delay_each: 0.03s;
#{ $BLOCK_NAME } {
font-size: 0;
opacity: 0;
& > span {
display: inline-block;
font-size: 40px;
opacity: 0;
transition-timing-function: $easing_default;
transition-duration: 1s;
transition-property: transform, opacity;
transform: translate(0.5em, 40%) rotateX(-30deg) rotateY(-30deg);
@for $i from 1 through 20 {
&:nth-child(#{$i}) {
transition-delay: #{($i - 1) * $delay_each};
}
}
}
&.is-animated {
opacity: 1;
& > span {
opacity: 1;
transform: translate(0) rotate(0);
}
}
}
'use strict';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
export const scrollAnim03 = () => {
// アニメーションさせる要素を指定
const els = document.getElementsByClassName('js-scroll-anim-03');
// アニメーションを設定
[...els].forEach(el => {
const imgAnim = new ImgAnim(<HTMLElement>el);
imgAnim.init();
});
}
class ImgAnim {
el: HTMLElement;
constructor(el: HTMLElement) {
this.el = el;
}
/**
* 初期化
*/
init(): void {
this.textInit();
this.scrollHandler();
}
/**
* テキストを初期化
*/
textInit(): void {
// アニメーション用に分割
let markup = '';
const text = this.el.textContent;
text.split('').forEach(l => {
markup += `
<span>${l}</span>
`;
});
this.el.innerHTML = markup;
}
/**
* スクロール連動のイベント設定
*/
scrollHandler(): void {
ScrollTrigger.create({
trigger: this.el,
start: 'top 70%',
onEnter: self => {
// 「is-animated」クラスを付与
this.el.classList.add('is-animated');
self.kill();
}
});
}
}