如何使用three.js在运行时绘制线段

use*_*133 2 javascript three.js

我是Three.js的新手,我正在尝试实现Microsoft Paint中用于绘制线段的技术。我试图获取点onMouseDown的坐标,然后使用onMouseMove扩展一条线,直到onMouseDown。请帮忙!

aca*_*lon 6

three.js主要用于3D绘图。如果您想复制2D绘图应用程序(例如paint),则使用2D画布可能会更容易:canvas.getContext("2d");

我将假设您确实要绘制Three.js。在这种情况下,我整理了这个示例。跟着这些步骤:

  1. 单击页面上的任意位置,然后在周围拖动鼠标以画一条线。该线在z平面上绘制。
  2. 单击“形状”按钮,然后注意一个形状在里面的位置更近,另一个形状的位置更近,这是因为一个形状在z平面上方,而另一个在后面。
  3. 单击“旋转”按钮,这将使相机缩小并绕轴旋转。请注意,当您穿过z平面时,所有图形都在该平面上。

看一下代码,主要部分是:

您需要将鼠标单击坐标投影到平面上。这是通过以下功能完成的:

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;
}
Run Code Online (Sandbox Code Playgroud)

然后从上一点到现在画一条线:

geometry.vertices.push(lastPoint);
geometry.vertices.push(pos);
var line = new THREE.Line(geometry, material);
scene.add(line);
Run Code Online (Sandbox Code Playgroud)

请注意,当旋转时接近通过z平面时,到Z的投影距离很远并且超出范围,为防止发生这种情况,请执行以下检查:

if( Math.abs(lastPoint.x - pos.x) < 500 && Math.abs(lastPoint.y - pos.y) < 500 && Math.abs(lastPoint.z - pos.z) < 500 )
Run Code Online (Sandbox Code Playgroud)

作为参考,我在此处(SO答案)和此处(three.js示例)找到了有关投影鼠标坐标的信息。

更新资料

要从mousedown位置到mouseup位置画一条线,请参阅此演示。代码更改是改为在鼠标向上的点之间进行绘制。

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());
        }
    }
}      
Run Code Online (Sandbox Code Playgroud)