Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/446.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Three.js使用鼠标绘制三维矩形_Javascript_3d_Three.js_Rectangles - Fatal编程技术网

Javascript Three.js使用鼠标绘制三维矩形

Javascript Three.js使用鼠标绘制三维矩形,javascript,3d,three.js,rectangles,Javascript,3d,Three.js,Rectangles,所以,我想用我的鼠标画一个3D矩形。经过几个小时的尝试,我发布了这个问题 我设法画了一个可调整大小的矩形。我通过编辑和更新顶点来实现这一点 我做了一个JSFIDLE: 我这里有几个问题: 当我开始拖动时,矩形不会将其自身定位在鼠标所在的位置 矩形的大小调整方向错误(如果在旋转相机时也能正确调整大小,那就太好了) 有人能帮我吗 如果您想要纯HTML: <!DOCTYPE html> <html lang="en"> <head> <meta c

所以,我想用我的鼠标画一个3D矩形。经过几个小时的尝试,我发布了这个问题

我设法画了一个可调整大小的矩形。我通过编辑和更新顶点来实现这一点

我做了一个JSFIDLE:

我这里有几个问题:

  • 当我开始拖动时,矩形不会将其自身定位在鼠标所在的位置
  • 矩形的大小调整方向错误(如果在旋转相机时也能正确调整大小,那就太好了)
有人能帮我吗

如果您想要纯HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>RSCEDIT - Test</title>

    <style>
        body {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
        }
        #main {
            width: 100%;
            height: 100%;
            display: block;
            padding: 0;
            margin: 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <canvas id="main"></canvas>
    </div>

    <script src="https://rscedit.io/assets/client/js/core/libraries/jquery.min.js"></script>

    <script type="text/javascript" src="https://rscedit.io/assets/client/js/threejs/three.min.js"></script>
    <script type="text/javascript" src="https://rscedit.io/assets/client/js/threejs/Detector.js"></script>
    <script type="text/javascript" src="https://rscedit.io/assets/client/js/threejs/controls/OrbitControls.js"></script>
    <script type="text/javascript" src="https://rscedit.io/assets/client/js/threejs/Projector.js"></script>
    <script type="text/javascript" src="https://rscedit.io/assets/client/js/threejs/dat.gui.min.js"></script>

    <script>

        var canvas = document.getElementById('main');

        var renderer = new THREE.WebGLRenderer({
            canvas: canvas
        });

        var scene = new THREE.Scene();

        var camera = new THREE.PerspectiveCamera(45, canvas.clientWidth / canvas.clientHeight, 1, 100000);

        var geometry = new THREE.Geometry();

        var rayCaster = new THREE.Raycaster();

        var controls;

        var dragging = false;

        var startPosition = {
            x: 0,
            y: 0
        };

        var vertexSize = 2;

        onLoad();

        function onLoad() {

            canvas.onmousedown = onMouseDown;
            canvas.onmousemove = onDrag;
            canvas.onmouseup = onMouseUp;

            renderer.setSize(canvas.clientWidth, canvas.clientHeight);

            camera.position.set(0, 0, 25.0);
            scene.add(camera);

            /*
             * Create a Rectangle
             */
            geometry.vertices.push(new THREE.Vector3(-vertexSize, vertexSize, 0.0));
            geometry.vertices.push(new THREE.Vector3(vertexSize, vertexSize, 0.0));
            geometry.vertices.push(new THREE.Vector3(vertexSize, -vertexSize, 0.0));
            geometry.vertices.push(new THREE.Vector3(-vertexSize, -vertexSize, 0.0));
            geometry.faces.push(new THREE.Face3(0, 1, 2));
            geometry.faces.push(new THREE.Face3(0, 2, 3));

            var material = new THREE.MeshBasicMaterial({
                color: 0xDB1E1E,
                wireframe: true
            });

            var mesh = new THREE.Mesh(geometry, material);
            mesh.rotation.x = Math.PI / 2;
            scene.add(mesh);

            var gridSize = 20;
            var divisions = 20;
            var gridHelper = new THREE.GridHelper(gridSize, divisions);
            scene.add(gridHelper);

            controls = new THREE.OrbitControls(camera, renderer.domElement);

            render();
        }

        function update(index, x, y) {
            geometry.vertices[index].set(x, y, 0);
            geometry.verticesNeedUpdate = true;
        }

        function render() {
            requestAnimationFrame(render);
            renderer.render(scene, camera);
        }

        function onMouseDown(e) {
            var relative = get3DPosition(e);
            if (!relative) {
                return;
            }
            dragging = true;
            startPosition.x = e.pageX;
            startPosition.y = e.pageY;
            scene.children[1].position.set(relative.x + vertexSize, relative.y, relative.z);
            controls.enabled = false;
        }

        function onDrag(e) {
            if (dragging) {
                var clientX = (e.pageX - startPosition.x) / 50;
                var clientY = (e.pageY - startPosition.y) / 50;
                var vertices = geometry.vertices;
                vertices[1].x = clientX;
                vertices[2].x = clientX;
                vertices[2].y = -clientY;
                vertices[3].y = -clientY;
                geometry.verticesNeedUpdate = true;
            }
        }

        function onMouseUp(e) {
            dragging = false;
            controls.enabled = true;
        }

        function get3DPosition(event) {
            var offset = $(canvas).offset();
            var position = {
                x: ((event.clientX - offset.left) / canvas.clientWidth) * 2 - 1,
                y: -((event.clientY - offset.top) / canvas.clientHeight) * 2 + 1
            };
            rayCaster.setFromCamera(position, camera);
            var intersects = rayCaster.intersectObjects(scene.children, true);
            if (intersects.length > 0) {
                return intersects[0].point;
            }
        }

    </script>
