【御茶ノ水駅】電源&Wi-Fiの使えるカフェ12選!勉強・仕事・ノマドワークにおすすめ
- Wi-Fi
 - カフェ
 - ノマド
 

線を使ったアニメーションは、流れ星や紙吹雪、風の動きなど、さまざまなモチーフの表現をより豊かにしてくれます。
今回はTHREE.MeshLineを使い、リボンのように滑らかに線が動くアニメーションを作る方法を、5つのデモとともにご紹介します。オリジナルのアニメーションを作る際は、ぜひ参考にしてみてください。
筆者は2年前から、Jaume Sanchez EliasがThree.js用に作成したライブラリ『THREE.MeshLine』を使用して、WebGLでヌルヌルと動く線を作りはじめました。
THREE.MeshLineの特徴は、Three.jsが長年抱えてきた「線の幅が変更できない」という問題に取り組んでいる点にあります。MeshLineは、幅のパラメーターをサポートしていないGL_LINEメソッドのかわりに、ビルボードを使った三角形ストリップでカスタムジオメトリを作成しています。
リボンのような線にはユニークな魅力があります。また太い線を作る際によく使用されるTubeGeometryより、頂点が少ないのも特徴のひとつです。
THREE.MeshLineに唯一欠けているのが、各フレームのジオメトリを再構築することなく、線にアニメーションをつける機能です。
SVGラインアニメーションの仕組みに基づいて、シェーダーを介してアニメーションをつけた破線を直接視覚化するために、MeshLineMaterialに3つの新しいパラメータを追加しました。
これらのパラメーターを使用するとSVGパスと同じく、トレースされた線全体にアニメーションをつけられます。
以下はMeshLineを作成してアニメーションをつける方法の例です。
  // Build an array of points
  const segmentLength = 1;
  const nbrOfPoints = 10;
  const points = [];
  for (let i = 0; i < nbrOfPoints; i++) {
    points.push(i * segmentLength, 0, 0);
  }
  // Build the geometry
  const line = new MeshLine();
  line.setGeometry(points);
  const geometry = line.geometry;
  // Build the material with good parameters to animate it.
  const material = new MeshLineMaterial({
    transparent: true,
    lineWidth: 0.1,
    color: new Color('#ff0000'),
    dashArray: 2,     // always has to be the double of the line
    dashOffset: 0,    // start the dash at zero
    dashRatio: 0.75,  // visible length range min: 0.99, max: 0.5
  });
  // Build the Mesh
  const lineMesh = new Mesh(geometry, material);
  lineMesh.position.x = -4.5;
  // ! Assuming you have your own webgl engine to add meshes on scene and update them.
  webgl.add(lineMesh);
  // ! Call each frame
  function update() {
    // Check if the dash is out to stop animate it.
    if (lineMesh.material.uniforms.dashOffset.value < -2) return;
    // Decrement the dashOffset value to animate the path with the dash.
    lineMesh.material.uniforms.dashOffset.value -= 0.01;
  }
すると、このようなアニメーションが完成します。

ここまでで、線にアニメーションをつける方法がわかりましたね。
次は線の形をカスタマイズしてみましょう。
配置されている点の配列をなめらかにしてくれる、SplineCurveもしくはCatmullRomCurve3を使ってみましょう。流れるような曲線を作り、それらの長さ・方向・動きなどをコントロールするのにぴったりです。
先ほど作った線に、動きを追加してみましょう。
 const segmentLength = 1;
  const nbrOfPoints = 10;
  const points = [];
  const turbulence = 0.5;
  for (let i = 0; i < nbrOfPoints; i++) {
    // ! We have to wrapped points into a THREE.Vector3 this time
    points.push(new Vector3(
      i * segmentLength,
      (Math.random() * (turbulence * 2)) - turbulence,
      (Math.random() * (turbulence * 2)) - turbulence,
    ));
  }
次にジオメトリを作成する前に、クラスのうちひとつを使用して線の配列をなめらかにします。
 // 2D spline
  // const linePoints = new Geometry().setFromPoints(new SplineCurve(points).getPoints(50));
  // 3D spline
  const linePoints = new Geometry().setFromPoints(new CatmullRomCurve3(points).getPoints(50));
  const line = new MeshLine();
  line.setGeometry(linePoints);
  const geometry = line.geometry;
すると、以下のような滑らかな曲線が完成します!

おすすめは、パフォーマンスがよく、さまざまなケースの曲線を作るのに十分な機能を備えているSplineCurveです。
ただし、3D(X・Y・Z軸)を考慮にいれているCatmullRomCurve3に対して、SplineCurveがなめらかにできるのは2D(X・Y軸)に限られるという点には注意しましょう。
以下の作品もSplineCurveで作られています。
 
THREE.MeshLineの例では、シーンに既に存在するMeshをRaycasterを使ってスキャンするというテクニックが使われています。
この方法を使うと、オブジェクトの形に沿った線を作れるのです。
const radius = 4;
  const yMax = -4;
  const points = [];
  const origin = new Vector3();
  const direction = new Vector3();
  const raycaster = new Raycaster();
  let y = 0;
  let angle = 0;
  // Start the scan
  while (y < yMax) {
    // Update the orientation and the position of the raycaster
    y -= 0.1;
    angle += 0.2;
    origin.set(radius * Math.cos(angle), y, radius * Math.sin(angle));
    direction.set(-origin.x, 0, -origin.z);
    direction.normalize();
    raycaster.set(origin, direction);
    // Save the coordinates raycsted.
    // !Assuming the raycaster cross the object in the scene each time
    const intersect = raycaster.intersectObject(objectToRaycast, true);
    if (intersect.length) {
      points.push(
        intersect[0].point.x,
        intersect[0].point.y,
        intersect[0].point.z,
      );
    }
  }
この方法は、Boreal Skyのデモにも採用されています。objectToRaycastを作成するためのジオメトリとして、ここでは球体パーツを使用しました。

本記事では、MeshLineにアニメーションをつけるのに十分なツールをご紹介しました。
今回ご紹介した内容の多くは、ライブラリの例を参考にしています。みなさんもThree.jsのライブラリ『THREE.MeshLine』を研究し、オリジナルの線を作ってみてください!
(原文:Jérémie Boulay 翻訳:Asuka Nakajima)
あわせて読みたい!▼
Three.jsでパーティクルアニメーションを作ってみよう
Workship MAGAZINE
Three.jsで波形アニメーションを作ってみよう!! ビルがニョキニョキ生えてくる?!
Workship MAGAZINE
チュートリアルをなぞるだけ!Three.jsでインタラクティブエフェクトを作ろう
Workship MAGAZINE