How to smoothly animate drawing of a line

半城伤御伤魂 提交于 2019-12-30 05:23:05

问题


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 is smooth only for line with >200 points. I've tried TWEEN.js but it in this case it wasn't good idea. Is there any other option to make it happen?

In Unreal Engine 4 this problem can be resolved by setting opacity in masked material and update it every tick (and we have drawing effect).

I would like to hear from you if you have any ideas how can I try to do it.

Best regards.


回答1:


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




回答2:


You can draw Lines with LineSegments: https://threejs.org/docs/api/objects/LineSegments.html and the other way: https://threejs.org/docs/api/objects/Line.html

Maybe a change gives better results.



来源:https://stackoverflow.com/questions/42229799/how-to-smoothly-animate-drawing-of-a-line

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!