ヒラヒラうふふ!桜の JavaScript のカスタマイズ方法から導入・設置まで!

桜の JavaScript のカスタマイズ
サクラ+カスタマイズで「サクラマイズ」って心の中で言っています。

はじめに

この記事は前に書いた「春風そよよ〜!桜の花びらがヒラヒラ舞い落ちるスクリプトだよー!」のカスタマイズやアレンジ方法のお助け記事です。(スマートフォンで使っていただけると思っていなかったので、スマホ対応も少し。)

JavaScript が分からなくとも HTML&CSS が分かれば比較的簡単にカスタマイズして使っていただける、と思っています。JavaScript の内容の記事にしては反響があったと思いますし、みなさん設置される時に色々とカスタマイズされてる様だったのでもう少し詳しく書いていたら良かったなー、と反省も含みます。

カスタマイズ!

説明対象になるのは、前回の記事の最後の、全部入れsakura.8222.7.jsです。(実際に動きを見てみる)これの変数を分かりやすい名前に変更しスペース等を入れた物、さらにそれにコメントを入れた物の2ファイル用意してみました。

+コメントを入れたファイル

/* sakura.8351.1.js にコメント入れたバージョン */

(function(){
	var divSakura = document.createElement('div'); /* 大枠になるdivを作る */
	divSakura.id = "sakura"; /* id を追加する */

	/* 以下 div の中に追加する html(style タグと css を追加しています) */
	divSakura.innerHTML = '<style>'+
	'html,body{overflow-x:hidden;}'+
	'.hana{'+
	'position:absolute;height:0;width:0;'+
	'border: 10px solid pink;'+
	'border-radius: 15px;'+
	'border-top-right-radius: 0;'+
	'border-bottom-left-radius: 0;}'+
	'.hana::after{'+
	'content:"";display:block;position:absolute;top:-7px;left:-7px;height:0;width:0;'+
	'border: 10px solid pink;'+
	'border-radius: 15px;'+
	'border-top-right-radius: 0;'+
	'border-bottom-left-radius: 0;'+
	'-webkit-transform: rotate(15deg);-ms-transform: rotate(15deg);transform: rotate(15deg);'+
	'}'+

	'.t1{border-color:#fff3f5;}'+
	'.t2{border-color:#ffe2e7;}'+
	'.t3{border-color:#ffd1d9;}'+
	'.t4{border-color:#ffc0cb;}'+
	'.t5{border-color:#ffafbd;}'+
	'.t6{border-color:#ffafbd;}'+
	'.t1::after{border-color:#fff3f5;}'+
	'.t2::after{border-color:#ffe2e7;}'+
	'.t3::after{border-color:#ffd1d9;}'+
	'.t4::after{border-color:#ffc0cb;}'+
	'.t5::after{border-color:#ffafbd;}'+
	'.t6::after{border-color:#ffafbd;}'+

	'.y1{-webkit-animation:v1 10s infinite;animation:v1 10s infinite;}'+
	'.y2{-webkit-animation:v2 10s infinite;animation:v2 10s infinite;}'+
	'.y3{-webkit-animation:v3 9s infinite;animation:v3 9s infinite;}'+
	'.y4{-webkit-animation:v4 9s infinite;animation:v4 9s infinite;}'+
	'.y5{-webkit-animation:v5 8s infinite;animation:v5 8s infinite;}'+
	'.y6{-webkit-animation:v6 8s infinite;animation:v6 8s infinite;}'+
	'@-webkit-keyframes v1{'+
		'from{-webkit-transform: rotate(0deg) scale(1);}'+
		'50%{-webkit-transform: rotate(270deg) scale(1);}'+
		'to{-webkit-transform: rotate(1deg) scale(1);}'+
	'}'+
	'@-webkit-keyframes v2{'+
		'from{-webkit-transform: rotate(-90deg) scale(.9);}'+
		'50%{-webkit-transform: rotate(-360deg) scale(.9);}'+
		'to{-webkit-transform: rotate(-89deg) scale(.9);}'+
	'}'+
	'@-webkit-keyframes v3{'+
		'from{-webkit-transform: rotate(30deg) scale(.8);}'+
		'50%{-webkit-transform: rotate(300deg) scale(.8);}'+
		'to{-webkit-transform: rotate(29deg) scale(.8);}'+
	'}'+
	'@-webkit-keyframes v4{'+
		'from{-webkit-transform: rotate(-120deg) scale(.7);}'+
		'50%{-webkit-transform: rotate(-390deg) scale(.7);}'+
		'to{-webkit-transform: rotate(-119deg) scale(.7);}'+
	'}'+
	'@-webkit-keyframes v5{'+
		'from{-webkit-transform: rotate(60deg) scale(.6);}'+
		'50%{-webkit-transform: rotate(330deg) scale(.6);}'+
		'to{-webkit-transform: rotate(59deg) scale(.6);}'+
	'}'+
	'@-webkit-keyframes v6{'+
		'from{-webkit-transform: rotate(-150deg) scale(.5);}'+
		'50%{-webkit-transform: rotate(-420deg) scale(.5);}'+
		'to{-webkit-transform: rotate(-149deg) scale(.5);}'+
	'}'+
	'@keyframes v1{'+
		'from{transform: rotate(0deg) scale(1);}'+
		'50%{transform: rotate(270deg) scale(1);}'+
		'to{transform: rotate(1deg) scale(1);}'+
	'}'+
	'@keyframes v2{'+
		'from{transform: rotate(-90deg) scale(.9);}'+
		'50%{transform: rotate(-360deg) scale(.9);}'+
		'to{transform: rotate(-89deg) scale(.9);}'+
	'}'+
	'@keyframes v3{'+
		'from{transform: rotate(30deg) scale(.8);}'+
		'50%{transform: rotate(300deg) scale(.8);}'+
		'to{transform: rotate(29deg) scale(.8);}'+
	'}'+
	'@keyframes v4{'+
		'from{transform: rotate(-120deg) scale(.7);}'+
		'50%{transform: rotate(-390deg) scale(.7);}'+
		'to{transform: rotate(-119deg) scale(.7);}'+
	'}'+
	'@keyframes v5{'+
		'from{transform: rotate(60deg) scale(.6);}'+
		'50%{transform: rotate(330deg) scale(.6);}'+
		'to{transform: rotate(59deg) scale(.6);}'+
	'}'+
	'@keyframes v6{'+
		'from{transform: rotate(-150deg) scale(.5);}'+
		'50%{transform: rotate(-420deg) scale(.5);}'+
		'to{transform: rotate(-149deg) scale(.5);}'+
	'}'+

	'</style>';

	document.body.appendChild(divSakura); /* body タグに大枠の div を追加します */

	var windowHeight = window.innerHeight; /* ウィンドウの高さを取得 */
	var scroll = document.documentElement.scrollTop || document.body.scrollTop; /* スクロールの位置を取得 */
	var styleZindex = 9999; /* 花びらの z-index (9999から開始) */
	var styleTop = new Array(); /* 花びらの top 位置配列 */
	var styleLeft = new Array(); /* 花びらの left 位置配列 */
	var yuragi = new Array(); /* ゆらぐ幅の配列 */
	var sokudo = new Array(); /* 落下速度の配列 */
	var hanabiraId = new Array(); /* 花びらのIDの配列 */
	var yuragiConut = new Array(); /* 揺らぎのカウンター配列 */
	var kazeCount = 0; /* 横風のカウンター */

	/* スクロール時のイベント登録(スクロールされても花びらがウィンドウ内に収まる様に) */
	document.addEventListener('scroll', function(){ scroll = document.documentElement.scrollTop || document.body.scrollTop; }, false);

	/* 花びら50枚用意する */
	for(var i = 0; i < 50; i++){
		var divHanabira = document.createElement('div'); /* 花びらの div を作る */
		divHanabira.id = 'hanabira' + i; /* id を追加する(例:<div id="hanabira0">) */
		styleTop[i] = Math.random() * -1000 + scroll; /* 初期表示位置(top)をランダムに取得 */
		styleLeft[i] = Math.random() * window.innerWidth; /* 初期表示位置(left)をウィンドウの幅内でランダムに取得 */
		divHanabira.setAttribute('style', 'z-index:' + (styleZindex + i) + ';top:' + styleTop[i] + 'px;left:' + styleLeft[i] + 'px;'); /* 花びら div に style を追加 */
		var hanabiraClass = 'hana t' + (Math.floor(Math.random() * 6) + 1) + ' y' + (Math.floor(Math.random() * 6) + 1); /* 花びら div の class を用意 */
		divHanabira.setAttribute('class', hanabiraClass); /* 花びら div に class を追加 */
		divSakura.appendChild(divHanabira); /* 大枠の div に花びら div を追加 */
		yuragi[i] = Math.random() * 40 + 5; /* 揺らぐ幅をランダムに取得 */
		sokudo[i] = Math.random() * 5 + 2; /* 落下速度をランダムに取得 */
		hanabiraId[i] = document.getElementById('hanabira' + i); /* あとあと扱いやすい様に花びらに id を配列に格納 */
		yuragiConut[i] = 0; /* 揺らぎカウンターの初期値は0 */
	}

	/* 花びらを動かす(45ミリ秒毎に繰り返し) */
	setInterval(function(){

		/* 花びらの位置を制御(50枚動かす) */
		for(var i = 0; i < 50; i++){
			if(styleTop[i] < scroll + windowHeight - 40){ /* 花びらの位置(top)がウィンドウ内なら */
				if(yuragi[i] >= yuragiConut[i]){ /* 揺らぐ幅(右へ移動)内なら */
					styleLeft[i] = styleLeft[i] + 0.5 + Math.random() * 0.5;
				}else{ /* 揺らぐ幅(左へ移動)内なら */
					styleLeft[i] = styleLeft[i] - 0.5 - Math.random() * 0.5;
				}
				if((yuragi[i] * 2) <= yuragiConut[i]){ /* ゆらぎの幅の2倍なら */
					yuragiConut[i] = 0; /* カウンターリセット */
				}
			}else{ /* 花びらがウィンドウの下まできたら */
				styleTop[i] = scroll - 40; /* 花びらを上に戻す(スクロール位置より-40) */
				styleLeft[i] = Math.random() * window.innerWidth; /* 花びら表示位置(left)をランダムに */
			}


/* ここから横風 */

			/* 風カウンターの数値により右への移動を加算 */
			if(kazeCount >= 100 && kazeCount <= 110){ styleLeft[i] = styleLeft[i] + 1; }
			else if(kazeCount >= 111 && kazeCount <= 120){ styleLeft[i] = styleLeft[i] + 3; }
			else if(kazeCount >= 121 && kazeCount <= 129){ styleLeft[i] = styleLeft[i] + 5; }
			else if(kazeCount >= 130 && kazeCount <= 137){ styleLeft[i] = styleLeft[i] + 7; }
			else if(kazeCount >= 138 && kazeCount <= 144){ styleLeft[i] = styleLeft[i] + 9; }
			else if(kazeCount >= 145 && kazeCount <= 300){ styleLeft[i] = styleLeft[i] + 11; }
			else if(kazeCount >= 301 && kazeCount <= 311){ styleLeft[i] = styleLeft[i] + 9; }
			else if(kazeCount >= 312 && kazeCount <= 322){ styleLeft[i] = styleLeft[i] + 7; }
			else if(kazeCount >= 323 && kazeCount <= 335){ styleLeft[i] = styleLeft[i] + 5; }
			else if(kazeCount >= 336 && kazeCount <= 349){ styleLeft[i] = styleLeft[i] + 3; }
			else if(kazeCount >= 350 && kazeCount <= 354){ styleLeft[i] = styleLeft[i] + 1; }

			/* 風カウンターの数値により左への移動を加算 */
			else if(kazeCount >= 500 && kazeCount <= 510){ styleLeft[i] = styleLeft[i] - 1; }
			else if(kazeCount >= 511 && kazeCount <= 520){ styleLeft[i] = styleLeft[i] - 3; }
			else if(kazeCount >= 521 && kazeCount <= 529){ styleLeft[i] = styleLeft[i] - 5; }
			else if(kazeCount >= 530 && kazeCount <= 537){ styleLeft[i] = styleLeft[i] - 7; }
			else if(kazeCount >= 538 && kazeCount <= 544){ styleLeft[i] = styleLeft[i] - 9; }
			else if(kazeCount >= 545 && kazeCount <= 700){ styleLeft[i] = styleLeft[i] - 11; }
			else if(kazeCount >= 701 && kazeCount <= 711){ styleLeft[i] = styleLeft[i] - 9; }
			else if(kazeCount >= 712 && kazeCount <= 722){ styleLeft[i] = styleLeft[i] - 7; }
			else if(kazeCount >= 723 && kazeCount <= 735){ styleLeft[i] = styleLeft[i] - 5; }
			else if(kazeCount >= 736 && kazeCount <= 749){ styleLeft[i] = styleLeft[i] - 3; }
			else if(kazeCount >= 750 && kazeCount <= 754){ styleLeft[i] = styleLeft[i] - 1; }

			else if(kazeCount >= 900){ kazeCount = 0; } /* カウンターリセット */

/* ここまで横風 */

			styleTop[i] = styleTop[i] + sokudo[i]; /* 表示位置(top)に速度分追加 */
			hanabiraId[i].style.top = styleTop[i] + 'px'; /* 実際に top に数値を反映させる */
			hanabiraId[i].style.left = styleLeft[i] + 'px'; /* 実際に left 数値を反映させる */
			yuragiConut[i]++; /* 揺らぎカウンターに1足す */
		}
		kazeCount++; /* 風カウンターに1足す */
	}, 45);
})();

