JavaScript でサウンド効果付きの花火効果を実装する

JavaScript でサウンド効果付きの花火効果を実装する

コードを書くのに 30 分かかりましたが、この HTML5 Canvas New Year Fireworks は間違いなくあなたを失望させません!

まず、静的レンダリングを見てみましょう。

記事の最後にはダイナミックレンダリングがありますので、スライドしてご覧ください。

JavaScript コードは次のとおりです。

$(関数() {
	var キャンバス = $('#canvas')[0];
	キャンバスの幅 = $(window).width();
	キャンバスの高さ = $(window).height();
	var ctx = canvas.getContext('2d');
 
	// サイズ変更
	$(window).on('resize', 関数() {
		キャンバスの幅 = $(window).width();
		キャンバスの高さ = $(window).height();
		ctx.fillStyle = '#000003';
		ctx.fillRect(0, 0, キャンバスの幅、キャンバスの高さ);
		中心 = { x: キャンバスの幅 / 2、 y: キャンバスの高さ / 2 };
	});
 
	// 初期化
	ctx.fillStyle = '#000003';
	ctx.fillRect(0, 0, キャンバスの幅、キャンバスの高さ);
	// オブジェクト
	var listFire = [];
	var listFirework = [];
	var リストテキスト = [];
	var listSpecial = [];
	var listSpark = [];
	var ライト = [];
	var ファイアナンバー = 10;
	var center = { x: canvas.width / 2, y: canvas.height / 2 };
	var 範囲 = 100;
	var fired = 0;
	var onHold = 0;
	var サプライズ = false;
	var テキストインデックス = 0;
	var actions = [makeDoubleFullCircleFirework、makePlanetCircleFirework、makeFullCircleFirework、makeDoubleCircleFirework、makeHeartFirework、makeCircleFirework、makeRandomFirework];
	(var i = 0; i < fireNumber; i++) の場合 {
		var 火 = {
			x: Math.random() * 範囲 / 2 - 範囲 / 4 + center.x,
			y: Math.random() * 範囲 * 2.5 + キャンバスの高さ、
			サイズ: Math.random() + 0.5,
			塗りつぶし: '#ff3',
			vx: Math.random() - 0.5、
			vy: -(Math.random() + 4)、
			軸: Math.random() * 0.06 - 0.03、
			遅延: Math.round(Math.random() * 範囲) + 範囲 * 4,
			保留: 偽、
			アルファ: 1,
			far: Math.random() * 範囲 + (center.y - 範囲)
		};
		火.ベース = {
			x: 火.x,
			y: 火.y,
			vx: ファイアー.vx,
			vy: 火.vy
		};
		//
		listFire.push(fire);
		// サウンドを再生する
		起動サウンドを再生します。
	}
	// サウンドの配列を定義する
	var listExpSound = $('audio.exp');
	var listLaunchSound = $('audio.launch');
 
	// テキストの配列位置を定義する
	var textString = 'happylunarnewyear2018';
	var テキストマトリックス = [
		4.5、0、5.5、0、6.5、0、7.5、0、8.5、0、
		0、1、1、1、2、1、3、1、4、1、6、1、7、1、8、1、10、1、11、1、12、1、13、1、
		5、2、6、2、7、2、8、2
	]
	var chars = {
		時間: [
			0、0、0、1、0、2、0、3、0、4、0、5、0、6、0、7、
			1、3、2、3、3、3、4、3、
			5、0、5、1、5、2、5、3、5、4、5、5、5、6、5、7
		]、
		:[
			2、0、2、1、2、2、1、2、1、3、1、4、1、5、0、5、0、6、0、7、2、5、
			3、0、3、1、3、2、4、2、4、3、4、4、4、1、5、5、5、6、5、7、3、5
		]、
		p: [
			0、0、0、1、0、2、0、3、0、4、0、5、0、6、0、7、
			1、0、2、0、3、0、4、1、5、2、4、3、3、4、2、4、1、4
		]、
		y: [
			0、0、0、1、1、1、1、2、1、3、2、3、2、4、2、5、2、6、2、7、
			3、2、3、3、4、1、4、2、5、0、5、1
		]、
		l: [
			0、0、0、1、0、2、0、3、0、4、0、5、0、6、0、7、
			1、7、2、7、3、7、4、7、5、7
		]、
		あなた: [
			0、0、0、1、0、2、0、3、0、4、0、5、0、6、
			1、7、2、7、3、7、4、7、
			5、0、5、1、5、2、5、3、5、4、5、5、5、6
		]、
		名詞: [
			0、0、0、1、0、2、0、3、0、4、0、5、0、6、0、7、
			1、1、1、2、2、2、2、3、2、4、3、4、3、5、4、5、4、6、
			5、0、5、1、5、2、5、3、5、4、5、5、5、6、5、7
		]、
		e: [
			0、0、0、1、0、2、0、3、0、4、0、5、0、6、0、7、
			1、0、2、0、3、0、4、0、5、0、
			1、3、2、3、3、3、4、3、
			1、7、2、7、3、7、4、7、5、7
		]、
		w: [
			0、0、0、1、0、2、0、3、0、4、0、5、1、6、
			2、1、2、2、2、3、2、4、2、5、2、6、2、7、3、7、
			5、0、5、1、5、2、5、3、5、4、5、5、4、5、4、6
		]、
		r: [
			0、0、0、1、0、2、0、3、0、4、0、5、0、6、0、7、
			1、0、2、0、3、0、4、1、5、2、4、3、3、4、2、4、1、4、
			1、5、2、5、3、6、4、6、5、7
		]、
		2: [
			0、1、0、0、1、0、2、0、3、0、4、0、5、0、5、1、5、2、5、3、
			4、3、3、3、2、3、2、4、1、4、1、5、
			0、5、0、6、0、7、1、7、2、7、3、7、4、7、5、7、5、6
		]、
		0: [
			0、1、0、2、0、3、0、4、0、5、0、6、
			1、0、2、0、3、0、4、0、
			1、7、2、7、3、7、4、7、
			5、1、5、2、5、3、5、4、5、5、5、6
		]、
		1: [
			1、2、2、2、2、1、3、1、3、0、
			4、0、4、1、4、2、4、3、4、4、4、5、4、6、4、7、
			1、7、2、7、3、7、5、7
		]、
		7: [
			0、0、1、0、2、0、3、0、4、0、5、0、
			5、1、5、2、5、3、4、3、4、4、
			3、4、3、5、3、6、3、7
		]
	}
 
	関数initText() {
		var i = テキストインデックス;
		var 速度 = Math.random() * 0.25 + 1;
		var shift = { x: -(Math.random() + 2), y: -(Math.random() + 3) };
		var char = chars[テキスト文字列[i]];
		var 幅 = 80;
		var 半分 = 6.5 * 幅;
		var left = textMatrix[i * 2] * 幅 - 半分;
		var top = textMatrix[i * 2 + 1] * 範囲 * 1.2 - 範囲 * 2.4;
		(var j = 0; j < fireNumber * char.length * 0.25; j++) {
			var rand = Math.floor(Math.random() * char.length * 0.5);
			var x = char[rand * 2] + shift.x;
			var y = char[rand * 2 + 1] + shift.y;
			var テキスト = {
				x: 中心.x + 左 * 0.9、
				y: 中心.y + 上、
				左: center.x + 左、
				サイズ: Math.random() + 0.5,
				塗りつぶし: '#ff3',
				vx: x * (速度 + (Math.random() - 0.5) * 0.5)、
				vy: y * (速度 + (Math.random() - 0.5) * 0.5)、
				0.08,
				アルファ: 1,
				寿命: Math.round(Math.random() * 範囲 / 2) + 範囲 / 1.5
			}
			テキストベース = {
				人生: テキスト.人生、
				サイズ: テキストサイズ、
			};
			テキストの直接方向 = (テキストの左方向 - テキストのx方向) * 0.08;
			listText.push(テキスト);
		}
		// サウンドを再生する
		ExpSoundを再生します。
		//
		lights.push({ x: center.x + left * 0.9, y: center.y + top, color: text.fill, radius: range * 2 });
		if (++textIndex < textString.length) {
			タイムアウトを設定します(initText、10);
		}
		それ以外 {
			テキストインデックス = 0;
		}
	}
 
	関数initSpark() {
		var x = Math.random() * 範囲 * 3 - 範囲 * 1.5 + center.x;
		var vx = Math.random() - 0.5;
		var vy = -(Math.random() + 4);
		var ax = Math.random() * 0.04 - 0.02;
		var far = Math.random() * range * 4 - range + center.y;
		var direct = ax * 10 * Math.PI;
		var 最大値 = fireNumber * 0.5;
		(var i = 0; i < max; i++) の場合 {
			var 特殊 = {
				x: x,
				y: Math.random() * 範囲 * 0.25 + キャンバスの高さ、
				サイズ: Math.random() + 2,
				塗りつぶし: '#ff3',
				vx: vx、
				ヴィ:ヴィ、
				斧:斧、
				直接的: 直接的な、
				アルファ: 1
			};
			special.far = far - (special.y - canvas.height);
			listSpecial.push(special);
			// サウンドを再生する
			起動サウンドを再生します。
		}
	}
 
	関数randColor() {
		var r = Math.floor(Math.random() * 256);
		var g = Math.floor(Math.random() * 256);
		var b = Math.floor(Math.random() * 256);
		var color = 'rgb($r, $g, $b)';
		色 = color.replace('$r', r);
		色 = color.replace('$g', g);
		色 = color.replace('$b', b);
		色を返します。
	}
 
	関数playExpSound() {
		var sound = listExpSound[Math.floor(Math.random() * listExpSound.length)];
		sound.volume = Math.random() * 0.4 + 0.1;
		サウンドを再生します。
	}
 
	関数playLaunchSound() {
		setTimeout(関数() {
			var sound = listLaunchSound[Math.floor(Math.random() * listLaunchSound.length)];
			サウンドの音量 = 0.05;
			サウンドを再生します。
		}, 200);
	}
 
	関数 makeCircleFirework(fire) {
		var color = randColor();
		var 速度 = Math.random() * 2 + 6;
		var 最大値 = fireNumber * 5;
		(var i = 0; i < max; i++) の場合 {
			var rad = (i * Math.PI * 2) / max;
			var 花火 = {
				x: 火.x,
				y: 火.y,
				サイズ: Math.random() + 1.5,
				塗りつぶし: 色、
				vx: Math.cos(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				vy: Math.sin(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				0.04,
				アルファ: 1,
				ライフ: Math.round(Math.random() * 範囲 / 2) + 範囲 / 2
			};
			花火.ベース = {
				人生: 花火.人生、
				サイズ: 花火.サイズ
			};
			listFirework.push(花火);
		}
		色を返します。
	}
 
	関数 makeDoubleCircleFirework(fire) {
		var color = randColor();
		var 速度 = Math.random() * 2 + 8;
		var 最大値 = fireNumber * 3;
		(var i = 0; i < max; i++) の場合 {
			var rad = (i * Math.PI * 2) / max;
			var 花火 = {
				x: 火.x,
				y: 火.y,
				サイズ: Math.random() + 1.5,
				塗りつぶし: 色、
				vx: Math.cos(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				vy: Math.sin(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				0.04,
				アルファ: 1,
				寿命: Math.round(Math.random() * 範囲 / 2) + 範囲 / 1.5
			};
			花火.ベース = {
				人生: 花火.人生、
				サイズ: 花火.サイズ
			};
			listFirework.push(花火);
		}
		色 = randColor();
		速度 = Math.random() * 3 + 4;
		(var i = 0; i < max; i++) の場合 {
			var rad = (i * Math.PI * 2) / max;
			var 花火 = {
				x: 火.x,
				y: 火.y,
				サイズ: Math.random() + 1.5,
				塗りつぶし: 色、
				vx: Math.cos(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				vy: Math.sin(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				0.04,
				アルファ: 1,
				寿命: Math.round(Math.random() * 範囲 / 2) + 範囲 / 1.5
			};
			花火.ベース = {
				人生: 花火.人生、
				サイズ: 花火.サイズ
			};
			listFirework.push(花火);
		}
		色を返します。
	}
 
	関数 makePlanetCircleFirework(fire) {
		var color = '#aa0609';
		var 速度 = Math.random() * 2 + 4;
		var 最大値 = fireNumber * 2;
		(var i = 0; i < max; i++) の場合 {
			var rad = (i * Math.PI * 2) / max;
			var 花火 = {
				x: 火.x,
				y: 火.y,
				サイズ: Math.random() + 1.5,
				塗りつぶし: 色、
				vx: Math.cos(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				vy: Math.sin(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				0.04,
				アルファ: 1,
				寿命: Math.round(Math.random() * 範囲 / 2) + 範囲 / 1.5
			};
			花火.ベース = {
				人生: 花火.人生、
				サイズ: 花火.サイズ
			};
			listFirework.push(花火);
		}
		最大値 = ファイアナンバー * 4;
		(var i = 0; i < max; i++) の場合 {
			var rad = (i * Math.PI * 2) / max;
			var 花火 = {
				x: 火.x,
				y: 火.y,
				サイズ: Math.random() + 1.5,
				塗りつぶし: 色、
				vx: Math.cos(rad) * 速度 * Math.random(),
				vy: Math.sin(rad) * 速度 * Math.random(),
				0.04,
				アルファ: 1,
				寿命: Math.round(Math.random() * 範囲 / 2) + 範囲 / 1.5
			};
			花火.ベース = {
				人生: 花火.人生、
				サイズ: 花火.サイズ
			};
			listFirework.push(花火);
		}
		最大値 = ファイアナンバー * 3;
		色 = '#ff9';
		var rotate = Math.random() * Math.PI * 2;
		var vx = 速度 * (Math.random() + 2);
		var vy = 速度 * 0.6;
		(var i = 0; i < max; i++) の場合 {
			var rad = (i * Math.PI * 2) / max;
			// 楕円の x、y を計算
			var cx = Math.cos(rad) * vx + (Math.random() - 0.5) * 0.5;
			var cy = Math.sin(rad) * vy + (Math.random() - 0.5) * 0.5;
			var 花火 = {
				x: 火.x,
				y: 火.y,
				サイズ: Math.random() + 1.5,
				塗りつぶし: 色、
				vx: cx * Math.cos(rotate) - cy * Math.sin(rotate), // x楕円を回転
				vy: cx * Math.sin(rotate) + cy * Math.cos(rotate), // y楕円を回転
				0.02,
				アルファ: 1,
				寿命: Math.round(Math.random() * 範囲 / 2) + 範囲 / 1.5
			};
			花火.ベース = {
				人生: 花火.人生、
				サイズ: 花火.サイズ
			};
			listFirework.push(花火);
		}
		'#aa0609' を返します。
	}
 
	関数 makeFullCircleFirework(fire) {
		var color = randColor();
		var 速度 = Math.random() * 8 + 8;
		var 最大値 = fireNumber * 3;
		(var i = 0; i < max; i++) の場合 {
			var rad = (i * Math.PI * 2) / max;
			var 花火 = {
				x: 火.x,
				y: 火.y,
				サイズ: Math.random() + 1.5,
				塗りつぶし: 色、
				vx: Math.cos(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				vy: Math.sin(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				0.06,
				アルファ: 1,
				寿命: Math.round(Math.random() * 範囲 / 2) + 範囲 / 1.5
			};
			花火.ベース = {
				人生: 花火.人生、
				サイズ: 花火.サイズ
			};
			listFirework.push(花火);
		}
		最大値 = fireNumber * Math.round(Math.random() * 4 + 4);
		(var i = 0; i < max; i++) の場合 {
			var rad = (i * Math.PI * 2) / max;
			var 花火 = {
				x: 火.x,
				y: 火.y,
				サイズ: Math.random() + 1.5,
				塗りつぶし: 色、
				vx: Math.cos(rad) * 速度 * Math.random(),
				vy: Math.sin(rad) * 速度 * Math.random(),
				0.06,
				アルファ: 1,
				寿命: Math.round(Math.random() * 範囲 / 2) + 範囲 / 1.5
			};
			花火.ベース = {
				人生: 花火.人生、
				サイズ: 花火.サイズ
			};
			listFirework.push(花火);
		}
		色を返します。
	}
 
	関数 makeDoubleFullCircleFirework(fire) {
		var color = randColor();
		var 速度 = Math.random() * 8 + 8;
		var 最大値 = fireNumber * 3;
		(var i = 0; i < max; i++) の場合 {
			var rad = (i * Math.PI * 2) / max;
			var 花火 = {
				x: 火.x、
				y: 火.y,
				サイズ: Math.random() + 1.5,
				塗りつぶし: 色、
				vx: Math.cos(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				vy: Math.sin(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				0.04,
				アルファ: 1,
				寿命: Math.round(Math.random() * 範囲 / 2) + 範囲 / 1.5
			};
			花火.ベース = {
				人生: 花火.人生、
				サイズ: firework.size
			};
			listFirework.push(花火);
		}
		色 = randColor();
		速度 = Math.random() * 3 + 4;
		最大値 = ファイアナンバー * 2;
		(var i = 0; i < max; i++) の場合 {
			var rad = (i * Math.PI * 2) / max;
			var 花火 = {
				x: 火.x,
				y: 火.y,
				サイズ: Math.random() + 1.5,
				塗りつぶし: 色、
				vx: Math.cos(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				vy: Math.sin(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				0.06,
				アルファ: 1,
				寿命: Math.round(Math.random() * 範囲 / 2) + 範囲 / 1.5
			};
			花火.ベース = {
				人生: 花火.人生、
				サイズ: 花火.サイズ
			};
			listFirework.push(花火);
		}
		最大値 = ファイアナンバー * 4;
		(var i = 0; i < max; i++) の場合 {
			var rad = (i * Math.PI * 2) / max;
			var 花火 = {
				x: 火.x,
				y: 火.y,
				サイズ: Math.random() + 1.5,
				塗りつぶし: 色、
				vx: Math.cos(rad) * 速度 * Math.random(),
				vy: Math.sin(rad) * 速度 * Math.random(),
				0.06,
				アルファ: 1,
				寿命: Math.round(Math.random() * 範囲 / 2) + 範囲 / 1.5
			};
			花火.ベース = {
				人生: 花火.人生、
				サイズ: 花火.サイズ
			};
			listFirework.push(花火);
		}
		色を返します。
	}
 
	関数 makeHeartFirework(fire) {
		var color = randColor();
		var 速度 = Math.random() * 3 + 3;
		var 最大値 = fireNumber * 5;
		var rotate = Math.random() * Math.PI * 2;
		(var i = 0; i < max; i++) の場合 {
			var rad = (i * Math.PI * 2) / max + rotate;
			var v、p;
			(ラジアン回転 < Math.PI * 0.5)の場合{
				p = (rad - 回転) / (Math.PI * 0.5);
				v = 速度 + 速度 * p;
			}
			そうでない場合、(rad - rotate > Math.PI * 0.5 && rad - rotate < Math.PI) {
				p = (rad - rotate - Math.PI * 0.5) / (Math.PI * 0.5);
				v = 速度 * (2 - p);
			}
			そうでない場合 (rad - rotate > Math.PI && rad - rotate < Math.PI * 1.5) {
				p = (rad - rotate - Math.PI) / (Math.PI * 0.5);
				v = 速度 * (1 - p);
			}
			そうでない場合、(rad - rotate > Math.PI * 1.5 && rad - rotate < Math.PI * 2) {
				p = (rad - rotate - Math.PI * 1.5) / (Math.PI * 0.5);
				v = 速度 * p;
			}
			それ以外 {
				v = 速度;
			}
			v = v + (Math.random() - 0.5) * 0.25;
			var 花火 = {
				x: 火.x,
				y: 火.y,
				サイズ: Math.random() + 1.5,
				塗りつぶし: 色、
				vx: Math.cos(rad) * v,
				vy: Math.sin(rad) * v、
				0.02,
				アルファ: 1,
				寿命: Math.round(Math.random() * 範囲 / 2) + 範囲 / 1.5
			};
			花火.ベース = {
				人生: 花火.人生、
				サイズ: firework.size
			};
			listFirework.push(花火);
		}
		色を返します。
	}
 
	関数 makeRandomFirework(fire) {
		var color = randColor();
		(var i = 0; i < fireNumber * 5; i++) の場合 {
			var 花火 = {
				x: 火.x,
				y: 火.y,
				サイズ: Math.random() + 1.5,
				塗りつぶし: 色、
				vx: Math.random() * 15 - 7.5、
				vy: Math.random() * -15 + 5,
				0.05,
				アルファ: 1,
				ライフ: Math.round(Math.random() * 範囲 / 2) + 範囲 / 2
			};
			花火.ベース = {
				人生: 花火.人生、
				サイズ: 花火.サイズ
			};
			listFirework.push(花火);
		}
		色を返します。
	}
 
	関数makeSpark(special) {
		var color = special.fill;
		var 速度 = Math.random() * 6 + 12;
		var max = fireNumber;
		(var i = 0; i < max; i++) の場合 {
			var rad = (Math.random() * Math.PI * 0.3 + Math.PI * 0.35) + Math.PI + special.direct;
			var スパーク = {
				x: 特殊.x、
				y: 特殊.y,
				サイズ: Math.random() + 1,
				塗りつぶし: 色、
				vx: Math.cos(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				vy: Math.sin(rad) * 速度 + (Math.random() - 0.5) * 0.5、
				0.02,
				アルファ: 1,
				ラッド:ラッド、
				直接: 特別直接、
				チェーン: Math.round(Math.random() * 2) + 2,
				ライフ: Math.round(Math.random() * 範囲 / 2) + 範囲 / 2
			};
			spark.base = {
				人生: スパークライフ、
				速度: 速度
			};
			Spark をリストします。
		}
		色を返します。
	}
 
	関数チェーンSpark(親Spark) {
		var color = parentSpark.fill;
		親Spark.chain > 0の場合{
			var 速度 = parentSpark.base.velocity * 0.6;
			var max = Math.round(Math.random() * 5);
			(var i = 0; i < max; i++) の場合 {
				var rad = (Math.random() * Math.PI * 0.3 - Math.PI * 0.15) + parentSpark.rad + parentSpark.direct;
				var スパーク = {
					x: 親Spark.x、
					y: 親Spark.y、
					サイズ: parentSpark.size * 0.6、
					塗りつぶし: 色、
					vx: Math.cos(rad) * 速度 + (Math.random() - 0.5) * 0.5、
					vy: Math.sin(rad) * 速度 + (Math.random() - 0.5) * 0.5、
					0.02,
					アルファ: 1,
					ラッド:ラッド、
					直接: parentSpark.direct、
					チェーン: parentSpark.chain、
					ライフ: parentSpark.base.life * 0.8
				};
				spark.base = {
					人生: スパークライフ、
					サイズ: spark.size、
					速度: 速度
				};
				Spark をリストします。
			}
 
			(Math.random() > 0.9 && parentSpark.chain > 1) の場合 {
				// サウンドを再生する
				ExpSoundを再生します。
			}
		}
		色を返します。
	}
 
	(関数ループ() {
		アニメーションフレームをリクエストします(ループ)。
		アップデート();
		描く();
	})();
 
	関数 update() {
		// 発火ロジックを更新
		(var i = 0; i < listFire.length; i++) {
			var fire = listFire[i];
			//
			(火のy <= 火の遠方)の場合{
				// サウンドを再生する
				ExpSoundを再生します。
				// case 花火を追加
				発射++;
				var color = actions[Math.floor(Math.random() * actions.length)](火);
				// ライト
				lights.push({ x: fire.x, y: fire.y, color: color, radius: range * 2 });
				// リセット
				y = ...
				fire.x = fire.base.x;
				//特別
				if (発火率 % 33 == 0) {
					初期化Spark();
				}
				// 保留中
				supprise = fired % 100 == 0 ? true : supprise;
				もし(サプライズ){
					火.vx = 0;
					火.vy = 0;
					火.ax = 0;
					ファイアホールド = true;
					オンホールド++;
				}
				それ以外 {
					fire.vx を fire.base.vx に追加します。
					fire.vy = fire.base.vy;
					fire.ax = Math.random() * 0.06 - 0.03;
					// サウンドを再生する
					起動サウンドを再生します。
				}
			}
			//
			(fire.hold && fire.delay <= 0)の場合{
				保留中 - ;
				ファイアホールド = false;
				fire.delay = Math.round(Math.random() * 範囲) + 範囲 * 4;
				fire.vx を fire.base.vx に追加します。
				fire.vy = fire.base.vy;
				fire.ax = Math.random() * 0.06 - 0.03;
				アルファ = 1;
				// サウンドを再生する
				起動サウンドを再生します。
			}
			そうでない場合 (fire.hold && fire.delay > 0) {
				火災遅延--;
			}
			それ以外 {
				火.x += 火.vx;
				火.y += 火.vy;
				fire.vx += fire.ax;
				fire.alpha = (fire.y - fire.far) / fire.far;
			}
		}
 
		// 花火ロジックを更新
		(var i = listFirework.length - 1; i >= 0; i--) {
			var 花火 = listFirework[i];
			if (花火) {
				花火.vx * = 0.9;
				花火.vy * = 0.9;
				firework.x += firework.vx;
				花火.y += 花火.vy;
				firework.vy += firework.ay;
				firework.alpha = firework.life / firework.base.life;
				firework.size = firework.alpha * firework.base.size;
				firework.alpha = firework.alpha > 0.6 ? 1 : firework.alpha;
				//
				花火.life--;
				花火の寿命が0以下の場合
					リストFirework.splice(i, 1);
				}
			}
		}
 
		// サプライズ、明けましておめでとうございます!
		if (サプライズ && onHold == 10) {
			驚き = false;
			タイムアウトを設定します(initText、3000);
		}
 
		// テキストロジックを更新
		(var i = listText.length - 1; i >= 0; i--) {
			var テキスト = listText[i];
			テキスト.vx * = 0.9;
			テキスト.vy * = 0.9;
			テキスト直接 * = 0.9;
			text.x += text.vx + text.direct;
			テキスト.y + = テキスト.vy;
			text.vy += text.ay;
			text.alpha = text.life / text.base.life;
			テキストのサイズ = テキストのアルファ * テキストのベースサイズ;
			text.alpha = text.alpha > 0.6 ? 1 : text.alpha;
			//
			テキスト.life--;
			(テキスト寿命<= 0)の場合{
				リストテキストを連結します(i, 1);
			}
		}
 
		// 特別なロジックを更新する
		(var i = listSpecial.length - 1; i >= 0; i--) {
			var special = listSpecial[i];
			(special.y <= special.far)の場合{
				// サウンドを再生する
				ExpSoundを再生します。
				// ライト
				lights.push({ x: special.x, y: special.y, color: special.fill, alpha: 0.02, radius: range * 2 });
				//
				Spark(特別)を作成します。
				// リストから削除
				リストスペシャル.splice(i, 1);
			}
			それ以外 {
				special.x += special.vx;
				special.y += special.vy;
				special.vx + = special.ax;
				special.alpha = (special.y - special.far) / special.far;
			}
		}
 
		// Spark ロジックを更新
		(var i = listSpark.length - 1; i >= 0; i--) {
			var spark = listSpark[i];
			もし(スパーク){
				スパーク。
				spark.vy * = 0.9;
				spark.x + = spark.vx;
				spark.y + = spark.vy;
				spark.vy + = spark.ay;
				spark.alpha = spark.life / spark.base.life + 0.2;
				//
				スパーク.ライフ--;
				spark.life < spark.base.life * 0.8 && spark.life > 0 の場合 {
					//
					spark.chain--;
					チェーンスパーク(スパーク);
				}
				(spark.life <= 0)の場合{
					リストSpark.splice(i, 1);
				}
			}
		}
	}
 
	関数draw() {
		// クリア
		ctx.globalCompositeOperation = 'ソースオーバー';
		ctx.globalAlpha = 0.2;
		ctx.fillStyle = '#000003';
		ctx.fillRect(0, 0, キャンバスの幅、キャンバスの高さ);
 
		// 再描画
		ctx.globalCompositeOperation = 'スクリーン';
		(var i = 0; i < listFire.length; i++) {
			var fire = listFire[i];
			ctx.globalAlpha = fire.alpha;
			ctx.beginPath();
			ctx.arc(fire.x, fire.y, fire.size, 0, Math.PI * 2);
			ctx.closePath();
			ctx.fillStyle = fire.fill;
			ctx.fill();
		}
 
		(var i = 0; i < listFirework.length; i++) {
			var 花火 = listFirework[i];
			ctx.globalAlpha = firework.alpha;
			ctx.beginPath();
			ctx.arc(firework.x、firework.y、firework.size、0、Math.PI * 2);
			ctx.closePath();
			ctx.fillStyle = firework.fill;
			ctx.fill();
		}
 
		(var i = 0; i < listSpecial.length; i++) の場合 {
			var special = listSpecial[i];
			ctx.globalAlpha = special.alpha;
			// ctx.beginPath();
			// ctx.arc(special.x, special.y, special.size, 0, Math.PI * 2);
			// ctx.closePath();
			// ctx.fill();
			ctx.fillStyle = special.fill;
			ctx.fillRect(special.x - special.size、special.y - special.size、special.size * 2、special.size *2);
		}
 
		(var i = 0; i < listSpark.length; i++) {
			var spark = listSpark[i];
			ctx.globalAlpha = spark.alpha;
			// ctx.beginPath();
			// ctx.arc(spark.x, spark.y, spark.size, 0, Math.PI * 2);
			// ctx.closePath();
			// ctx.fill();
			ctx.fillStyle = spark.fill;
			ctx.fillRect(spark.x - spark.size、spark.y - spark.size、spark.size * 2、spark.size *2);
		}
 
		// ライト効果
		ライトの長さが続く間
			var light = lights.pop();
			var gradient = ctx.createRadialGradient(light.x, light.y, 0, light.x, light.y, light.radius);
			グラデーションに色ストップを追加します(0, '#fff');
			グラデーションにColorStopを追加します(0.2、ライトの色)。
			グラデーションにColorStopを追加します。0.8, 'rgba(0, 0, 0, 0)';
			グラデーションにColorStopを追加します(1, 'rgba(0, 0, 0, 0)');
			ctx.globalAlpha = light.alpha ? light.alpha: 0.25;
			ctx.fillStyle = グラデーション;
			ctx.fillRect(light.x - light.radius, light.y - light.radius, light.radius * 2, light.radius * 2);
		}
 
		// サプライズ: 2018年旧正月おめでとうございます!
		(var i = 0; i < listText.length; i++) {
			var テキスト = listText[i];
			ctx.globalAlpha = text.alpha;
			ctx.fillStyle = テキスト.fill;
			ctx.fillRect(text.x - text.size, text.y - text.size, text.size * 2, text.size * 2);
		}
	}
})

インデックスホームページのコードは次のとおりです。

<!DOCTYPE html>
<html lang="ja" >
<ヘッド>
<メタ文字セット="UTF-8">
<title>明けましておめでとうございます</title>
<link rel="スタイルシート" href="css/style.css" rel="外部nofollow" >
</head>
 
<本文>
 
<キャンバスid="キャンバス"></キャンバス>
 
<div class="block-audio">
  <audio class="exp" src="m/exp1.mp3" コントロール></audio>
  <audio class="exp" src="m/exp1.mp3" コントロール></audio>
  <audio class="exp" src="m/exp1.mp3" コントロール></audio>
  <audio class="exp" src="m/exp2.mp3" コントロール></audio>
  <audio class="exp" src="m/exp2.mp3" コントロール></audio>
  <audio class="exp" src="m/exp2.mp3" コントロール></audio>
  <audio class="exp" src="m/exp3.mp3" コントロール></audio>
  <audio class="exp" src="m/exp3.mp3" コントロール></audio>
  <audio class="exp" src="m/exp3.mp3" コントロール></audio>
  <audio class="exp" src="m/exp4.mp3" コントロール></audio>
  <audio class="exp" src="m/exp4.mp3" コントロール></audio>
  <audio class="exp" src="m/exp4.mp3" コントロール></audio>
  <audio class="exp" src="m/exp5.mp3" コントロール></audio>
  <audio class="exp" src="m/exp5.mp3" コントロール></audio>
  <audio class="exp" src="m/exp5.mp3" コントロール></audio>
  <audio class="exp" src="m/exp6.mp3" コントロール></audio>
  <audio class="exp" src="m/exp6.mp3" コントロール></audio>
  <audio class="exp" src="m/exp6.mp3" コントロール></audio>
  <audio class="exp" src="m/exp7.mp3" コントロール></audio>
  <audio class="exp" src="m/exp7.mp3" コントロール></audio>
  <audio class="exp" src="m/exp7.mp3" コントロール></audio>
  <audio class="exp" src="m/exp8.mp3" コントロール></audio>
  <audio class="exp" src="m/exp8.mp3" コントロール></audio>
  <audio class="exp" src="m/exp8.mp3" コントロール></audio>
  <audio class="launch" src="m/launch1.mp3" コントロール></audio>
  <audio class="launch" src="m/launch1.mp3" コントロール></audio>
  <audio class="launch" src="m/launch2.mp3" コントロール></audio>
  <audio class="launch" src="m/launch2.mp3" コントロール></audio>
  <audio class="launch" src="m/launch3.mp3" コントロール></audio>
  <audio class="launch" src="m/launch3.mp3" コントロール></audio>
  <audio class="launch" src="m/launch4.mp3" コントロール></audio>
  <audio class="launch" src="m/launch4.mp3" コントロール></audio>
  <audio class="launch" src="m/launch5.mp3" コントロール></audio>
  <audio class="launch" src="m/launch5.mp3" コントロール></audio>
</div>
 
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/index.js"></script>
 
</本文>
</html>

CSS コードは次のとおりです。

キャンバス {
  表示: ブロック;
}
 
.block-audio {
  表示: なし;
}
本文{パディング: 0px;マージン: 0px}

最後に、花火の特殊効果のダイナミック チャートを次のように実行します。

以上が、JavaScript を使って効果音付きの花火効果を実現する方法の詳細です。JavaScript 花火効果の詳細については、123WORDPRESS.COM の他の関連記事にも注目してください。

以下もご興味があるかもしれません:
  • 花火効果を実現するための js シミュレーション
  • 花火効果を実現するネイティブJS
  • とても美しいjs花火効果
  • クリック花火効果を実現する js
  • 花火効果を実現するJavaScript(オブジェクト指向)
  • クールな花火効果を実現するjs
  • JavaScriptは5つの異なる花火効果を実装します

<<:  自動行折り返し機能付き CSS Flex レイアウトのサンプル コード

>>:  HTML、CSS、JSコメントの標準的な使用法の概要

推薦する

マインスイーパゲームを実装するための jQuery プラグイン (3)

この記事では、jQueryプラグインを使用してマインスイーパゲームを実装する方法に関する3番目の記事...

Docker-compose チュートリアルのインストールとクイックスタート

目次1. Compose の紹介2. ComposeとDockerの互換性3. Dockerをインス...

MySQLでconcat関数を使用する方法

以下のように表示されます。 //managefee_managefee テーブルの年と月を照会し、c...

VueはOSSを使用して画像や添付ファイルをアップロードします

OSS を使用して Vue プロジェクトに画像や添付ファイルをアップロードするここでは、写真のアップ...

UbuntuにProtobuf 3をインストールするための詳細なチュートリアル

いつインストールするかprotoc コマンドを使用しても Protoc が見つからない場合は、インス...

プロジェクトにおける CSS グリッドシステムの柔軟な使用方法の詳細な説明

序文CSS グリッドは通常、さまざまなフレームワークにバンドルされていますが、実際のビジネス ニーズ...

フォーム送信の更新ページはソースコード設計にジャンプしません

1. ソースコードの設計コードをコピーコードは次のとおりです。 <!DOCTYPE html ...

Vueのprovideとinjectの使い方と原則を分析する

まず、provide/inject を使用する理由について説明しましょう。祖父コンポーネントと孫コン...

JavaScript でプライベート メンバーを作成する

目次1. クロージャを使用する2. ES6クラスを使用する3. ES2020提案を使用する4. We...

Vue 親子コンポーネントの相互値の転送と呼び出し

目次1. 親が子コンポーネントに値を渡す2. 子コンポーネントが親コンポーネントに値を渡す3. 子コ...

メタビューポートタグ(モバイルブラウジングズームコントロール)の使用方法

OP が現在のファームウェアで Web ページを開くと、常に 50% にズームアウトされてから表示さ...

js を使用して年カルーセル選択効果をネイティブに実装する例

序文js を使用して、年の回転選択効果を実現します。では早速、写真を見てみましょう。 1. アイデア...

跳ねるボールを実現するネイティブjs

思いつきで、小さなボールが跳ね返るケーススタディを書いてみました。具体的な内容は以下のとおりです。主...

HTML テーブル データを Json 形式に変換するサンプル コード

<table>テーブルデータをJSON形式に変換するJavaScript関数は次のとおり...

this.parentNode.parentNode (親ノードの親ノード) はどういう意味ですか?

親ノードの親ノード、例えば、このような段落がありますHTML:コードをコピーコードは次のとおりです。...