2020年10月09日

Three.jsでラインアニメーション

JavaScriptで取り組むクリエイティブコーディング パーリンノイズを使いこなせ」を参考に、Three.jsでラインアニメーションを試してみました。※Three.jsはr120を使用しています。

Three.jsでラインアニメーション

● ラインを生成

ラインを生成します。

始点と終点の頂点座標を設定し、頂点座標の配列からsetFromPointsを使用して、BufferGeometryを生成してラインを生成します。

//頂点座標の配列
const points = [];
points.push(new THREE.Vector3(0,3,0));
points.push(new THREE.Vector3(5,3,0));

//頂点座標の配列からBufferGeometryを生成
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial();
const line = new THREE.Line(geometry,material);
scene.add(line);

● 頂点座標の設定

始点と終点以外の頂点座標も設定します。ラインの長さと分割数は自由に調整できるようにしました。

//ラインの長さ
const lineLength = 10;

//ラインの分割数
const segmentNum = 10;

//頂点座標の配列
const points = [];

//頂点座標を設定
for(let i = 0; i <= segmentNum; i++){
	const x = ((lineLength/segmentNum) * i) - lineLength / 2;
	const y = 3;
	const z = 0;
	const p = new THREE.Vector3(x,y,z);
	points.push(p);
}

● パーリンノイズの設定

パーリンノイズを設定して、ラインを曲線にします。

各頂点のY軸の値をパーリンノイズによってランダムにすることで、ラインを曲線にします。

パーリンノイズは「perlin.js」を使用して生成します。

const lineLength = 10;
const segmentNum = 100;

//振り幅
const amplitude = 5;

const points = [];
const time = Date.now() / 4000;

for(let i = 0; i <= segmentNum; i++){
	const x = ((lineLength/segmentNum) * i) - lineLength / 2;

	//Y軸にパーリンノイズを設定
	const px = i / 50;
	const py = time;
	const y =  amplitude * noise.perlin2(px,py) + 3;

	const z = 0;
	const p = new THREE.Vector3(x,y,z);
	points.push(p);
}

const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial();
const line = new THREE.Line(geometry,material);
scene.add(line);

● ライン数の増加

ライン数を増やします。ライン数は自由に調整できるようにしました。

//ライン数
const lineNum = 50;

const lineLength = 10;
const segmentNum = 100;
const amplitude = 5;

const time = Date.now() / 4000;

for(let i = 0; i < lineNum; i++){
	const points = [];

	for(let j = 0; j <= segmentNum; j++){
		const x = ((lineLength/segmentNum) * j) - lineLength / 2;
		const px = j / (50 + i);
		const py = i / 50 + time;
		const y = amplitude * noise.perlin2(px,py) + 3;

		//Z軸を調整
		const z = i * 0.1 - ((lineNum * 0.1) / 2);

		const p = new THREE.Vector3(x,y,z);
		points.push(p);
	}

	const geometry = new THREE.BufferGeometry().setFromPoints(points);
	const material = new THREE.LineBasicMaterial();

	const line = new THREE.Line(geometry,material);
	scene.add(line);
}

● ラインカラーの調整

ラインカラーを調整します。

HSL色空間は、色相(Hue)、彩度(Saturation)、輝度(Lightness)で色を表現し、彩度や輝度で色を調整することができます。

const h = Math.round((i / lineNum) * 360);
const s = 100;
const l = Math.round((i / lineNum) * 100);
const color = new THREE.Color(`hsl(${h},${s}%,${l}%)`);

const material = new THREE.LineBasicMaterial({
	color:color
});

● アニメーション

ラインをアニメーションさせます。

let lineArr = [];
const lineNum = 50;
const lineLength = 10;
const segmentNum = 100;
const amplitude = 5;

for(let i = 0; i < lineNum; i++){
	const points = [];

	for(let j = 0; j <= segmentNum; j++){
		const x = ((lineLength/segmentNum) * j) - lineLength / 2;
		const y = 0;
		const z = i * 0.3 - ((lineNum * 0.3) / 2);;
		const p = new THREE.Vector3(x,y,z);
		points.push(p);
	}

	const geometry = new THREE.BufferGeometry().setFromPoints(points);
	const material = new THREE.LineBasicMaterial();

	const line = new THREE.Line(geometry,material);
	lineArr[i] = line;
	scene.add(lineArr[i]);
}

function rendering(){
	requestAnimationFrame(rendering);

	for(let i = 0; i < lineNum; i++){
		const line = lineArr[i];
		const positions = line.geometry.attributes.position.array;
		const time = Date.now() / 4000;

		for(let j = 0; j <= segmentNum; j++){
			const x = ((lineLength/segmentNum) * j) - lineLength / 2;
			const px = j / (50 + i);
			const py = i / 50 + time;
			const y =  amplitude * noise.perlin2(px,py);
			const z = i * 0.3 - ((lineNum * 0.3) / 2);
			positions[j * 3] = x;
			positions[j * 3 + 1] = y;
			positions[j * 3 + 2 ] = z;
		}

		const h = Math.round((i / lineNum) * 360);
		const s = 100;
		const l = Math.round((i / lineNum) * 100);
		const color = new THREE.Color(`hsl(${h},${s}%,${l}%)`);

		line.material.color = color;

		line.geometry.attributes.position.needsUpdate = true;
	}

	renderer.render(scene,camera);
}

完成したデモになります。ラインの長さやカラー、カメラワークを調整しました。

  • このエントリーをはてなブックマークに追加

関連記事

前の記事へ

球体の頂点アニメーション

次の記事へ

Three.jsで球体アニメーション