When I Move mouse over an object it flies. How to make that object came off the circle? Radius is 100, I added a circle to the mouse.
Here is my code:
function onDocumentMouseMove(event){
fly.style.left = (event.clientX - maxR) + 'px';
fly.style.top = (event.clientY - maxR) + 'px';
event.preventDefault();
mouse.x = (( event.clientX / renderer.domElement.width ) * 2 - 1);
mouse.y = - ( event.clientY / renderer.domElement.height ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( scene.children );
if ( intersects.length > 0 ) {
new TWEEN.Tween( intersects[ 0 ].object.position ).to( {
x: Math.random()*750-375,
y: Math.random()*750-375,
/*z: Math.random() * 400 - 200 */}, 10000 )
.easing( TWEEN.Easing.Elastic.Out).start()
}
}
Related
I am trying to detect the mesh that was clicked on using an orthographic camera.
It works great for objects that are near the center of the viewport. But when objects are near the edges of the viewport, intersection is no longer detected.
renderer.domElement.addEventListener('pointerdown', (event) => {
let raycaster = new THREE.Raycaster();
let mouse = new THREE.Vector2();
mouse.x = ( event.clientX / sizes.width ) * 2 - 1;
mouse.y = - ( event.clientY / sizes.height ) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(objectsList, false);
console.log("Intersects:", intersects);
}
Update 1: My camera is rotated to an isometric-like view; might it have to do with that?
var camera = new THREE.OrthographicCamera(
sizes.width / -2,
sizes.width / 2,
sizes.height / 2,
sizes.height / -2,
-100,
100
);
camera.position.set(16, 0, -16);
camera.rotation.order = 'YXZ';
camera.rotation.y = -30 * THREE.MathUtils.DEG2RAD;
camera.rotation.x = -30 * THREE.MathUtils.DEG2RAD;
camera.zoom = 82;
camera.updateProjectionMatrix();
Update 2: I have noticed that when I change the y coordinate of camera.position to something greater, e.g. 8, it works as expected. Why is that?
I'm trying to convert Mouse position to world coordinates in Three via Aframe
Using something like
let mouse = new three.Vector2()
let camera = document.querySelector('#camera')
let rect = document.querySelector('#sceneContainer').getBoundingClientRect()
mouse.x = ( (event.clientX - rect.left) / rect.width ) * 2 - 1
mouse.y = - ( (event.clientY - rect.top) / rect.height ) * 2 + 1
let vector = new three.Vector3( mouse.x, mouse.y, -1 ).unproject( camera )
However it doesn't seem to be able to handle the camera, I get
TypeError: Cannot read property 'elements' of undefined
From Matrix4.getInverse
9550 |
9551 | // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
9552 | var te = this.elements,
> 9553 | me = m.elements,
9554 |
9555 | n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],
9556 | n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],
I presume it's not reading the camera properly, any ideas on how to get the three camera out of the aframe camera if that's the problem?
Using Piotr's info about accessing the camera and fixing up the 'three' to 'THREE' seems to work:
https://glitch.com/edit/#!/aframe-mouse-to-world
AFRAME.registerComponent('mouse-to-world', {
init: function () {
document.addEventListener('click', (e) => {
let mouse = new THREE.Vector2()
let camera = AFRAME.scenes[0].camera
let rect = document.querySelector('body').getBoundingClientRect()
mouse.x = ( (e.clientX - rect.left) / rect.width ) * 2 - 1
mouse.y = - ( (e.clientY - rect.top) / rect.height ) * 2 + 1
let vector = new THREE.Vector3( mouse.x, mouse.y, -1 ).unproject( camera )
console.log(vector)
})
}
});
I have a sphere and I need to convert mouse click to latitude and longitude
Everything works fine as long as the sphere having no rotation, but if it have any rotation - I get wrong results
Here is my code:
var mouse = new THREE.Vector2();
mouse.x = (event.pageX / window.innerWidth) * 2 - 1;
mouse.y = -(event.pageY / window.innerHeight) * 2 + 1;
var raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObject( EarthSphere );
if (intersects.length!=1) return;
var pointOnSphere = new THREE.Vector3();
pointOnSphere.x = intersects[0].point.x;
pointOnSphere.y = intersects[0].point.y;
pointOnSphere.z = intersects[0].point.z;
var EarthRadius = 20;
var lat = 90 - (Math.acos(pointOnSphere.y / EarthRadius)) * 180 / Math.PI;
var lon = ((90 + (Math.atan2(pointOnSphere.x , pointOnSphere.z)) * 180 / Math.PI) % 360) - 180;
I am gussing that I need to manipulate somehow the pointOnSphere based on EarthSphere, any ideas?
EDITED
earth.updateMatrixWorld(true);
pointOnSphere = earth.localToWorld( pointOnSphere.clone() );
I thought something like the following would work:
EarthSphere.updateMatrixWorld(true);
pointOnSphere = EarthSphere.localToWorld( pointOnSphere.clone() );
But it does not work ..
I think, you have to use .worldToLocal() rather than .localToWorld(). Thus you'll get a point in local coordinates of your sphere.
The documetation says about .worldToLocal():
Updates the vector from world space to local space.
Which means that the vector, passed into this function, will be updated. No creation of a new THREE.Vector3().
Both of those functions just update an existing vector which you pass to them.
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects;
var pointOfIntersection = new THREE.Vector3();
var localPoint = new THREE.Vector3();
var spherical = new THREE.Spherical();
var lat, lon;
window.addEventListener("mousedown", sphereClick, false);
function sphereClick(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
intersects = raycaster.intersectObjects([sphere]);
if (intersects.length == 0) return;
pointOfIntersection = intersects[0].point;
sphere.worldToLocal(localPoint.copy(pointOfIntersection)); // that's how it works with translation from the world coordinate system to the local one
createPoint(localPoint);
}
function createPoint(position) {
var point = new THREE.Mesh(new THREE.SphereGeometry(0.0625, 16, 12), new THREE.MeshBasicMaterial({
color: 0x777777 + Math.random() * 0x777777
}));
point.position.copy(position);
sphere.add(point);
var color = point.material.color.getHexString();
// three.js already has useful object to get polar coordinates from the given vector - 'position', which is in local coordinates already
spherical.setFromVector3(position);
lat = THREE.Math.radToDeg(Math.PI / 2 - spherical.phi);
lon = THREE.Math.radToDeg(spherical.theta);
pointList.innerHTML += "<span style='color:#" + color + "'>lat: " + lat + "; lon: " + lon + "</span><br>";
}
jsfiddle example r87.
i have a canvas element that i rotate with context.rotate();
when i drag around the image in the canvas if i rotated lets say 90 degrees, and i move to the left, the image moves down,
is there a formula in which i can apply a movement of
for example
x+5 y+2 * degrees
and i get the real movement i need to do to move the rotated canvas in the direction i want? I would like to apply it to this function which works but with the undesired efect of moving left and the image moving down `
vm.canvasMouseMove = function (event) {
vm.delta = Date.now();
if (vm.mouseisdown && vm.delta - vm.now > (1000 / 60) && (event.clientX > 0 && event.clientY > 0)) {
vm.now = vm.delta
vm.snapshot.mouse.x -= event.clientX;
vm.snapshot.offsetSlider.value -= vm.snapshot.mouse.x;
if (vm.snapshot.offsetSlider.value < -160) {
vm.snapshot.offsetSlider.value = -160
}
else if (vm.snapshot.offsetSlider.value > 160) {
vm.snapshot.offsetSlider.value = 160
}
vm.snapshot.mouse.y -= event.clientY;
vm.snapshot.verticalOffsetSlider.value += vm.snapshot.mouse.y;
if (vm.snapshot.verticalOffsetSlider.value < -120) {
vm.snapshot.verticalOffsetSlider.value = -120
}
else if (vm.snapshot.verticalOffsetSlider.value > 120) {
vm.snapshot.verticalOffsetSlider.value = 120
}
vm.snapshot.mouse.x = event.clientX;
vm.snapshot.mouse.y = event.clientY;
}
};`
This draws
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(vm.snapshot.rotationSlider.value * Math.PI / 180);
ctx.drawImage(image, vm.snapshot.offsetSlider.value - (canvas.width / 2), (vm.snapshot.verticalOffsetSlider.value * -1) - (canvas.height / 2), vm.scaledImageW * vm.snapshot.zoomSlider.value / 100, vm.scaledImageH * vm.snapshot.zoomSlider.value / 100);
ctx.rotate(-1 * vm.snapshot.rotationSlider.value * Math.PI / 180);
ctx.translate(-canvas.width / 2, -canvas.height / 2);
vm.donePicture = canvas.toDataURL();
This made the trick, passing the offset to the translate method, then draw the image only taking into account the canvas half translation
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate((canvas.width / 2) + (vm.snapshot.offsetSlider.value), (canvas.height / 2) - vm.snapshot.verticalOffsetSlider.value);
ctx.rotate(vm.snapshot.rotationSlider.value * Math.PI / 180);
ctx.drawImage(vm.canvasImage, 0 - (canvas.width/2), 0 - (canvas.height/2), vm.scaledImageW * vm.snapshot.zoomSlider.value / 100, vm.scaledImageH * vm.snapshot.zoomSlider.value / 100);
ctx.restore();
Three.js r70 source code
setFromCamera: function ( coords, camera ) {
// camera is assumed _not_ to be a child of a transformed object
if ( camera instanceof THREE.PerspectiveCamera ) {
this.ray.origin.copy( camera.position );
this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( camera.position ).normalize();
}
this line,set the mouse's position and z's default value 0.5.
this.ray.direction.set( coords.x, coords.y, 0.5 )
most example code about raycasting like
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
I wonder how it works ,what does the ( event.clientX / window.innerWidth ) * 2 - 1 mean, and why set the z 0.5?
event its every time your mouse click client.x is the mouse position on x-axiz width.innerheight is how height your screen size is when you have a 2d mouse you have to separate it so when you are on left half of screen you go left and right you go right so you divide the screen height in 2 and compare where the 1 on the end mouse the mouse registration around so if you want to offset the crosshairs you can do to
function onDocumentMouseMove(e) {
e.preventDefault();
var fleece = window.document.body.scrollHeight;
var fleeceb = window.document.body.scrollWidth;
mouse.x = (e.clientX / fleeceb) * 2 - 1;
mouse.y = - (e.clientY / fleece) * 2 + 1;
}