javascriptでテキストがシャカシャカと流暢に流れるアニメーション。Flashの時代からずっと存在し続ける息の長いこのアニメーションは、尊敬する中村勇吾氏の専売特許のような印象。主張し過ぎない佇まいがチャーミングなjavascript animationです。
この文字がシャッフルするアニメーション。個人的には好みなのですが、調べてみるとあまり情報も多くないので、練習がてらに自分でこのjavascript animationを書いてみました。それなりに簡単には書けてると思うので少し雑ですが読んでくれる皆様に意味が伝達してくれれば幸いです。
先に分かり易いようにシンプルに絞ったコードを提示します。制作したjavascriptのコードは以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
<!DOCTYPE html> <!-- --> <html> <head> <title>js animation shuffle txt 1</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> </head> <body> <div id="letter">flowers or beautifully yet and over % _ _.</div> <script> (function ($) { $(document).ready(function () { var node = document.querySelector('#letter'); var str = node.textContent.split(''); //文字を分割strに代入 var types = []; //ランダム表示する文字のタイプの配列 var index = []; //始動時の順序の配列。ランダムに表示させるために使用 var step = 3; //繰り返しの数何週するか var fps = 20; //表示スピード var strClone = []; //strクローン用の配列 var typeClone = []; //typeクローン用の配列 for (var i = 0; i <= str.length; i++) { index[i] = i; //文字の長さ分だけ格納。あとでシャッフルする。 types[i] = 'symbol'; //randomCharでsymbolを返す。 typeClone[i] = 'first'; //randomCharでfirstをを返す。 }; // ランダム文字を生成して返す。 var randomChar = function (type) { var pool; switch (type) { case 'symbol': pool = '?/\\(^)![]abcdefghijklmnopqrstuvwxyz0123456789{}*&^%$'; break; case 'first': pool = '---'; break; default: pool = ''; } return pool.charAt(Math.floor(Math.random() * pool.length)); }; //初期化。 var j = 0; var k = 0; node.textContent = ''; // ランダム文字を織り交ぜながら一文字ずつ表示させる。メインです。 var ticker = function () { if (k > str.length) { k = str.length; //str.lengthを超えたらstr.lengthで止める。 //理由はそれ以上文字がないから止まっちゃうので。 } //Math.max(a, 0); aと0を比較して値の大きい方を返します。aがマイナスの値の間は0。 for (var i = Math.max((j + ((step - 1) * - str.length)), 0); i < k; i++ ) { strClone[Math.abs(i)] = randomChar(typeClone[Math.abs(i)]); //strCloneにランダムな文字列を返す。first or symbol if (k >= str.length) { typeClone.splice(Math.abs(j - str.length), 1, types[Math.abs(i)]); //typeCloneの中身を入れ替える。from first to symbol }; if ((j + ((step - 1) * - str.length)) >= 0) { strClone[Math.abs(j + ((step - 1) * - str.length))] = str[Math.abs(j + ((step - 1) * - str.length))]; //strCloneの中身をランダムな文字列から最初の文字列に戻す。 }; }; node.textContent = strClone.join(''); //ループkから抜けた現在のstrCloneの中身をtimer措きに'#letter'の中に追加していきます。 if (j === step * str.length) { return; //この条件で終了。 }; j++; k++; return setTimeout(function () { ticker(); }, 1000 / fps); }; ticker(); }); })(jQuery); </script> </body> </html> |
それではテキストをシャッフルするjsの説明に入ります。str.lengthが分かれば多分理解できると思います。
ランダムの文字列用の配列
types[],typeClone[]の二つの配列にランダム文字を生成する時のフックになる文字列を実際のテキストの文字列分だけ代入します。メインのところでrandomChar関数を呼び出す時に使用します。types[]には’symbol’がtypeClone[]には’first’がテキストの文字列分だけ入ります。
文字列の初期化
冒頭のところで変数strに実際の文字列を保存してあるので、div id=”letter”の中身の文字列をメインスクリプトを走らす前にnode.textContent = ”;で空にします。
ticker関数内のfor文の条件
ticker関数の中身がこのプログラムのメインになります。冒頭の変数stepを確認すると3が入っています。本当に申し分けないのですが、str.lengthが3回分の意味以外なにもありません。
もしこのテキストをシャッフルするjavascriptアニメーションのstr.lengthが10と仮定した時、1回目10、2回目10、3回目10でtimerは30回回ります。ただし1回目、2回目、3回目ではそれぞれでfor文の条件が変わってきます。それではそれぞれのfor文の条件を確認していきます。
まず1回目、str.lengthを10と仮定すると、(j + ((step – 1) * – str.length))の初期値は(0 +(2 × -10))で-20、結果Math.max((j + ((step – 1) * – str.length)), 0)は0と-20の最大値をとるので0を取ります。1回目の10回のtimerではjの最大値は9までなのでMath.max((j + ((step – 1) * – str.length))の返す値は0に固定されます。そしてkは0から9まで変動するので、for文の条件は1回のtimer措きに0<i<0,0<i<1,0<i<2…0<i<9と条件が変化します。1回のtimer(1回のfor文)ごとにnode.textContent = strClone.join(”);で文字を追加していくので1文字目、2文字目と文字が増加していく状態を作り出します。
2回目はjに入る最大値は19ですのでMath.max((j + ((step – 1) * – str.length))は0で固定されます。またkはstr.lengthで固定されるため10で固定され、結果for文の条件は0<i<10で固定されます。10回のtimerで繰り返すことにより文字をランダムに変化さる状態を作り出しています。
それではラスト3回目です。まずkはstr.lengthで固定されるため10です。jには20から29が入るのでMath.max((j + ((step – 1) * – str.length))は0から9の値を取ります。for文の条件は0<i<10,1<i<10,2<i<10…9<i<10と変化していき、結果、左から順に文字を固定していきます。
ticker関数内のfor文の中身
特に書かなくても良いかな的なのですが一応綴っておきます。最初にstrClone[Math.abs(i)] = randomChar(typeClone[Math.abs(i)]);。1回目の状態ではtypeCloneにはすべて’first’が入っているので、’- – -’の文字列をランダムに返します。2回目以降はtypeClone.splice(Math.abs(j – str.length), 1, types[Math.abs(i)]);でtypeClone配列のすべての’first’を’symbol’に書き換えるので、symbolに代入された文字列がシャッフルされて返ってきます。3回目にstrClone[Math.abs(j + ((step – 1) * -str.length))] = str[Math.abs(j + ((step – 1) * -str.length))];でstr変数に保存しておいた元の文字列をstrClone配列に代入して、node.textContent = strClone.join(”);でジョインして終了です。
2順目の文字の出現をさらにシャッフルする
javascriptで文字をシャッフルするプログラムを少し変更して2順目で文字が左から順番に出現していたのをランダムに出現するよう改造します。