Three.js使用鼠标

时间:2018-04-01 11:59:49

标签: 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>

谢谢!

1 个答案:

答案 0 :(得分:1)

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

目前所有这些编码仍然很新,但是我和你的JFiddle搞混了,发现:

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

这里是要检查的JFiddle,希望它有所帮助!您可以随时更换相机并再次将controls.enabled = false设置为true。

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