2016-08-18 2 views
0

마우스로 상자를 그린다. 여기서 레이크 캐스트를 사용하여 장면에서 마우스의 위치를 ​​얻는다. 그래서 mouseDown 이벤트가 발생하면 나는 시작점을 잡았고 mouseMove가 발생하는 동안 끝점을 가져온 다음 두 점 사이에 상자를 그립니다. 빈 페이지에서 드로잉을 시도하기 시작했습니다. 모든 것이 좋았을 때 드로잉 코드를 많은 구성 요소가 포함 된 메인 페이지로 옮기고 물론 드로잉 캔버스 용 컨테이너로 이동했습니다. 코드를 기본 페이지로 이동 한 후 마우스 위치에 문제가 발생했습니다. 박스 위치는 x와 y에 캔버스 컨테이너의 거리만큼 이동합니다.마우스 위치 변경

다음 이미지 문제 설명 :

Simplified case of the problem

내가 마우스를 중지 된 위치 상자와 파란색을 보여줍니다 그리기 시작하는 마우스를 누르면 빨간색 마크 쇼, 여기에 shiffting가 켜져을 페이지 위쪽에 두 행의 구성 요소가 있기 때문에 Y 축 이런 일이 왜 모르겠어요

<body> 

<div> 
    <button class="btn btn-info" onclick="rotate_x()"><b>X</b></button> 
    <button class="btn btn-info" onclick="rotate_y()"><b>Y</b></button> 
    <button class="btn btn-info" onclick="rotate_z()"><b>Z</b></button> 
    <button class="btn btn-info" onclick="reset_rotation()"><b>Reset</b></button> 
    <input type="checkbox" name="selection" onchange="selection_mode_change()" checked><b>Selection mode</b> 
</div> 


<div> 
    <button class="btn btn-info" onclick="rotate_x()"><b>X</b></button> 
    <button class="btn btn-info" onclick="rotate_y()"><b>Y</b></button> 
    <button class="btn btn-info" onclick="rotate_z()"><b>Z</b></button> 
    <button class="btn btn-info" onclick="reset_rotation()"><b>Reset</b></button> 
    <input type="checkbox" name="selection" onchange="selection_mode_change()" checked><b>Selection mode</b> 
