こんにちは!セミマサです。
今回はJavaScriptを使ってスクロールに連動したアニメーションをつけてみました。
デモサイト
今回のデモサイトです。
ソースコード
HTML
<section>
<div class="space"></div>
</section>
<section>
<h2 class="heading">下から登場</h2>
<div class="content-box">
<div class="content anime anime-bottom">コンテンツ</div>
<div class="content anime anime-bottom">コンテンツ</div>
<div class="content anime anime-bottom">コンテンツ</div>
</div>
</section>
<section>
<h2 class="heading">横から登場</h2>
<div class="content-box">
<div class="content anime anime-left">コンテンツ</div>
<div class="content anime anime-right">コンテンツ</div>
<div class="content anime anime-left">コンテンツ</div>
<div class="content anime anime-right">コンテンツ</div>
<div class="content anime anime-left">コンテンツ</div>
<div class="content anime anime-right">コンテンツ</div>
</div>
</section>
<section>
<h2 class="heading">拡大</h2>
<div class="content-box">
<div class="content anime anime-big">コンテンツ</div>
<div class="content anime anime-big">コンテンツ</div>
<div class="content anime anime-big">コンテンツ</div>
</div>
</section>
<section>
<h2 class="heading">縮小</h2>
<div class="content-box">
<div class="content anime anime-small">コンテンツ</div>
<div class="content anime anime-small">コンテンツ</div>
<div class="content anime anime-small">コンテンツ</div>
</div>
</section>
<section>
<h2 class="heading">縦回転</h2>
<div class="content-box">
<div class="content anime anime-rotate-x">コンテンツ</div>
<div class="content anime anime-rotate-x">コンテンツ</div>
<div class="content anime anime-rotate-x">コンテンツ</div>
</div>
</section>
<section>
<h2 class="heading">横回転</h2>
<div class="content-box">
<div class="content anime anime-rotate-y">コンテンツ</div>
<div class="content anime anime-rotate-y">コンテンツ</div>
<div class="content anime anime-rotate-y">コンテンツ</div>
</div>
</section>
今回のHTMLです。アニメーションをつけたい要素にanimeクラスとアニメーションの内容に応じたクラスを付与しておきます(anime-bottom等)。
CSS
.content-box{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
padding:16px 0;
}
.content{
width: 32vw;
height: 25vh;
font-size: 1.2rem;
background-color: #ccc;
margin-bottom: 16px;
text-align: center;
line-height: 25vh;
}
.space{
width: 100%;
height: 80vh;
}
.anime{
opacity: 0;
transition: all ease .5s;
}
.anime.is-active{
opacity: 1;
transform:none;
}
.anime-bottom{
transform: translateY(100px);
}
.anime-left{
transform: translateX(-100px);
}
.anime-right{
transform: translateX(100px);
}
.anime-big{
transform: scale(0.5);
}
.anime-small{
transform: scale(1.5);
}
.anime-rotate-x{
transform: rotateX(180deg);
}
.anime-rotate-y{
transform: rotateY(-180deg);
}
.heading{
font-size: 1.5rem;
text-align: center;
padding: 20px 0;
background-color: mediumturquoise;
}
@media screen and (max-width: 480px) {
.heading{
font-size: 0.8rem;
}
}
アニメーションはCSSでつけています。transformを使えば色々な動きがつけられますね!
JavaScript
animation_list = document.querySelectorAll('.anime');
const animation = ()=>{
let margin = 200;
for(i = 0 ; i < animation_list.length; i++){
let element_top = animation_list[i].offsetTop;
let nowDisplay = window.innerHeight + window.scrollY;
if(nowDisplay > element_top + margin){
animation_list[i].classList.add('is-active');
}
if(nowDisplay < element_top){
if(animation_list[i].classList.contains('is-active')){
animation_list[i].classList.remove('is-active');
}
}
}
}
window.addEventListener('load', animation);
window.addEventListener('scroll', animation);
今回のスクリプトです。
querySelectorAllを用いてanimeクラスのリストをanimation_listに格納します。
ウィンドウが読み込まれた時とスクロールした時にanimation関数を呼び出します。
animation関数
animeクラスが付与されている要素の数だけ繰り返し処理します。
変数element_topにanimeクラスが付与されている各要素の位置を代入します。
window.innerHeightで取得したブラウザのビューポートの高さにwindow.scrollYで取得したY方向のスクロール量を加算し、今どこを表示しているかを算出して変数nowDisplayに代入します。
要素が画面内にある場合はアニメーションさせながら表示します。変数marginの値を変更することで表示開始のタイミングを調整できるようにしました。
上方向へのスクロールやウィンドウの縦幅が小さくなる等でアニメーション済みの要素が画面外に行った場合その要素を非表示に戻しています。
おわりに
無事動くものが作れました。