2016-08-18 2 views
0

Ich zeichne eine Box mit der Maus, wo ich raycast verwende, um die Position der Maus in der Szene zu erhalten. Wenn also das mouseDown-Ereignis ausgelöst wird, nehme ich den Startpunkt, und während mouseMove stattfindet, nehme ich den Endpunkt und zeichne ein Kästchen zwischen den beiden Punkten. Ich begann auf einer leeren Seite, nur um die Zeichnung auszuprobieren, und als alles gut war, habe ich den Zeichencode auf meine Hauptseite verschoben, die viele Komponenten und natürlich einen Container für die Zeichenfläche enthält. Nachdem ich meinen Code auf die Hauptseite verschoben habe, ist ein Problem mit der Mausposition aufgetreten. Die Position der Box wird um die Entfernung des Canvas-Containers von x und y verschoben.Ändern der Mausposition

Die folgende Abbildung veranschaulicht das Problem:

Simplified case of the problem

Die rote Show Markierung, wo ich die Maus, um die Box und die blaue Zeichnung beginnt gedrückt zeigt, wo ich die Maus angehalten, die shiffting hier ist die Y-Achse, weil ich zwei Zeilen von Komponenten oben auf der Seite habe.

Dies ist ein vereinfachter Code:

<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> 

Ich weiß nicht, warum dies geschieht und wie dieses Problem zu lösen.

Danke

Antwort

1

Wenn Sie genau auf Ihr Bild betrachten, werden Sie feststellen, dass die Klicks von einem Y-Wert (in Bezug auf Bildschirmpixel) versetzt sind. Wenn Sie noch genauer hinschauen, sieht es so aus, als wäre die Verschiebung die gleiche wie Ihre Kopfzeile (Kopfzeile des XYZ/Auswahlmodus). Dies liegt daran, dass Sie ein div erstellt haben und seine Größe auf die innere Breite/innere Höhe festgelegt haben. Es erstellt ein Div mit der angegebenen Größe, aber niedriger. Ihre Mausklicks wären also korrekt, wenn Sie diese Kopfzeile nicht hätten (da threejs sie auf dem Bildschirm mit 40px registriert, wird sie auf 40px übersetzt) ​​

WIE FIX: Als ich dieses Problem hatte Ich habe JQuery verwendet, um die TOP zu erhalten, und habe diesen Offset zu meinem Raycaster-Mausklick hinzugefügt. In Ihrem Fall kann man renderer.domElement.top bekommen (ich bin nicht sicher, console.log (renderer.domElement, um zu sehen, ob es gibt einen oberen Standortwert) und subtrahiere es mit der Maus Y (subtrahiere, da du das Rechteck verschieben willst)

+0

Danke, ich kannte den Grund des Problems und ich wusste nicht, wie ich mein Bedürfnis ausdrücken sollte. Ich fand die Lösung hier: https://stackoverflow.com/questions/29518886/moved-coordinat es-of-the-scene-wenn-dom-element-with-renderer-ist-nicht-am-oberen wo Sie den Anfang des Containers mit erhalten: container.getBoundingClientRect(). top Danke^_ ^ –

Verwandte Themen