How to smoothly animate drawing of a line

前端 未结 2 700
情话喂你
情话喂你 2021-01-03 14:28

I have about 40 curved lines and all of them have from 30 to 200 points. I draw all of them equally using BufferGeometry and setDrawRange() but it

2条回答
  •  礼貌的吻别
    2021-01-03 15:12

    You can smoothly animate the drawing of a line -- even if the line consists of only a few points -- by using LineDashedMaterial.

    The trick is to render only one dash, and increment the length of the dash in the animation loop.

    // geometry
    var geometry = new THREE.BufferGeometry();
    
    // attributes
    numPoints = points.length;
    var positions = new Float32Array( numPoints * 3 ); // 3 vertices per point
    var colors = new Float32Array( numPoints * 3 ); // 3 channels per point
    var lineDistances = new Float32Array( numPoints * 1 ); // 1 value per point
    
    geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
    geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
    geometry.addAttribute( 'lineDistance', new THREE.BufferAttribute( lineDistances, 1 ) );
    
    // populate
    var color = new THREE.Color();
    
    for ( var i = 0, index = 0, l = numPoints; i < l; i ++, index += 3 ) {
    
        positions[ index ] = points[ i ].x;
        positions[ index + 1 ] = points[ i ].y;
        positions[ index + 2 ] = points[ i ].z;
    
        color.setHSL( i / l, 1.0, 0.5 );
    
        colors[ index ] = color.r;
        colors[ index + 1 ] = color.g;
        colors[ index + 2 ] = color.b;
    
        if ( i > 0 ) {
    
            lineDistances[ i ] = lineDistances[ i - 1 ] + points[ i - 1 ].distanceTo( points[ i ] );
    
        }
    
    }
    
    lineLength = lineDistances[ numPoints - 1 ];
    
    // material
    var material = new THREE.LineDashedMaterial( {
    
        vertexColors: THREE.VertexColors,
        dashSize: 1, // to be updated in the render loop
        gapSize: 1e10 // a big number, so only one dash is rendered
    
    } );
    
    // line
    line = new THREE.Line( geometry, material );
    scene.add( line );
    

    Then, in the animation loop:

    fraction = ( fraction + 0.001 ) % 1; // fraction in [ 0, 1 ]
    
    line.material.dashSize = fraction * lineLength;
    

    fiddle: http://jsfiddle.net/156yxd3L/

    Note: You can compute the line distances any way you want. For example, you could normalize the distances by the total length, so the distance to the last point is 1. You would then vary dashSize from 0 to 1.


    Compare this approach with this alternate method.

    three.js r.84

提交回复
热议问题