This is what I'd like to achieve (a modifiable polygon where the red circles are vertices) and I'd like to build the polygon dynamically.
When initiating the geometry as
var geometry = new THREE.Geometry(); geometry.vertices.push(point); geometry.vertices.push(point); var line = new THREE.Line(geometry, new THREE.LineBasicMaterial({}));
it works well until the second click, it builds a straight line between 1 and 2 but does not add a third line when it's pushed to the array. WebGL seems to require buffered points.
When I predefine vertices like this I can draw two lines (third click)
var geometry = new THREE.Geometry(); for (var i = 0; i < 4; i++) { geometry.vertices.push(point); } var line = new THREE.Line(geometry, new THREE.LineBasicMaterial({}));
but this is not a good solution as I don't know how many vertices does the user want to add and it's pointless to assign it a big number as I have to loop it multiple times.
Is there any way around it?
Objects in three. js exist in a three-dimensional space with x, y, and z axes. Your view of those points is determined by the camera, which also exists in three-dimensional space. This allows a bunch of stuff like zooming past 3D objects, or rotating around them, that we don't need for this 2D visualization.
three. js is a JavaScript-based WebGL engine that can run GPU-powered games and other graphics-powered apps straight from the browser. The three. js library provides many features and APIs for drawing 3D scenes in your browser.
You can animate a line -- or increase the number of points rendered -- very easily using BufferGeometry
and the setDrawRange()
method. You do need to set a maximum number of points, however.
var MAX_POINTS = 500; // geometry var geometry = new THREE.BufferGeometry(); // attributes var positions = new Float32Array( MAX_POINTS * 3 ); // 3 vertices per point geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); // draw range drawCount = 2; // draw the first 2 points, only geometry.setDrawRange( 0, drawCount ); // material var material = new THREE.LineBasicMaterial( { color: 0xff0000 } ); // line line = new THREE.Line( geometry, material ); scene.add( line );
You set the position data using a pattern like this one:
var positions = line.geometry.attributes.position.array; var x = y = z = index = 0; for ( var i = 0, l = MAX_POINTS; i < l; i ++ ) { positions[ index ++ ] = x; positions[ index ++ ] = y; positions[ index ++ ] = z; x += ( Math.random() - 0.5 ) * 30; y += ( Math.random() - 0.5 ) * 30; z += ( Math.random() - 0.5 ) * 30; }
If you want to change the number of points rendered after the first render, do this:
line.geometry.setDrawRange( 0, newValue );
If you want to change the position data values after the first render, you set the needsUpdate
flag like so:
line.geometry.attributes.position.needsUpdate = true; // required after the first render
Here is a fiddle showing an animated line which you can adapt to your use case.
EDIT: See this answer for a technique that you may like better -- especially if the line consists of only a few points.
three.js r.84
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With