javascript - Three.js 使用鼠标绘制3D矩形

标签 javascript 3d three.js rectangles

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

我设法绘制了一个可调整大小的矩形。我通过编辑和更新顶点来做到这一点。

我做了一个jsfiddle:https://jsfiddle.net/bgzrcx46/7/

我在这里遇到一些问题:

  • 当我开始拖动时,矩形不会将其自身定位在鼠标所在的位置
  • 矩形以错误的方向调整大小(如果您在旋转相机时也能做到这一点,那就太好了)

谁能帮我解决这个问题吗?

如果您想要纯 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>

谢谢!

最佳答案

感谢您分享您的 JFiddle!这对我目前正在做的事情会有很大的帮助!!

目前对所有这些编码还是很陌生,但我弄乱了你的 JFiddle 并发现:

  • 鼠标到框拖动的准确性受到相机在网格中的位置的影响,因此我将其锁定并将其设置为正交......
  • 将“* -1”添加到每个顶点“onDrag”命令中(因为 盒子正在以相反的方向调整自身的大小。
  • 将初始框大小设置为0以从鼠标位置拖出

这是要检查的JFiddle,希望对您有所帮助!您随时可以将摄像头调回原来的位置,并将 controls.enabled = false 再次设置为 true。

https://jsfiddle.net/JoshyB/o2ze8qer/

关于javascript - Three.js 使用鼠标绘制3D矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49597810/

相关文章:

rotation - THREE.js:计算对象上的点的世界空间位置

javascript - 三.js |动态生成贝塞尔曲线

javascript - 如何删除 HTML 5 Canvas 中的形状?

ios - 如何将 3D 模型导入 iOS 游戏

c - 如何在 OpenGL 中创建便宜的阴影?

java - 没有 OpenGL、DirectX、XNA 等的 3D 图形理论和代码

javascript - 如何在 THREE.js 中的粒子系统中绕其轴旋转每个粒子?

javascript - 如果数组长度大于 1 则运行代码

javascript - == null 和 === null 有什么区别?

javascript - 如何在使用 javascript/jquery 单击 "delete icon"时删除表中的行?