</body>
</html>

RSCEDIT-测试
身体{
保证金:0;
填充:0;
宽度:100%;
身高:100%;
}
#主要{
宽度:100%;
身高:100%;
显示:块;
填充:0;
保证金:0;
}
var canvas=document.getElementById('main');
var renderer=new THREE.WebGLRenderer({
画布:画布
});
var scene=new THREE.scene();
var摄像机=新的三视角摄像机(45,canvas.clientWidth/canvas.clientHeight,11000);
var geometry=new THREE.geometry();
var rayCaster=new THREE.rayCaster();
风险值控制;
var=false;
var起始位置={
x:0,,
y:0
};
var vertexSize=2;
onLoad();
函数onLoad(){
canvas.onmousedown=onmousedown;
canvas.onmousemove=onDrag;
canvas.onmouseup=onmouseup;
renderer.setSize(canvas.clientWidth、canvas.clientHeight);
摄像机位置设置(0,0,25.0);
场景。添加(摄影机);
/*
*创建一个矩形
*/
geometry.Vertex.push(新的3.Vector3(-vertexSize,vertexSize,0.0));
geometry.Vertex.push(新的3.Vector3(vertexSize,vertexSize,0.0));
geometry.Vertex.push(新的3.Vector3(vertexSize,-vertexSize,0.0));
geometry.Vertex.push(新的3.Vector3(-vertexSize,-vertexSize,0.0));
几何.faces.push(新的三个面3(0,1,2));
几何.faces.push(新的三个面3(0,2,3));
var材料=新的三网格基本材料({
颜色:0xDB1E1E,
线框:正确
});
var mesh=新的三个网格(几何体、材质);
mesh.rotation.x=Math.PI/2;
场景。添加(网格);
var-gridSize=20;
var分区=20;
var gridHelper=new THREE.gridHelper(gridSize,divisions);
添加(gridHelper);
控件=新的三个.轨道控件(摄影机、渲染器.doElement);
render();
}
函数更新(索引,x,y){
几何体.顶点[索引].集合(x,y,0);
geometry.verticesNeedUpdate=true;
}
函数render(){
请求动画帧(渲染);
渲染器。渲染(场景、摄影机);
}
函数onMouseDown(e){
var relative=get3DPosition(e);
如果(!相对){
返回;
}
拖动=真;
startPosition.x=e.pageX;
startPosition.y=e.pageY;
scene.children[1].position.set(relative.x+vertexSize,relative.y,relative.z);
controls.enabled=false;
}
函数onDrag(e){
如果(拖动){
var clientX=(e.pageX-startPosition.x)/50;
var clientY=(e.pageY-startPosition.y)/50;
var顶点=geometry.vertices;
顶点[1]。x=clientX;
顶点[2].x=clientX;
顶点[2]。y=-clientY;
顶点[3]。y=-clientY;
geometry.verticesNeedUpdate=true;
}
}
函数onMouseUp(e){
拖动=假;
controls.enabled=true;
}
函数get3DPosition(事件){
var offset=$(canvas.offset();
变量位置={
x:((event.clientX-offset.left)/canvas.clientWidth)*2-1,
y:-((event.clientY-offset.top)/canvas.clientHeight)*2+1
};
rayCaster.setFromCamera(位置,摄像头);
var intersects=rayCaster.intersectObjects(scene.children,true);
如果(相交长度>0){
返回与[0]相交的点;
}
}

谢谢

谢谢你分享你的小提琴!这将是一个完全伟大的帮助,我正在工作的时刻

目前对这种编码还是很陌生的,但我把你的JFiddle弄乱了,发现:

  • 鼠标到框拖动的精度受摄影机在网格中的位置影响,因此我将其锁定为“关闭”,并将其设置为“正交”以及
  • 将“*-1”添加到每个vertice“onDrag”命令中(因为 盒子朝相反的方向调整大小
  • 将初始框大小设置为0以从鼠标位置拖出
这是要检查的JFiddle,希望它有帮助!您可以随时将相机更改回原来的状态,并将
controls.enabled=false
再次设置为true


看起来很不错。我很惊讶有人解决了这个问题。虽然我不再需要它了。我正在创建自己的矩形(瓷砖)并动态更改顶点的材质以将其标记为选中。这要容易得多。例如:由于我当前使用的电脑,gif速度非常慢。如果您愿意,我可以在家中发布更快的gif。