どうも、くまだ です。
JavaScriptとSassをつかって、文字分割のアニメーションについて書いていきます。勉強したやつのアウトプットなので、オリジナルで考えたわけではありません。
今回使用する主なメソッドは、以下のメソッド。
- split()
- reduce()
文字分割のアニメーション htmlとSass
まずは完成版から。
これを作っていきます。最初にhtmlから。超カンタンな記述です。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="css/style.css">
<link href="https://fonts.googleapis.com/css2?family=Teko:wght@500&display=swap" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="animation">
アニメーション しますー。
</div>
</div>
<script src="main.js"></script>
</body>
</html>
次にSassのコードを書きます。
.container {
position: relative;
height: 100vh;
}
.animation {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
opacity: 0;
font-size: 24px;
font-weight: bold;
&.in {
opacity: 1;
.cat {
display: inline-block;
animation: cat_in 3s ease;
animation-delay: 0;
@for $i from 1 through 13 {
&:nth-child(#{$i}) {
animation-delay: $i * .06s;
}
}
}
}
}
@keyframes cat_in {
0% {
transform: translateY(-50%) rotate(-180deg);
opacity: 0;
}
100% {
transform: translate(0) rotate(360deg);
opacity: 1;
}
}
.in クラスはJavaScriptでクラスを付与させます。@keyframes cat_in でアニメーションの設定をしておきます。cat クラスは、JavaScriptでhtmlの文字を分割した文字一つ一つにあてるためのクラスです。
JavaScriptによって文章が1文字ずつに分割され、1文字ずつに.catクラスを付与。そしてcat_inアニメーションが入ります。
.catクラスが付与され、分割された文字はそれぞれ、@for文の記述のanimation-delayで0.06sずつ遅らせてアニメーションを動かします。
JavaScriptでも似たようなfor文(ループ処理)がありますが、それといっしょです。
@forの構文は以下のような記述です。
@for $変数名 from 開始値 through 終了値 {
// ここにスタイルをあてる処理を書く
}
もしくは、
@for $変数名 from 開始値 to 終了値 {
// ここにスタイルをあてる処理を書く
}
throughとto の違いは、
- throughは、その数値を含める
- to はその数値を含まない
以下は、参考記事です。
文字分割のアニメーション JavaScript
次にJavaScriptの記述を書いていきます。(\マークは、バックスラッシュに変換してください)
'use strict';
document.addEventListener('DOMContentLoaded',()=>{
const elm = document.querySelector('.animation');
elm.classList.add('in');
const cut = elm.innerHTML.trim().split("");
elm.innerHTML = cut.reduce((i, j) => {
j = j.replace(/\s+/, ' ');//replace:置換
return `${i}<span class="cat">${j}</span>`;
}, "");
});
addEventListener メソッドは、イベントリスナー(イベントに合わせて実行させる関数)を登録するためのメソッドです。
DOMContentLoadedイベントは、HTMLの初期文章の読込が完全に読み込まれたタイミングで発生します。(スタイルシート、画像などの読込の完了は待たない)
document.querySelector で.animationを取得し、変数 elmに格納。
格納したelmに、classList.add でin クラスを付与。
classList は、特定のクラス名を追加・削除・参照することができるプロパティです。
使い方としては、上記のように classList.add(クラス名)みたいな感じでつかいます。classList関係で使えるものだと以下のようなものがあります。
- add・・・クラス追加
- remove・・・クラス削除
- contains・・・クラスがあるか確認
- toggle・・・クラスがあれば削除、なければ追加
変数elmを、innerHTMLで操作します。
innerHTMLは、HTML要素の中身を変更することができるプロパティです。trim()で空白を取り除き、splitメソッドで文字列を分割しています。
splitメソッドは、例えば以下みたいな感じで使うことができます。
const Arry = 'yamada taro';
const ret = Arry.split("");
console.log(ret);
これをコンソール画面で見ると、
と、こんな感じで分割されます。
なので、elmをinnerHTMLによる操作によって、trim()によって空白を取り除き、splitで一文字ずつ分割してそれをcutに格納します。
そして次はreduceメソッドの部分ですが、以下のような構文で書きます。
reduce((累積値, 要素)={
});
例えば、reduce関数をつかって足し算をすると、
const num = [2,3,6,7,100];
const total = num.reduce((i,j)=>{
return i + j;
});
console.log(total); // 118
このように、複数個の配列やオブジェクトをひとつにまとめる関数です。
例えば、上記のアニメーションを一文字ずつ分割してそれぞれspanタグで括りたいとします。すると下記のような感じで書きます。
const NewArry = mojiArry.reduce((x, y)=> {
return `${x}<span>${y}</span>`;
});
console.log(NewArry);
これを検証ツールで確認すると、
分割された文字列にspanタグが挿入されています。
reduceメソッドの動きとしては、
〇1回目のループ:
初期値がx(xの中身はyamada taroの y )。
yにspanタグがつく(yの中身はyamada taro の a )。
〇2回目のループ:
xにはy<span>a</span>(1回目のループの結果)。
yにはspanタグがつく( yの中身はyamada taro の m )
〇3回目のループ:
xにはy<span>a</span><span>d</span>(2回目のループの結果)。
yにはspanタグがつく( yの中身はyamada taro の a )
以下、繰り返し。
そして、よく見ると最初の「y」がspanタグで括られていません。これを解決するためには、
const NewArry = mojiArry.reduce((x, y)=> {
return `${x}<span>${y}</span>`;
}, '');
console.log(NewArry);
前と変わったのは、}); を、 }, ”);に変更しただけです。
}, ”); の”には初期値を設定します。初期値に空文字を設定すると、上記のような処理になります。reduceメソッドの動きとしては、
〇1回目のループ:
初期値がx(xの中身は、初期値の空白” )。
yにspanタグがつく(yの中身はyamada taro の y )。
〇2回目のループ:
xには、空白<span>y</span>(1回目のループの結果)。
yにはspanタグがつく( yの中身はyamada taro の a )
〇3回目のループ:
xには、空白<span>y</span><span>a</span>(2回目のループの結果)。
yにはspanタグがつく( yの中身はyamada taro の m )
以下、繰り返し。
という感じになります。この要領で、<span class=”cat”></span>を挿入していきます。
elm.innerHTML = cut.reduce((i, j) => {
j = j.replace(/\s+/, ' ');//replace:置換
return `${i}<span class="cat">${j}</span>`;
}, ""); //初期値は空
});
replaceに関しては、以下参考記事です。
というわけで、以下の処理を行うと、文字分割アニメーションをつくることができます。
ここまで読んでくださりありがとうございました。