桜スクリプトのおおまかな流れ

  1. <div id=”sakura”></div> を用意する
  2. その中に <style> … </style> を追加する
  3. それを <body> … </body> に追加する
  4. 次に <div id=”hanabira0″ class=”hana t1 y1″ style=”z-index:10000;top:-300px;left:300px;'”></div> みたいなのを50個用意する
  5. <div id=”sakura”> … </div> に追加する
  6. setInterval(function(){ … },45); で繰り返し動かす

変数一覧

変数 意味
divHanabira 花びらのdiv
divSakura 大枠のdiv
hanabiraClass 花びらのdivのclass(文字列)
hanabiraId 花びらのIDの配列(文字列)
kazeCount 横風のカウンター(数値)
scroll スクロール(y)の位置(数値)
sokudo 落下速度の配列(数値)
styleLeft 花びらの位置(x)の配列(数値)
styleTop 花びらの位置(y)の配列(数値)
styleZindex 花びらのz-index(数値)
windowHeight ウィンドウの高さ(数値)
yuragi ゆらぐ幅の配列(数値)
yuragiConut 揺らぎのカウンター配列(数値)

CSS の指定で気を付ける事!

主な CSS の指定は、8行〜105行の間に書いています。見やすい様にタブと改行が入っていますが、JavaScript の構文中なので「(シングルクォーテーション)」で挟む事と、継続して書く場合は「+(プラス)」、終わる場合は「;(セミコロン)」が必要になります。

