【问题标题】:three js drag and drop Uncaught TypeError三个js拖拽Uncaught TypeError
【发布时间】:2016-09-04 08:20:56
【问题描述】:

我一直在尝试实现此处的拖放功能...

http://www.smartjava.org/tjscb/07-animations-physics/07.08-drag-n-drop-object-around-scene.html

每当我稍微定制它并在我的项目中使用它时,我都会得到以下结果..

"Uncaught TypeError: Cannot read property 'point' of undefined"

每当我尝试拖动立方体时。旋转没有发生,所以它必须认识到我正在尝试拖动一个对象并且它与这行代码有关..

"selectedObject.position.copy(intersects[0].point.sub(offset))"

我假设因为我对所有这些都是新手,所以我把上面链接中的所有代码复制到一个新页面中(所以应该是相同的)并运行它,我得到了同样的东西(其他一切都很好)

我可能遗漏了一些非常愚蠢的东西,我已经搜索过这个并查看了有关如何实现此目标的其他示例,但是由于我正在阅读一本书,该书解释了我认为我会坚持的所有内容,以及它找出它为什么不起作用的一个很好的学习经验。如果有人能指出我正确的方向,我将不胜感激

<!DOCTYPE html>
<html>
 <head> 
  <title>07.08 - Drag and drop object around scene</title> 
    <script type="text/javascript" src="js/threejs/three.min.js"></script> 
    <script type="text/javascript" src ="js/threejs/OrbitControls.js"></script>
  <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style> 
  <script>

    // global variables
    var renderer;
    var scene;
    var camera;
    var cube;


    var control;
    var orbit;

    // used for drag and drop
    var plane;
    var selectedObject;
    var offset = new THREE.Vector3();
    var objects = [];

    // based on http://mrdoob.github.io/three.js/examples/webgl_interactive_draggablecubes.html
    function init() {

        // create a scene, that will hold all our elements such as objects, cameras and lights.
        scene = new THREE.Scene();

        // create a camera, which defines where we're looking at.
        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

        // create a render, sets the background color and the size
        renderer = new THREE.WebGLRenderer();
        renderer.setClearColor(0xffffff, 1.0);
        renderer.setSize(window.innerWidth, window.innerHeight);

        plane = new THREE.Mesh(new THREE.PlaneGeometry(2000, 2000, 18, 18), new THREE.MeshBasicMaterial({
            color: 0x00ff00,
            opacity: 0.25,
            transparent: true
        }));
        plane.visible = false;
        scene.add(plane);

        var dirLight = new THREE.DirectionalLight();
        dirLight.position.set(25, 23, 15);
        scene.add(dirLight);

        var dirLight2 = new THREE.DirectionalLight();
        dirLight2.position.set(-25, 23, 15);
        scene.add(dirLight2);

        for (var i = 0; i < 200; i++) {
            // create a cube and add to scene
            var cubeGeometry = new THREE.BoxGeometry(2, 2, 2);
            var cubeMaterial = new THREE.MeshLambertMaterial({color: Math.random() * 0xffffff});
            cubeMaterial.transparent = true;
            cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
            objects.push(cube);

            cube.scale.x = Math.random() + 0.5 * 2;
            cube.scale.y = Math.random() + 0.5 * 2;
            cube.scale.z = Math.random() + 0.5 * 2;

            cube.position.x = Math.random() * 50 - 25;
            cube.position.y = Math.random() * 50 - 25;
            cube.position.z = Math.random() * 50 - 25;

            cube.rotation.x = Math.random() * Math.PI * 2;
            cube.rotation.y = Math.random() * Math.PI * 2;
            cube.rotation.z = Math.random() * Math.PI * 2;
            scene.add(cube);
        }

        // position and point the camera to the center of the scene
        camera.position.x = 35;
        camera.position.y = 35;
        camera.position.z = 53;
        camera.lookAt(scene.position);

        // add some controls so we can rotate
        orbit = new THREE.OrbitControls(camera);

        // add the output of the renderer to the html element
        document.body.appendChild(renderer.domElement);

        // call the render function
        render();
    }


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

    document.onmousemove = function (event) {
        // make sure we don't access anything else
        event.preventDefault();

        // get the mouse positions
        var mouse_x = ( event.clientX / window.innerWidth ) * 2 - 1;
        var mouse_y = -( event.clientY / window.innerHeight ) * 2 + 1;

        // get the 3D position and create a raycaster
        var vector = new THREE.Vector3(mouse_x, mouse_y, 0.5);
        vector.unproject(camera);
        var raycaster = new THREE.Raycaster(camera.position,
                vector.sub(camera.position).normalize());

        // first check if we've already selected an object by clicking
        if (selectedObject) {
            // check the position where the plane is intersected
            var intersects = raycaster.intersectObject(plane);
            // reposition the selectedobject based on the intersection with the plane
            selectedObject.position.copy(intersects[0].point.sub(offset));
        } else {
            // if we haven't selected an object, we check if we might need
            // to reposition our plane. We need to do this here, since
            // we need to have this position before the onmousedown
            // to calculate the offset.
            var intersects = raycaster.intersectObjects(objects);

            if (intersects.length > 0) {
                // now reposition the plane to the selected objects position
                plane.position.copy(intersects[0].object.position);
                // and align with the camera.
                plane.lookAt(camera.position);

            }
        }
    };

    document.onmousedown = function (event) {

        // get the mouse positions
        var mouse_x = ( event.clientX / window.innerWidth ) * 2 - 1;
        var mouse_y = -( event.clientY / window.innerHeight ) * 2 + 1;

        // use the projector to check for intersections. First thing to do is unproject
        // the vector.
        var vector = new THREE.Vector3(mouse_x, mouse_y, 0.5);
        // we do this by using the unproject function which converts the 2D mouse
        // position to a 3D vector.
        vector.unproject(camera);

        // now we cast a ray using this vector and see what is hit.
        var raycaster = new THREE.Raycaster(camera.position,
                vector.sub(camera.position).normalize());

        // intersects contains an array of objects that might have been hit
        var intersects = raycaster.intersectObjects(objects);

        if (intersects.length > 0) {
            orbit.enabled = false;

            // the first one is the object we'll be moving around
            selectedObject = intersects[0].object;

            // and calculate the offset
            var intersects = raycaster.intersectObject(plane);
            offset.copy(intersects[0].point).sub(plane.position);
        }
    };

    document.onmouseup = function (event) {
        orbit.enabled = true;
        selectedObject = null;
    }

    // calls the init function when the window is done loading.
    window.onload = init;

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

