プログラミングライフスタイル

「ChatGPT」で作る「パーティクルアニメーション」

「OPEN AI」が公開している対話型チャットAI「ChatGPT」を活用したプログラミングは、「プログラミングの時間短縮」につながり、より効率的な「システム・アプリケーション開発」を行うために活用されています。

しかし複雑なシステムを「ChatGPT」のみで作り上げることは難しく、人間の「思考と判断」が必ず必要になってきます。

「ChatGPT」を「どのように活用してプログラミングを行うのか?」が、「プログラミング効率を上げること」が出来るのかに影響してきます

これから、さまざまな検証を繰り返しながらプログラミングにおける「ChatGPTの効率的な活用方法」を探索していきたいと思います。

「パーティクルアニメーション」

今回は「パーティクルアニメーション」を「ChatGPT」を活用して作成していきたいと思います。

ChatGPT対話(その1)

まず始めに、

「HTML・CSS」を利用して、画面内のボタンを押すと「星型のパーティクル」が画面の中心から放射状に拡散するプログラムを教えてください。
					

のように「ChatGPT」に聞いてみました。

すると下記のような「HTML・CSS・Javascript」のプログラムを出力してくれました。

以下がHTML・CSSを利用して、画面内のボタンを押すと星型のパーティクルが画面の中心から放射状に拡散するプログラムの例です。

HTMLファイル:

<!DOCTYPE html>
<html>
<head>
	<title>Star Particle Animation</title>
	<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
	<button onclick="explode()">Explode!</button>
	<div id="particles"></div>
	<script src="script.js"></script>
</body>
</html>

CSSファイル:

body {
	background-color: black;
}

button {
	margin: 20px;
	padding: 10px 20px;
	font-size: 24px;
	background-color: white;
	border: none;
	color: black;
	cursor: pointer;
}

#particles {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 0;
	height: 0;
	background-color: transparent;
	overflow: hidden;
}

JavaScriptファイル:

function explode() {
	var particles = 200; // パーティクルの数
	var duration = 2000; // アニメーションの時間(ミリ秒)
	var size = 4; // パーティクルのサイズ
	var colors = ['#FFB6C1', '#87CEFA', '#FFFACD', '#90EE90', '#FFD700']; // パーティクルの色

	var container = document.getElementById('particles');
	var w = container.offsetWidth;
	var h = container.offsetHeight;

	for (var i = 0; i < particles; i++) {
		var angle = Math.random() * 360;
		var radius = Math.random() * w * 0.5;
		var x = w * 0.5 + radius * Math.cos(angle * Math.PI / 180);
		var y = h * 0.5 + radius * Math.sin(angle * Math.PI / 180);
		var color = colors[Math.floor(Math.random() * colors.length)];

		var particle = document.createElement('div');
		particle.style.width = size + 'px';
		particle.style.height = size + 'px';
		particle.style.borderRadius = '50%';
		particle.style.backgroundColor = color;
		particle.style.position = 'absolute';
		particle.style.left = x + 'px';
		particle.style.top = y + 'px';

		container.appendChild(particle);

		TweenMax.to(particle, duration / 1000, {
			left: w * 0.5,
			top: h * 0.5,
			scale: 0,
			ease: Power2.easeOut,
			onComplete: function() {
				container.removeChild(particle);
			}
		});
	}
}

このプログラムでは、HTMLのボタンをクリックするとJavaScriptのexplode()関数が呼び出され、指定されたパラメーターを元にパーティクルが生成されてアニメーションが実行されます。生成されたパーティクルは、CSSのposition: absoluteプロパティを使って画面の中央に配置され、TweenMaxライブラリを使用してアニメーションが実行されます。パーティ

・・・出力が途中で止まってしまいました。

続きを教えてください。

とお願いすると続きを出力してくれます。

クルが画面中央に集まるアニメーションが終了すると、onCompleteコールバック関数が呼び出され、パーティクルがDOMから削除されます。
このプログラムは、TweenMaxライブラリを使用してアニメーションを実行するため、TweenMaxライブラリのCDNをHTMLファイルに追加する必要があります。以下はTweenMaxライブラリのCDNの例です。
php

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>