CSS が1行だけの場合の例

divSakura.innerHTML = '<style>html,body{overflow-x:hidden;}.hana{position:absolute;height:0;width:0;}</style>';

1行で書く事もできます。(指定する CSS が少ない、または可読性を落として良いなら)

CSS が複数行の場合の例

divSakura.innerHTML = '<style>'+
'html,body{overflow-x:hidden;}'+
'.hana{'+
	'position:absolute;height:0;width:0;'+
	'border: 10px solid pink;'+
	'border-radius: 15px;'+
	'border-top-right-radius: 0;'+
	'border-bottom-left-radius: 0;}'+
'.hana::after{'+
	'content:"";display:block;position:absolute;top:-7px;left:-7px;height:0;width:0;'+
	'border: 10px solid pink;'+
	'border-radius: 15px;'+
	'border-top-right-radius: 0;'+
	'border-bottom-left-radius: 0;'+
	'-webkit-transform: rotate(15deg);-ms-transform: rotate(15deg);transform: rotate(15deg);'+
'}</style>';

‘CSSの文字列’+」なら、途中に改行入れて複数業に股がっても、タブを入れても半角スペースを入れても問題ありません。あとあと見やすい様に入れておくと無難かもしれません。

class の指定で気を付ける事

/* 130行あたりね↓ */
		var hanabiraClass = 'hana t' + (Math.floor(Math.random() * 6) + 1) + ' y' + (Math.floor(Math.random() * 6) + 1); /* 花びら div の class を用意 */
		divHanabira.setAttribute('class', hanabiraClass); /* 花びら div に class を追加 */

