2016-11-12 79 views
1

我是一個完整的Three.js新手和新的JavaScript一般。我試圖測試一些鼠標事件交互。我嘗試了很多東西,但無法進行任何交互,所以我只是從下面的頁面抓取了一些Javascript,調整它以使其成爲'MouseDown',而不是'MouseOver'事件,並且通常簡化它以便在那裏沒有旋轉等: -Three.js鼠標事件與光線投射和相交測試

https://threejs.org/examples/#webgl_interactive_cubes

但是,隨後出現的頁面有我不明白的問題。無論何時刷新頁面,立方體都會自動變爲紅色,但只有在點擊它時纔會發生。如果我減小多維數據集的大小,則可以解決問題。

我做了一個console.log(INTERSECTIONS),發現刷新時的值是'5',但每次我點擊後立方體的值都是'1'。因爲我沒有實際點擊過任何東西,我會期望刷新時的值爲'0'?知道了這一點,我可以很容易「如果」那個去類似的語句添加附加:

if (intersects.length > 4) 
     { 
    INTERSECTED.material.emissive.setHex(0x111111); 
     } 

而且這個有點可以解決問題,但我仍然不知道爲什麼這個問題擺在首位出現?

如何進一步簡化此代碼以便我可以從中創建一個基本模板,以便創建將來的鼠標單擊事件類型頁面?例如,如果我希望立方體在點擊時旋轉,那麼目前這似乎不起作用?

的代碼如下:

<script src="js/three.js"></script> 
<script> 

    var camera, scene, raycaster, renderer; 
    var mouse = new THREE.Vector2(), INTERSECTED; 
    var radius = 100; 
    init(); 
    animate(); 

    function init() { 

    container = document.createElement('div'); 
    document.body.appendChild(container); 

    var info = document.createElement('div'); 
    info.style.position = 'absolute'; 
    info.style.top = '10px'; 
    info.style.width = '100%'; 
    info.style.textAlign = 'center'; 


    camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 1, 10000); 
    scene = new THREE.Scene(); 

    scene.add(new THREE.AmbientLight(0xffffff, 0.2)); 

    var light = new THREE.DirectionalLight(0xffffff, 2); 

    light.position.set(30, 10, 1).normalize(); 
    scene.add(light); 

    var cubeGeometry = new THREE.BoxGeometry(20,20,20); 
    var cubeMaterial = new THREE.MeshLambertMaterial({color: 0x999999, wireframe: false}); 
    var object = new THREE.Mesh(cubeGeometry, cubeMaterial); 

     object.position.x = 0; 
     object.position.y = 0; 
     object.position.z = 0; 

     scene.add(object); 



    raycaster = new THREE.Raycaster(); 
    renderer = new THREE.WebGLRenderer(); 
    renderer.setClearColor(0xf0f0f0); 
    renderer.setPixelRatio(window.devicePixelRatio); 
    renderer.setSize(window.innerWidth, window.innerHeight); 
    renderer.sortObjects = false; 
    container.appendChild(renderer.domElement); 


    document.addEventListener('mousedown', onDocumentMouseDown, false); 
    window.addEventListener('resize', onWindowResize, false); 

    } 
    function onWindowResize() { 
    camera.aspect = window.innerWidth/window.innerHeight; 
    camera.updateProjectionMatrix(); 
    renderer.setSize(window.innerWidth, window.innerHeight); 
    } 
    function onDocumentMouseDown(event) { 
    event.preventDefault(); 
    mouse.x = (event.clientX/window.innerWidth) * 2 - 1; 
    mouse.y = - (event.clientY/window.innerHeight) * 2 + 1; 
    } 

    function animate() { 
    requestAnimationFrame(animate); 
    render(); 
    } 

    camera.position.x = -30; 
    camera.position.y = 30; 
    camera.position.z = 30; 
    camera.lookAt(scene.position); 
    camera.updateMatrixWorld(); 

    function render() 
    { 
    // find intersections 
    raycaster.setFromCamera(mouse, camera); 
    var intersects = raycaster.intersectObjects(scene.children); 
    if (intersects.length > 0) { 
     if (INTERSECTED != intersects[ 0 ].object) { 
     if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex); 
     INTERSECTED = intersects[ 0 ].object; 
     INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex(); 
     INTERSECTED.material.emissive.setHex(0xff0000); 
     console.log(intersects.length); 
     } 
    } else { 
     if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex); 
     INTERSECTED = null; 
    } 
    renderer.render(scene, camera); 

    } 
</script> 

回答

1

在聲明var mouse = new THREE.Vector2(),這意味着你創建具有值{x:0, y:0}一個矢量(這意味着鼠標定位在屏幕的中心)。然後,您用init()初始化場景,在那裏設置立方體,然後使用animate()開始渲染。

現在,您將鼠標放在scneen的中心,並在每個渲染(在render()函數中)檢查交集。這意味着,當你在屏幕中間你的mouse你會有積極的交集。當您從多維數據集中單擊某處時,您將設置鼠標的一個新點,因此相交結果爲負數。

如果您想與鼠標點擊進行交互,那麼最好將檢查交叉點的代碼塊從render()移動到onDocumentMouseDown(event)

// find intersections 
raycaster.setFromCamera(mouse, camera); 
var intersects = raycaster.intersectObjects(scene.children); 
if (intersects.length > 0) { 
    if (INTERSECTED != intersects[ 0 ].object) { 
    if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex); 
    INTERSECTED = intersects[ 0 ].object; 
    INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex(); 
    INTERSECTED.material.emissive.setHex(0xff0000); 
    console.log(intersects.length); 
    } 
} else { 
    if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex); 
    INTERSECTED = null; 
} 

因此,只有當您單擊場景時纔會檢查相交。

jsfiddle示例

+0

你好,謝謝!這非常有幫助。只是想知道如何做一個布爾點擊交互:如果多維數據集是灰色的,點擊會將其變成紅色;如果它是紅色的,那麼點擊會將其變回灰色? – user62109

+0

@ user62109您可以檢查與光線相交的物體的顏色。訪問並設置它:'INTERSECTED.material.color.setHex(0xff0000)'。 – prisoner849