また、このプログラムでは、colors変数にパーティクルの色を指定する配列を定義しています。必要に応じて、この配列に好きな色を追加したり、変更したりすることができます。

なお、このプログラムでは、CSSのposition: absoluteプロパティを使ってパーティクルを配置していますが、これは一例であり、必ずしも最適な方法とは限りません。適切な方法は、使用するフレームワークやライブラリ、アプリケーションの要件によって異なります。

以上が、HTML・CSSを利用して、画面内のボタンを押すと星型のパーティクルが画面の中心から放射状に拡散するプログラムの例です。

すぐにでも実行できそうなコードが生成されましたね。

このプログラムを実行して、「Explode」ボタンをクリックすると、

Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

のようなエラーが発生します。

「TweenMax」のメソッド内のエラーのようですが、「TweenMax」を使ったことが無いのでエラーの原因がわからないことと、「Pure Javascript」が出力されることを想定していました。

「ChapGPT」は「ライブラリ」を使用したプログラムも出力してくれるんですね。

不具合があった時に自分で直せるようにしたいため、「ChapGPT」に再度異なるお願いをしてみました。

ChatGPT対話(その2)

次にお願いした内容は、

ライブラリを使わずに「HTML・CSS」を利用して、画面内のボタンを押すと「星型のパーティクル」が画面の中心から放射状に拡散するプログラムを教えてください。

です。

先ほどの質問内容に「ライブラリ」を使わないように文言を付け加えました。

すると、

このようなアニメーションを実装するには、JavaScriptを使う必要があります。以下は、HTMLとCSSを使ってボタンと画面全体の背景色を設定し、JavaScriptを使って星型のパーティクルを生成してアニメーションを実装する方法です。

まず、HTMLファイルに以下のコードを追加します。

html
Copy code
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Star Particle Animation</title>
	<style>
	/* ボタンのスタイル */
	button {
		background-color: #3498db;
		color: white;
		padding: 10px 20px;
		border: none;
		border-radius: 5px;
		font-size: 16px;
		cursor: pointer;
	}
	
	/* 画面の背景色 */
	body {
		background-color: #f2f2f2;
	}
	
	/* パーティクルのスタイル */
	.particle {
		position: absolute;
		width: 5px;
		height: 5px;
		background-color: white;
		border-radius: 50%;
		animation: particleAnimation 1s ease-out;
	}
	
	/* パーティクルのアニメーション */
	@keyframes particleAnimation {
		0% {
		opacity: 1;
		transform: scale(1);
		}
		100% {
		opacity: 0;
		transform: scale(10);
		}
	}
	</style>
</head>
<body>
	<button onclick="createParticles()">Generate particles</button>
	<script src="app.js"></script>
</body>
</html>
次に、JavaScriptファイル(app.js)に以下のコードを追加します。

javascript
Copy code
// パーティクルの生成
function createParticles() {
	// 画面の中心座標を取得
	const centerX = window.innerWidth / 2;
	const centerY = window.innerHeight / 2;
	
	// パーティクルを生成する回数を設定
	const particleCount = 50;
	
	// パーティクルを生成
	for (let i = 0; i < particleCount; i++) {
	const particle = document.createElement("div");
	particle.classList.add("particle");
	document.body.appendChild(particle);
	
	// パーティクルの初期座標を設定
	const x = centerX;
	const y = centerY;
	particle.style.left = x + "px";
	particle.style.top = y + "px";
	
	// パーティクルの終了座標をランダムに設定
	const endX = centerX + getRandomNumber(-200, 200);
	const endY = centerY + getRandomNumber(-200, 200);
	
	// パーティクルを移動させるアニメーションを設定
	const animation = particle.animate([
		{ transform: `translate(${x}px, ${y}px)`, opacity: 1 },
		{ transform: `translate(${endX}px, ${endY}px)`, opacity: 0 }
	], {
		duration

のように出力され、出力が途中で止まってしまいましたので、再度

続きを教えてください

とお願いしてみました。すると、

javascript
Copy code
	duration: 1000, // アニメーションの時間(ミリ秒)
	easing: "ease-out" // アニメーションのイージング
});

// アニメーションが終了したらパーティクルを削除
animation.onfinish = () => {
	particle.remove();
}
}
}