このスクリプトは class を「t1 〜 t6」と「y1 〜 y6」の2タイプを6個ずつ作って、花びらの div にランダムに追加しています。

<div id="hanabira0" class="hana t3 y2" style="...省略..."></div>
<div id="hanabira1" class="hana t6 y1" style="...省略..."></div>
<div id="hanabira2" class="hana t4 y5" style="...省略..."></div>
<div id="hanabira3" class="hana t1 y6" style="...省略..."></div>

実行されるとこんな感じで花びらの div が作られます。

/* 130行あたりね↓ */
		var hanabiraClass = 'hana t' + (Math.floor(Math.random() * 6) + 1); /* 花びら div の class を用意 */
		divHanabira.setAttribute('class', hanabiraClass); /* 花びら div に class を追加 */

class を1タイプ減らすとこんな感じになります。「t1 〜 t6」をランダムに。

/* 130行あたりね↓ */
		var hanabiraClass = 'hana t' + (Math.floor(Math.random() * 6) + 1) + ' y' + (Math.floor(Math.random() * 6) + 1) + ' r' + (Math.floor(Math.random() * 6) + 1); /* 花びら div の class を用意 */
		divHanabira.setAttribute('class', hanabiraClass); /* 花びら div に class を追加 */

逆に class を1タイプ増やすとこんな感じです。「t1 〜 t6」と「y1 〜 y6」それに「r1 〜 r6」が新たに追加されました。

