JavaScript | 文字が降るアニメーションサンプル
指定したHTML要素内に文字が降ってくるJavaScriptアニメーションです。
文字が降るJavaScriptアニメーションの使い方
以下は文字が降るJavaScriptアニメーションの動作サンプルになります。
オプションを指定する事で、文字の種類、色や、落下速度、サイズ、角度、回転、発光の有無などをカスタマイズができるようにしてあります。
See the Pen JavaScript | Falling Letters Animation by yochans (@yochans) on CodePen.
様々な文字が範囲外から降り注ぐアニメーションのJavaScriptコードは「falling_letters_animation.js」として以下の場所に置いてあります。
ダウンロード:falling_letters_animation.js(v.1.0)
ダウンロードしたjsファイルを読み込む、または既存のJavaScriptコードに貼り付けて利用できます。
<script src="falling_letters_animation.js"></script>
動作サンプルでは以下のHTMLを作成しています。<div>
要素の「container」内に文字を落下、降らせています。
画像のありなしや要素のサイズなど、変更しても対応できているはずです。
<div id="container"></div>
CSSは以下の通りです。
「aspect-ratio」でアスペクト比を固定しています。
#container {
width: 100%;
aspect-ratio: 3 / 1;
}
fallingLettersAnim()
という関数を実行する事で、指定したHTML要素に文字を降らせます。
オプションを指定する事でカスタマイズが可能です。
「target_element」以外のオプションは必須ではありません。
「target_element」が未指定の場合や存在しなかった場合、<body>
全体を対象にします。
//////////////////////////// call function
let option = {
target_element: '#container', // taget HTML element
where_to_insert: 'img', // Insert after the specified element in target_element. If unspecified, insert at the end of the target_element. ('img' 'p' '#id' etc)
letters_amount: 5, // Amount of letters (min 1 max 10)
letters_speed: 5, // Speed of letters (min 1 max 10)
letters_size: 1.0, // Size of letters (min 0.1)
letters_color: 'random', // Color of letters (hex, rgba, name, random)
letters_type: 'Aऄก', // select letter (aA1ऄกあア)
letters_angle: true, // Random default angle / affect rotation mode
letters_rotate_mode: 1, //Rotation mode (0=false 1=X 2=Y 3=XY)
letters_rotate_deg: 180, // (0 = false 720 = 720deg)
letters_rotate_reverse: true, // reverse rotation
letters_neon_light: true, // Emission of light from letters.
letters_neon_color: 'random', // Color of letters (hex, rgba, name, random)
animation_time: 600 // Animation time (s)
};
fallingLettersAnim(option);
fallingLettersAnim()
で利用可能なオプション設定です。
オプションの指定がないものはデフォルト値が割り当てられます。
オプション | 内容 | 初期値 |
---|---|---|
target_element | 文字を降らすHTML要素 | body |
where_to_insert | target_element内の指定した要素の次に挿入 未指定の場合はtarget_element内の最後に挿入 ('img’ 'p’ '#id’ など) | 未指定 |
letters_amount | 文字の量 (min 1 max 10) | 5 |
letters_speed | 文字の速さ (min 1 max 10) | 5 |
letters_size | 文字の多きさ (min 0.1) | 1 |
letters_color | 文字の色 (hex, rgba, name, random) | random |
letters_type | 抽出する文字の種類 ※平仮名なら「あ」を含める (aA1ऄกあア) | Aऄก |
letters_angle | 文字の角度をランダムにするか | true |
letters_rotate_mode | 文字の回転モード (0=false 1=X 2=Y 3=XY) | 1 |
letters_rotate_deg | 文字の回転量、単位はdeg、360以上も可 (0 = false 720 = 720deg) | 180 |
letters_rotate_reverse | 文字の逆回転 | true |
letters_neon_light | 文字を発光するかどうか | true |
letters_neon_color | 文字の発光色 (hex, rgba, name, random) | random |
animation_time | アニメーション時間 (s) | 60 |
- 「target_element」以外のオプションは必須ではありません。
- 「target_element」が未指定の場合や存在しなかった場合、<body>全体を対象にします。
- 「letters_amount」を未指定の場合、「target_element」の最後に追加されますが、指定するとその要素の次に追加されます。
- 文字の種類は、例えばアルファベットの大文字と平仮名にする場合は「Aあ」と指定できます。
- ランダム角度を有効にしてX軸回転、Y軸回転を選択した場合は斜めに回転します。
- 回転量にて回転速度を調節できます。
- 文字の発光はネオン文字みたいになります。
- アニメーション時間経過後、アニメーションは停止します。指定に制限はありません。
文字が降るアニメーションのJavaScriptコード詳細
以下は文字が降るアニメーションの実行部分のJavaScriptコードになります。
- 対象のHTML要素が見つからない場合は
<body>
を対象とします。 - ランダム色はスクリプトで生成しています。
- 平仮名・片仮名はString.fromCharCode()でユニコードから取得しています。
// drop letters animation function
const fallingLettersAnim = (option) => {
// default option
let default_option = {
target_element: 'body', // taget HTML element
where_to_insert: 'img', // Insert after the specified element in target_element. If unspecified, insert at the end of the target_element. ('img' 'p' '#id' etc)
letters_amount: 5, // Amount of letters (min 1 max 10)
letters_speed: 5, // Speed of letters (min 1 max 10)
letters_size: 1.0, // Size of letters (min 0.1)
letters_type: 'Aऄก', // select letter (aA1ऄกあア)
letters_angle: true, // Random default angle / affect rotation mode
letters_rotate_mode: 1, //Rotation mode (0=false 1=X 2=Y 3=XY)
letters_rotate_deg: 180, // (0 = false 360 = 360deg)
letters_rotate_reverse: true, // reverse rotation
letters_color: 'random', // Color of letters (hex, rgba, name, random)
letters_neon_light: true, // Emission of light from letters.
letters_neon_color: 'random', // Color of letters (hex, rgba, name, random)
animation_time: 600 // Animation time (s)
};
// merge option
let op = Object.assign(default_option, option);
// whether the target element exists
if (!document.querySelector(op.target_element)) {
console.log('no target element.');
return;
}
// target element
let target_element = document.querySelector(op.target_element);
target_element.style.position = 'relative';
target_element.style.overflow = 'hidden';
// Insert after the specified element
let insert_after_element = '';
if (op.where_to_insert != '') {
insert_after_element = target_element.querySelector(op.where_to_insert);
}
// main container
let container = document.createElement('div');
if (!insert_after_element) {
target_element.appendChild(container);
} else {
insert_after_element.after(container);
}
container.style.position = 'absolute';
container.style.top = 0;
container.style.left = 0;
container.style.width = '100%';
container.style.height = '100%';
container.style.overflow = 'hidden';
// letters container
let letters_container = document.createElement('div');
container.appendChild(letters_container);
letters_container.style.position = 'absolute';
letters_container.style.width = '100%';
letters_container.style.height = '100%';
// letter clone
let letter = document.createElement('div');
letter.style.position = 'absolute';
letter.style.opacity = 1;
letter.style.fontFamily = '';
// letters
let chars = '';
if (op.letters_type.includes('a')) {
chars += 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz';
}
if (op.letters_type.includes('A')) {
chars += 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ';
}
if (op.letters_type.includes('1')) {
chars += '012345678901234567890123456789012345678901234567890123456789';
}
if (op.letters_type.includes('ऄ')) {
chars += 'ऄअआइईउऊऋऌऍऎएऐऑऒओऔकखगघङचछजझञटठडढणतथदधनऩपफबभमयरऱलळऴवशषसह';
}
if (op.letters_type.includes('ก')) {
chars += 'กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ';
}
if (op.letters_type.includes('あ')) {
for (let i = 12353; i < 12435; i++) {
chars += String.fromCharCode(i);
}
}
if (op.letters_type.includes('ア')) {
for (let i = 12439; i < 12538; i++) {
chars += String.fromCharCode(i);
}
}
let colors = [];
if (op.letters_color == 'random' || op.letters_neon_color == 'random') {
for (let i = 0; i < 110; i++) {
colors.push('#' + Math.floor(Math.random() * 16777215).toString(16));
}
}
;
let letters = '';
for (var i = 0; i < 500; i++) {
letters += chars.charAt(Math.floor(Math.random() * chars.length));
}
let no = 0;
let count = 0;
op.animation_time *= 60;
const update = () => {
let rand1 = Math.floor(Math.random() * 110);
let rand2 = Math.floor(Math.random() * 100);
// font color
let letters_color = op.letters_color;
if (op.letters_color == 'random') {
letters_color = colors[rand1];
}
// neon color
let letters_neon_color = op.letters_neon_color;
if (op.letters_neon_color == 'random') {
letters_neon_color = colors[rand2];
}
// angle
let angle = 0;
if (op.letters_angle == true) {
angle = Math.floor(Math.random() * 360);
}
// rotate set reverse
if (rand2 % 2 == 0 && op.letters_rotate_reverse == true) {
op.letters_rotate_deg = -(op.letters_rotate_deg);
}
// rotate set
let angle_set = 0;
let rotate_angle_set = '';
if (op.letters_rotate_mode == 0) {
rotate_angle_set = `rotateX(0deg)`;
rotate_angle_set = `rotateX(0deg)`;
} else if (op.letters_rotate_mode == 1) {
angle_set = `rotate(${angle}deg)`;
rotate_angle_set = `rotateX(${angle + op.letters_rotate_deg}deg)`;
} else if (op.letters_rotate_mode == 2) {
angle_set = `rotate(${angle}deg)`;
rotate_angle_set = `rotateY(${angle + op.letters_rotate_deg}deg)`;
} else if (op.letters_rotate_mode == 3) {
angle_set = `rotate(${angle}deg)`;
rotate_angle_set = `rotate(${angle + op.letters_rotate_deg}deg)`;
}
// letter drop
if (count % (11 - op.letters_amount) == 0) {
let letter_clone = letter.cloneNode();
letter_clone.innerText = letters[no];
letter_clone.style.fontSize = `${0.1 * rand2 * op.letters_size}vw`;
letter_clone.style.left = `${rand1 - 10}%`;
letter_clone.style.color = letters_color;
letter_clone.style.transform = `rotate(${angle}deg)`;
if (op.letters_neon_light == true) {
letter_clone.style.textShadow = `
0 0 1.0em ${letters_neon_color},
0 0 0.5em ${letters_neon_color},
0 0 0.1em ${letters_neon_color}
`;
}
letters_container.appendChild(letter_clone);
let letters_anim = letter_clone.animate(
[
{ top: `-20%`, transform: angle_set },
{ top: `100%`, transform: rotate_angle_set }
],
{
fill: 'forwards',
duration: 6000 / op.letters_speed
}
);
letters_anim.onfinish = (event) => {
letter_clone.remove();
};
if (no < 499) {
no++;
} else {
no = 1;
}
}
// stop or run animation
count++;
if (op.animation_time >= count) {
requestAnimationFrame(update);
} else {
cancelAnimationFrame(update);
}
};
update();
};
ディスカッション
コメント一覧
まだ、コメントがありません