// 指定した範囲の乱数を生成する関数
function getRandomNumber(min, max) {
return Math.random() * (max - min) + min;
}

JavaScriptファイルでは、`createParticles`関数でパーティクルを生成し、それぞれにアニメーションを設定しています。具体的には、以下の処理を行っています。

1. 画面の中心座標を取得します。
2. パーティクルを生成する回数を設定します。
3. パーティクルを生成し、初期座標を設定します。
4. パーティクルの終了座標をランダムに設定します。
5. パーティクルを移動させるアニメーションを設定します。
6. アニメーションが終了したらパーティクルを削除します。

また、`getRandomNumber`関数は、指定した範囲の乱数を生成するために使用しています。

以上で、HTML、CSS、JavaScriptを組み合わせて、星型のパーティクルを画面の中心から放射状に拡散するアニメーションを実装することができます。

のように続きを出力してくれます。

「Javascriptのプログラム」の内容を最後に解説してくれるところも親切ですね。

このプログラムを実行してみると「縦と横のスクロールバー」が表示されて、しばらくスクロールしてから消えるだけで画面に何も表示されません。

どうやらブラウザの「表示画面の外」に何か描画しているようです。

プログラムの内容を読み解きながら、不具合箇所を変更していきました。

その中で「星型」を指定したはずのパーティクルが「丸型」だったため、「ChatGPT」に、

HTML内に「星型」を表示する「SVG要素」を教えてください。

と聞いてみると、

<svg width="100" height="100">
	<polygon points="50,10 10,90 90,35 10,35 90,90" style="fill:yellow;stroke:black;stroke-width:1" />
</svg>

のようにHTMLコードを出力してくれます。

わからない点を少しずつ聞いて解決していくことで、自分で調べるより各段に早くプログラムを作成することができますね。

この「SVG要素」を「appendChild」でDOMの子要素に追加する方法がわからなかったため、さらに、

下記のSVG要素をDOMに追加するJavascriptコードを教えてください。
<svg width="100" height="100"><polygon points="50,10 10,90 90,35 10,35 90,90" style="fill:yellow;stroke:black;stroke-width:1" /></svg>

のように聞いてみました。すると、

以下のように、JavaScriptを使用してSVG要素をDOMに追加することができます。
// 新しいSVG要素を作成する
const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");

// SVG要素の属性を設定する
svgElement.setAttribute("width", "100");
svgElement.setAttribute("height", "100");

// polygon要素を作成する
const polygonElement = document.createElementNS("http://www.w3.org/2000/svg", "polygon");

// polygon要素の属性を設定する
polygonElement.setAttribute("points", "50,10 10,90 90,35 10,35 90,90");
polygonElement.setAttribute("style", "fill:yellow;stroke:black;stroke-width:1");

// SVG要素にpolygon要素を追加する
svgElement.appendChild(polygonElement);

// SVG要素をDOMに追加する
document.body.appendChild(svgElement);
このコードでは、document.createElementNS()を使用して新しいSVG要素を作成し、setAttribute()を使用して要素の属性を設定します。次に、createElementNS()を使用して新しいpolygon要素を作成し、setAttribute()を使用してpolygon要素の属性を設定します。最後に、appendChild()を使用してSVG要素にpolygon要素を追加し、appendChild()を使用してSVG要素をDOMに追加します。

のようにコードを教えてくれます。

このままでは現在のプログラムに適用できないため、修正を加えながら適用していきました。

完成したプログラム