Math.floor(Math.random() * 6) + 1

「t1 〜 t6」などと、6個の class をランダムに追加出来るようにしていますが、この数を減らしたい(増やしたい)場合は6の部分を変更してください。

/* 130行あたりね↓ */
		var hanabiraClass = 'hana t' + (Math.floor(Math.random() * 2) + 1) + ' y' + (Math.floor(Math.random() * 5) + 1) + ' r' + (Math.floor(Math.random() * 20) + 1); /* 花びら div の class を用意 */
		divHanabira.setAttribute('class', hanabiraClass); /* 花びら div に class を追加 */

「t1 〜 t2」と「y1 〜 y5」と「r1 〜 r20」を使いたい場合はこんな感じになります。

ランダムな数値の取得

乱数の取得にMath.random()を、少数点以下の切り捨てにMath.floor()を使っています。

Math.floor(Math.random() * 6) + 1

これを実行すると1〜6が得られます。

例)Math.random()で 0.6749259305652231 の数値得てそれを6倍した4.049555583391339 をMath.floor()で小数点以下を切り捨ててさらに1加えると5が得られます。

花びらの枚数を減らしたい(増やしたい)!

今回のスクリプトはデモ用に50枚にしていますが、実際に使っていただくとかなりウザい事になると思います。みなさん減らされて使っていただいてますもんね!花びらの枚数減らす(増やす)には2カ所の数値を変更するだけでOKです!

/* 123行あたりね↓ */
	/* 花びら50枚用意する */
	for(var i = 0; i &lt; 50; i++){
/* 142行あたりね↓ */
		/* 花びらの位置を制御(50枚動かす) */
		for(var i = 0; i &lt; 50; i++){

50をお好きな数値に変更してください!
※枚数を多くしすぎると重くなるので注意が必要です。

参考にお使いいただけたサイトでの枚数をピックアップ!(ちょっと時期を逃してしまったみたいで、もう使っていただけていないサイトもありました。しくしく… 時期が限られていますもんね!)

全体の動きを速めたい(遅めたい)!

場合によってはもうスピーディーに!逆にスローにしたい事もありますよね?

/* 196行あたりね↓ */
		kazeCount++; /* 風カウンターに1足す */
	}, 45);
})();

最後の45の数値を、速めたい場合は小さく遅めたい場合は大きくしてみてください。ここの数値はsetInterval()のミリ秒なので、大きめなら70とか、小さめなら20とか色々試してみてください。

横風が邪魔だ!

横風が必要ない場合もありますよねw
159行〜189行を削除するかコメントアウトするとかしてください。

揺らぐ幅を大きく(小さく)!

/* 133行あたりね↓ */
		yuragi[i] = Math.random() * 40 + 5; /* 揺らぐ幅をランダムに取得 */

133行目の40の数値を変更してみてください。大きくすると揺らぐ幅が大きく、逆は小さくなります。

