Update Three.js Raycaster After CSS Tranformation
1) Please include the full code of your fiddle. When (not if) your fiddle goes away, so does the context of your question, and this answer.
2) You're attaching the mouse events to the document, not to the part that's moving. Use this instead:
canvas.addEventListener('mousemove', onDocumentMouseMove, false);
canvas.addEventListener('mousemove', onHover, false);
3) clientX
/clientY
don't behave how you're expecting them to. Use offsetX
/offsetY
to get the coordinates relative to the canvas (provided you followed step 2). (Don't worry that MDN says it's experimental, it works just fine in browsers that support WebGL.)
mouse.x = (event.offsetX / SCREEN_WIDTH) * 2 - 1;
mouse.y = - (event.offsetY / SCREEN_HEIGHT) * 2 + 1;
Changing Raycaster position dynamically
try to change a code as follows:
function onDocumentMouseDown( event ) {
event.preventDefault();
var x = event.offsetX == undefined ? event.layerX : event.offsetX;
var y = event.offsetY == undefined ? event.layerY : event.offsetY;
var vector = new THREE.Vector3();
vector.set( ( x / renderer.domElement.width ) * 2 - 1, - ( y / renderer.domElement.height ) * 2 + 1, 0.5 );
vector.unproject( camera );
raycaster.ray.set( camera.position, vector.sub( camera.position ).normalize() );
...
Three.js cube face rotation vector in relation to camera
Disclaimer: I know nothing about three.js
. I've just done a bit of OpenGL.
Your euler angles are coming from a model-view-projected origin (lines 74-80). I can't see the logic behind this.
If your div is on the sphere surface, then it should be oriented by the normal of the sphere at the location of the div. Fortunately, you already have these angles. They are named rotation
.
If you replace the euler angles in lines 82-84 with the rotation angles used to position the div, then in my browser the div appears edge on when it is at the edge of the circle, and face on when it is at the centre. It kind of looks like it is moving in a circle, edge on to the screen. Is this the effect you want?
My modification to the linked code:
82 var rotX = (rotation.x * (180/ Math.PI));
83 var rotY = (rotation.y * (180/ Math.PI));
84 var rotZ = 0;
EDIT
Ah, ok. The rotation
variable is just that of the camera. It governs the tangent at the equator. You also need to modify the orientation to account for latitude.
Make rotY
equal to negative your latitude. Then make sure that this rotation happens before the equatorial rotation. Rotations are not commutative.
In summary, changes from the code at https://jsfiddle.net/ao5wdm04/1/ are as follows:
27 var lat = 45 * Math.PI / 180;
...
82 var rotX = (rotation.x * (180/ Math.PI));
83 var rotY = - 45;
...
88 document.getElementById('face').style.webkitTransform = 'translate3d(' + x + 'px,' + y + 'px,0px) rotateY('+rotX+'deg) rotateX('+rotY+'deg)';
I don't know how the latitude should propagate between the init
and render
functions. As I said, I'm not familiar with the language.
Three.js reverse raycasting
Basing on the link provided by @prisoner849, I've implemented the following solution:
a) on mouseup event I set a new tooltip 3D origin point (only if there was no significant delta in mouse position, to discern between clicking and dragging the camera)
b) every frame, the following function is fired, which converts the 3D coords to 2D and calculates the position of the tooltip:
function setTooltipOrigin( camera, renderer, tooltip, lastClickPoint ) {
var canvas = renderer.domElement,
point = new THREE.Vector3();
point.x = lastClickPoint.x,
point.y = lastClickPoint.y,
point.z = lastClickPoint.z,
point.project( camera );
point.x = Math.round(( 0.5 + point.x / 2 ) * ( canvas.width / window.devicePixelRatio ));
point.y = Math.round(( 0.5 - point.y / 2 ) * ( canvas.height / window.devicePixelRatio ));
point.x -= 14; //small adjustment to the position, so the line points to the click point
point.y -= (tooltip.scrollHeight * 0.7); //same for y
tooltip.style.transform = 'translate(' + point.x + 'px, ' + point.y + 'px)';
}
Three.js - Mouse hover effect doesn't restore previous color
Few problems in your code:
You seem to use INTERSECTED.currentRGB to restore previous color. But you never save the previous color into it (maybe the object.currentHex should have done it?)
THREE.Color.setRGB takes 3 arguments: (r, g, b). You code wouldn't work even if you saved [r,g,b] to currentRGB, which you can't since there is no THREE.Color.getRGB. In this case, it's better if you use Hex. (THREE.Color.getHex and THREE.Color.setHex)
Here is fixed part of the code, lines changed by me are commented
if (intersects.length > 0) {
if (intersects[0].object != INTERSECTED) {
if (INTERSECTED) {
// Use hex rather than RGB (setRGB uses 3 arguments, hex one)
INTERSECTED.face.color.setHex(INTERSECTED.currentHex);
}
INTERSECTED = intersects[0];
// Save actual color so we can restore it later
INTERSECTED.currentHex = INTERSECTED.face.color.getHex();
INTERSECTED.face.color.setHex(0x777777);
INTERSECTED.object.geometry.colorsNeedUpdate = true;
}
} else {
if (INTERSECTED) {
// Use hex rather than RGB (setRGB uses 3 arguments, hex one)
INTERSECTED.face.color.setHex( INTERSECTED.currentHex );
}
INTERSECTED = null;
}
You can see it working here: https://jsfiddle.net/ord2rjw5/3/
Related Topics
How to Apply Title Case in Input Box Through CSS
How to Convert Rgba to Hex Color Code Using JavaScript
Google Maps API - Strange Map "Offset" Behaviour
Changing CSS Variables via Js in Polymer
Focusing on Nested Contenteditable Element
Force Address Bar to Show in Mobile Chrome App
How to Open Bootstrap Modal in Ajax Success
How to Put Logical Operators in Document.Queryselectorall? If So, How
How to Execute Jquery Code Only Once
Jquery + Animate.CSS Animation Only Working Once, Animation Not Resetting
How to Zoom in an Image and Center It
How to Make the Facebook Like Button's Width Automatically Resize
Resize Bar for Sidenav in Angular Material Design
Alter CSS Class Attributes with JavaScript
Fast Image Loading Methods, Low to High Res with Multiple Backgrounds - JavaScript Solution
How to Get Horizontal Scrollbars at Top and Bottom of a Div