LoginSignup
5
2

More than 3 years have passed since last update.

three.jsで一筆書きのlineを作る

Last updated at Posted at 2019-12-09

作ったもの

一筆書きlineのリンク

初めに

Three.js Advent Calendar 2019の10日目の記事です。

今回、ご紹介するのはSVGをJSONに変換して、一筆書きのlineを作ろうというものです。

少し古くなってしまうのですが、
three.js r92
blender 2.79
を使用しています。

まず、blenderでSVGをインポートします。
ファイル > インポート > .svg

その際、インポートしたSVGはカーブになっていますので、SVGを選択した状態でAlt + Cを押して、メッシュに変換してください。

次は、インポートしたSVGをJSONにエクスポートします。
ファイル > エクスポート > .json
デフォルトでは、JSONのエクスポートはないため、アドオンを追加する必要があり、こちらの記事が参考になります。

3Dデータ(Blender)をThree.jsで表示するまでの方法

JSONをエクスポートする際のオプションですが今回は頂点情報のみを使用するので、
Geometry
タイプ: geometry
index Buffer: なし
エクスポートするもの 頂点にのみチェックを入れる、でやっています。

コード

頂点座標を配列に追加する関数を書きます。

function addVertexBuffer(geometry, index, x, y, z){
    var index = index*3;
    var array = geometry.attributes.position.array;
    array[index]   = x;
    array[index+1] = y;
    array[index+2] = z;
};

描くlineの設定を書きます。

function drawDynamicLine(){
    var geometry = new THREE.BufferGeometry();

    // JSONの読み込み
    var request = new XMLHttpRequest();
    request.open("GET", "think.json", false);
    request.send(null);
    var json_l = JSON.parse(request.responseText);

    var positions = new Float32Array(maxpoints * 3);
    geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));

    var material = new THREE.LineBasicMaterial({color: 0xffd700});

    var line = new THREE.Line(geometry, material);

    var points = new Float32Array(json_l["vertices"]);

    for(var i=0; i<maxpoints; i++){
        var x = points[i*3+0];
        var y = points[i*3+1];
        var z = points[i*3+2];
        addVertexBuffer(line.geometry, i, x, y, z);
    }
    line.position.z = 0.3;
    scene.add(line);
}

繰り返す関数を書きます。

function animate() {
    line.geometry.setDrawRange( 0, drawCount );

    if(drawCount > maxpoints) drawCount = maxpoints;
    drawCount += 2;

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

    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}

Sceneなどを設定します。

function setup() {
    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 100);

    var ambientLight = new THREE.AmbientLight(0xffffff);
    scene.add(ambientLight);

    var directionalLight = new THREE.DirectionalLight(0xffffff);
    directionalLight.position.set(1, 1, 1).normalize();
    scene.add(directionalLight);

    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    drawDynamicLine();
}

setup();
animate();

最後に

個人の感想ですが、lineが時間の経過とともに描かれていくのは、とても面白いです。
僕が作ったものでは、lineがZ軸上は移動していないので、Z軸も移動させるとまた違うものができてくると思います。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2