最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to smoothly animate drawing of a line - Stack Overflow

programmeradmin3浏览0评论

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.

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.

Share Improve this question edited Feb 16, 2017 at 20:31 WestLangley 105k11 gold badges287 silver badges283 bronze badges asked Feb 14, 2017 at 15:18 Filemon279Filemon279 1882 silver badges11 bronze badges 2
  • Can you say why using Tween isn't a good idea in your use case ? – Console-buche Commented Feb 14, 2017 at 18:05
  • Yes. I have about 40 curved lines and I would like to show all of them equally. It should look like scanner. I do not generate lines by myself so there is different amount of points and all of them are in different places. So with Tween I would have to make abut 40 different animation with different time of executing and that should be done about 200 times (for largest line). What's more I do not want to use Line() to push vertex to line since I've tried that and animation had about 20fps. – Filemon279 Commented Feb 14, 2017 at 19:43
Add a ment  | 

2 Answers 2

Reset to default 7

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; // points is an array of Vector3
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.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
geometry.setAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
geometry.setAttribute( '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: true,
    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;

Note: You can pute 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.143

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

Maybe a change gives better results.

发布评论

评论列表(0)

  1. 暂无评论