【问题讨论】:

    标签: three.js


    【解决方案1】:

    “未捕获的类型错误:无法读取未定义的属性‘点’” "selectedObject.position.copy(intersects[0].point.sub(offset))"

    这意味着,intersects[0] 未定义,这意味着数组 intersects 没有元素(长度 = 0)。您正在使用raycasting,但它无法正常工作。

    您应该分享您修改后的代码,以便我们检查您的raycasting 中的问题所在。

    更新:我认为你的three.js 版本大于71,而本网站的three.js 版本是71 或更低。在第 72 版中,raycaster 中有更新 -

    忽略不可见的对象。 (@mrdoob,@tschw)

    那么,问题就在这里——

    var intersects = raycaster.intersectObject(plane);
    

    由于飞机是不可见的,intersectObject 正在返回空数组。

    解决方法:我找到了解决方法。您可以删除以下行 -

    plane.visible = false;
    

    您可以通过以下方式隐藏飞机的material -

    plane = new THREE.Mesh(new THREE.PlaneGeometry(2000, 2000, 18, 18), new THREE.MeshBasicMaterial({
                    color: 0xffff00,
                    opacity: 0.50,
                    transparent: true,
                    visible: false
                }));
    

    这样,raycaster 将正常工作,飞机也将不可见。

    【讨论】:

    • 感谢您抽出宝贵时间回复。为了尝试解决问题,我只是尝试使用上述链接中的代码,我已将我所拥有的内容复制到我的原始问题中。任何建议将不胜感激
    • 这太棒了,而且效果很好。感谢您的帮助...我确实查看了更改日志,但没有发现(或者更可能不知道我在寻找什么!)。再次感谢您的帮助
    • Three.js 版本有问题,谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    • 2023-03-17
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多