Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
44
rated 0 times [  49] [ 5]  / answers: 1 / hits: 7842  / 10 Years ago, tue, april 8, 2014, 12:00:00

I am new to Three.js and I'm trying to implement the technique used in Microsoft Paint for drawing a line segment. I'm trying to get coordinates of a point onMouseDown then extend a line with onMouseMove until onMouseDown. Please help!


More From » three.js

 Answers
5

three.js is mainly for drawing in 3D. If you want to copy a 2D drawing application like paint then using the 2D canvas will probably be easier: canvas.getContext(2d);.



I will assume that you do want to draw in three.js. In which case I have put together this example. Follow these steps:




  1. Click anywhere on the page and drag the mouse around to draw a line. The line is drawn on the z plane.

  2. Click the Shapes button and notice how one shape is closer in and the other further, that is because one is above the z plane and the other behind.

  3. Click the Rotate button, this will cause the camera to zoom out and rotate around the axes. Notice that when you pass through the z plane all your drawing is on that plane.



Have a look at the code, the main parts are:



You need to project the mouse click coordinates onto the plane. This is done with this function:



function get3dPointZAxis(event)
{
var vector = new THREE.Vector3(
( event.clientX / window.innerWidth ) * 2 - 1,
- ( event.clientY / window.innerHeight ) * 2 + 1,
0.5 );
projector.unprojectVector( vector, camera );
var dir = vector.sub( camera.position ).normalize();
var distance = - camera.position.z / dir.z;
var pos = camera.position.clone().add( dir.multiplyScalar( distance ) );
return pos;
}


Then draw the line from previous to this point:



geometry.vertices.push(lastPoint);
geometry.vertices.push(pos);
var line = new THREE.Line(geometry, material);
scene.add(line);


Note that when you get close to passing through the z plane while rotating, the projection to Z is very far off and you go out of bounds, to prevent this the following check is done:



if( Math.abs(lastPoint.x - pos.x) < 500 && Math.abs(lastPoint.y - pos.y) < 500 && Math.abs(lastPoint.z - pos.z) < 500 )


For reference, I found information for projecting the mouse coordinate here (SO answer) and here (three.js sample).



Update



To draw a line from the mousedown position to the mouseup position see this demo. The code changes are to instead just do the draw between points on mouse up.



function stopDraw(event)
{
if( lastPoint )
{
var pos = get3dPointZAxis(event);
var material = new THREE.LineBasicMaterial({
color: 0x0000ff
});
var geometry = new THREE.Geometry();
if( Math.abs(lastPoint.x - pos.x) < 2000 && Math.abs(lastPoint.y - pos.y) < 2000 && Math.abs(lastPoint.z - pos.z) < 2000 )
{
geometry.vertices.push(lastPoint);
geometry.vertices.push(pos);

var line = new THREE.Line(geometry, material);
scene.add(line);
lastPoint = pos;
}
else
{
console.debug(lastPoint.x.toString() + ':' + lastPoint.y.toString() + ':' + lastPoint.z.toString() + ':' +
pos.x.toString() + ':' + pos.y.toString() + ':' + pos.z.toString());
}
}
}

[#46202] Monday, April 7, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
victorr

Total Points: 193
Total Questions: 86
Total Answers: 105

Location: Pitcairn Islands
Member since Thu, Jun 24, 2021
3 Years ago
;