ここまで「ChatGPT」にサポートをしてもらいながら作成したプログラムは、

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style>
		/* ボタンのスタイル */
		button {
			background-color: #3498db;
			color: white;
			padding: 10px 20px;
			border: none;
			border-radius: 5px;
			font-size: 16px;
			cursor: pointer;
		}

		/* 画面の背景色 */
		body {
			/* ↓パーティクルが見えづらいため黒に変更↓ */
			/* background-color: #f2f2f2; */
			background-color: #000;

			/* ↓追加↓ */
			overflow: hidden;
			height: 100vh;
		}

		/* パーティクルのスタイル */
		.particle {
			position: absolute;
			/* ↓サイズが小さすぎるため変更↓ */
			/* width: 5px;
			height: 5px; *//*変更前のコード*/
			
			width: 100px;
			height: 100px;

			/* ↓「白色」だと背景色と同化して何も見えないため、「黄色」に変更↓ */
			/* background-color: white; *//*変更前のコード*/

			/* ↓背景色を変更↓ */
			background-color: #ffffff00;

			border-radius: 50%;
			animation: particleAnimation 1s ease-out;
		}

		/* パーティクルのアニメーション */
		@keyframes particleAnimation {
			0% {
				opacity: 1;
				transform: scale(1);
			}

			100% {
				opacity: 0;
				transform: scale(10);
			}
		}
	</style>
</head>

<body>
	<button onclick="createParticles()">Explode!</button>
	<div id="particles"></div>
	<script>
		function createParticles() {
			// 画面の中心座標を取得
			// ↓画面の中央にパーティクルが表示されないので調整↓
			const centerX = window.innerWidth / 4;
			const centerY = window.innerHeight / 4;

			// const centerX = window.innerWidth / 4;/*変更前のコード*/
			// const centerY = window.innerHeight / 4;/*変更前のコード*/

			const particleCount = 50;

			// パーティクルを生成
			for (let i = 0; i < particleCount; i++) {
				const particle = document.createElement("div");
				particle.classList.add("particle");

				// ↓星型のSVGを追加↓
				const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
				svgElement.setAttribute("width", "100");
				svgElement.setAttribute("height", "100");

				const polygonElement = document.createElementNS("http://www.w3.org/2000/svg", "polygon");
				polygonElement.setAttribute("points", "50,0 63,38 100,38 69,63 82,100 50,75 18,100 31,63 0,38 37,38");
				polygonElement.setAttribute("fill", "#FFFF00");

				svgElement.appendChild(polygonElement);

				particle.appendChild(svgElement);

				document.body.appendChild(particle);

				// パーティクルの初期座標を設定
				const x = centerX;
				const y = centerY;
				particle.style.left = x + "px";
				particle.style.top = y + "px";

				// パーティクルの終了座標をランダムに設定
				// ↓範囲が狭いため拡張↓
				const endX = centerX + getRandomNumber(-1000, 1000);
				const endY = centerY + getRandomNumber(-1000, 1000);

				// const endX = centerX + getRandomNumber(-1 * centerX, centerX);/*変更前のコード*/
				// const endY = centerY + getRandomNumber(-1 * centerY, centerY);/*変更前のコード*/

				// パーティクルを移動させるアニメーションを設定
				const animation = particle.animate([
					{ transform: `translate(${x}px, ${y}px)`, opacity: 1 },
					{ transform: `translate(${endX}px, ${endY}px)`, opacity: 0 }
				], {
					duration: 1000, // アニメーションの時間(ミリ秒)
					easing: "ease-out" // アニメーションのイージング
				});

				// アニメーションが終了したらパーティクルを削除
				animation.onfinish = () => {
					particle.remove();
				}
			}
		}

		// 指定した範囲の乱数を生成する関数
		function getRandomNumber(min, max) {
			return Math.random() * (max - min) + min;
		}
	</script>
</body>

</html>

のようになります。

プログラムの「変更した箇所」をわかりやすくするため、コメントで付記しています。

このプログラムを実行すると、

→パーティクルアニメーション

のようになります。

左上にある「Explode!」ボタンをクリックすると画面中央から「星型のパーティクル」が表示されます。

作成に取り組んだ時間は1時間ほどです。

「ChatGPTのサポート」が無いとこのアニメーションプログラムを作るのに何倍もの時間がかかりますね。

今回は「ChatGPT」で

  • ベースのプログラムの作成
  • わからない点を随時質問

という用途で利用していきました。

今後もさまざまなプログラムの作成に取り組みながら、より効率的な「ChatGPTの利用方法」を模索していきたいと思います。

HOMEへ