</div> 
<script> 

    var container; 
    var camera, scene, renderer, dirLight; 
    var raycaster; 
    var mouse; 
    var is_mouse_down = false; 
    var area; 
    var start, end; 
    var objects = []; 

    init(); 
    animate(); 

    function init() { 

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

     camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 1, 1000000); 
     camera.position.set(0, 0, 1000); 

     scene = new THREE.Scene();   


     // Box 
     var area_geometry = new THREE.BoxGeometry(1, 1, 1); 
     area = new THREE.Mesh(area_geometry, new THREE.MeshBasicMaterial({ 
      color: 0x00ff00, 
      opacity: 0.2, 
      visible: true 
     })); 
     area.position.x = 0; 
     area.position.y = 0; 
     area.position.z = 0; 
     area.scale.x = 1; 
     area.scale.y = 1; 
     area.scale.z = 1; 

     scene.add(area); 

     // plane for the raycast intersection 

     var geometry = new THREE.BoxGeometry(100, 100, 100); 
     var object = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ 
      color: Math.random() * 0xffffff, 
      opacity: 0.1, 
      visible: false 
     })); 
     object.position.x = 0; 
     object.position.y = 0; 
     object.position.z = -1000; 
     object.scale.x = 100; 
     object.scale.y = 100; 
     object.scale.z = 1; 
     scene.add(object); 
     objects.push(object); 



     raycaster = new THREE.Raycaster(); 
     mouse = new THREE.Vector2(); 


     // Light 
     dirLight = new THREE.DirectionalLight(0xffffff, 1); 
     dirLight.position.set(camera.position.x, camera.position.y, camera.position.z); 
     scene.add(dirLight); 

     renderer = new THREE.CanvasRenderer(); 
     renderer.setClearColor(0xffffff); 
     renderer.setPixelRatio(window.devicePixelRatio); 
     renderer.setSize(window.innerWidth, window.innerHeight); 
     container.appendChild(renderer.domElement); 

     document.addEventListener('mousedown', onDocumentMouseDown, false); 
     document.addEventListener('mouseup', onDocumentMouseUp, false); 
     document.addEventListener('mousemove', onDocumentMouseMove, false); 
     document.addEventListener('touchstart', onDocumentTouchStart, false); 

     window.addEventListener('resize', onWindowResize, false); 

    } 

    function onWindowResize() { 

     camera.aspect = window.innerWidth/window.innerHeight; 
     camera.updateProjectionMatrix(); 

     renderer.setSize(window.innerWidth, window.innerHeight); 

    } 

    function onDocumentTouchStart(event) { 

     event.preventDefault(); 

     event.clientX = event.touches[0].clientX; 
     event.clientY = event.touches[0].clientY; 
     onDocumentMouseDown(event); 

    } 

    function onDocumentMouseDown(event) { 

     event.preventDefault(); 
     start = get_intersection_point(event); 
     is_mouse_down = true; 
    } 

    function onDocumentMouseUp(event) { 

     event.preventDefault(); 
     is_mouse_down = false; 
    } 

    function onDocumentMouseMove(event) { 

     if (is_mouse_down) { 

      end = intersection(event); 
      update_selection_area_view(start, end); 
     } 
    } 

    function animate() { 

     requestAnimationFrame(animate); 

     render(); 
    } 

    function render() { 

     camera.lookAt(scene.position); 

     renderer.render(scene, camera); 

    } 

    function get_intersection_point(event) { 
     mouse.x = (event.clientX/renderer.domElement.clientWidth) * 2 - 1; 
     mouse.y = -(event.clientY/renderer.domElement.clientHeight) * 2 + 1; 

     raycaster.setFromCamera(mouse, camera); 

     var intersects = raycaster.intersectObjects(objects); 

     if (intersects.length > 0) { 

      return intersects[0].point; 

     } 
     return null; 
    } 


    function update_selection_area_view(start, end) { 

     width = Math.abs(start.x - end.x); 
     height = Math.abs(start.y - end.y); 

     center = new THREE.Vector3(-(start.x + end.x)/2, -(start.y + end.y)/2, (start.z + end.z)/2); 

     area.position.x = center.x; 
     area.position.y = center.y; 
     area.position.z = center.z; 
     area.scale.x = width; 
     area.scale.y = height; 
     area.scale.z = 1; 
    } 

</script> 

</body> 

, 어떻게이 문제를 해결하는 방법 :

이 단순화 된 코드입니다. 당신은, 당신은 클릭이 (화면 픽셀의 측면에서) Y 값에 의해 상쇄되는 것을 볼 수 사진을 자세히 보면

답변

1

감사드립니다. 더 가까이서 보면 이동이 머리글 (XYZ/선택 모드 머리글)과 동일하게 나타납니다. 이는 div를 생성하고 크기를 innerWidth/innerHeight로 설정했기 때문입니다. 지정한 크기의 div를 만듭니다. 그러나 아래로 내려갑니다. 마우스가 클릭되지 않았다면 마우스 클릭은 정확합니다 (3j는 40px로 화면에 등록되므로 div에서 40px로 변환됩니다)

설명 : 이 문제가 있었을 때 , 나는 JQuery를 사용하여 TOP를 얻었고, 그 레이아시스 mouseclick에 오프셋을 추가했다. 나는 renderer.domElement.top을 얻을 수 있다고 생각한다. (나는 너무 확신하지 않는다. console.log (renderer.domElement if 상단 위치 값이 있습니다.) Y 마우스로 뺍니다. (사각형을 위로 이동하려고하므로 빼기)

+0

감사합니다. 문제의 원인을 알았고 필요한 것을 표현하는 방법을 알지 못했습니다. 해결책을 찾은 곳 : https://stackoverflow.com/questions/29518886/moved-coordinat 화면 상단에있는 렌더러가 아닌 상단의 컨테이너의 상단을 얻는 곳 : container.getBoundingClientRect(). 위로 감사^_ ^ –