落下速度を速く(遅く)!

/* 134行あたりね↓ */
		sokudo[i] = Math.random() * 5 + 2; /* 落下速度をランダムに取得 */

134行目の5の数値を変更してみてください。大きくすると落下速度は速く、逆は遅くなります。

桜はもう見飽きた!

な、…そうですよねー
もう桜の時期は終わりですもんねー

スマートフォンでも使いたい!

桜のスクリプトは APPPS! さんからも記事で紹介していただけまして、iPhoneからのアクセスも多かったんですよ〜!なので、スマートフォン用に調整した物も用意してみました。少しの変更で大丈夫でしょ、と考えてましたが甘かったですw

花びらを10枚に減らしたり、落下速度、揺らぎ、横風等の数値を調節してスマートフォンからでも使用しやすくしてみました。

デモをみる
download

ブックマークレットもどうぞ!

スマートフォン用に調節した物のブックマークレットも用意しました!パソコン用の物はさぞ重かった事と想像します、こちらに置き換えていただけたらな〜、と思います!

Android用(URLエンコード無し)

Android の登録方法は以前に こちら で詳しく書きましたので参考にしてみてください。

iPhone用(URLエンコード有り)

桜のブックマークレット

iPhone は、上記リンクを開いてそのページを一旦ブックマークして URL 先頭部分の「http://actyway.com/?」のみを削除して「javascript:」からはじまる状態で保存しなおせば OK だと思います。

導入・設置!

この桜のスクリプトは body タグに要素の追加をしますので、body タグが無い場合、または見つからないタイミングでの実行をするとエラーが出て正常に動きませんので気を付けてください!

単純に読み込ませたい

<body>
<!-- ...色々他のタグがあるとして... -->

<script type="text/javascript" src="sakura.js"></script>
</body>

body タグの閉じる直前で読み込ませるのが無難かなーと思います。

パソコン用に読み込ませたい

<body>
<!-- ...色々他のタグがあるとして... -->

<script type="text/javascript">
	(function(u,d){
		/* ユーザーエージェントに iPhone と Android を含まないなら */
		if(u.indexOf('iPhone')==-1 && u.indexOf('Android')==-1){
			var j = d.createElement('script');
			j.src = 'sakura.js';	/* 桜のスクリプトのパス or URL */
			d.body.appendChild(j);
		}
	})(navigator.userAgent,document);
</script>
</body>

スマートフォン用に読み込ませたい

<body>
<!-- ...色々他のタグがあるとして... -->

<script type="text/javascript">
	(function(u,d){
		/* ユーザーエージェントが iPhone or Android  なら */
		if(u.indexOf('iPhone')>0 || u.indexOf('Android')>0){
			var j = d.createElement('script');
			j.src = 'sakura.smart.js';	/* 桜のスクリプトのパス or URL */
			d.body.appendChild(j);
		}
	})(navigator.userAgent,document);
</script>
</body>

スマホとパソコン別々のを読み込ませたい

<body>
<!-- ...色々他のタグがあるとして... -->

<script type="text/javascript">
	(function(u,d){
		var j = d.createElement('script');
		if(u.indexOf('iPhone')>0 || u.indexOf('Android')>0){
			j.src = 'sakura.smart.js';	/* スマートフォン用の桜のスクリプトのパス or URL */
		} else {
			j.src = 'sakura.js';	/* パソコン用の桜のスクリプトのパス or URL */
		}
		d.body.appendChild(j);
	})(navigator.userAgent,document);
</script>
</body>

コードの圧縮もしようよ!

ファイルサイズが小さいとあまり意味が無いかもしれませんが、細かい事が好きだし大切かなーと思うのでついでに!コードを圧縮してサイズを小さくしてくれる Web サービスって色々あると思いますが、個人的には Refresh-SF – Online JavaScript and CSS Compressor がおすすめです。

コードをコピペして Compress のボタンを押すだけで小さくしてくれますので、それをファイルに保存するだけなので比較的に手軽だと思います。ファイルサイズは、物によりますがコメントやタブとか入ってる状態から半分程度にはなると思います。

気をつけたいのは、余計な情報が削除されるのはもちろん、変数名なども短い文字に置き換えもされるので原形はなくなります。なので誤って元ファイルの上書きをしない様に気をつけてください!