2020年10月09日 - WebVR・Three.js
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); }
● パーリンノイズの設定

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); }
完成したデモになります。ラインの長さやカラー、カメラワークを調整しました。