I have a scene with Camera and OrbitControls in position. And I'm letting users to move around the scene and change camera view and OrbitControls position.
Now I have a reset button which will reset the scene view to its default position.
We can do this using TweenJS. Just include its JS library on your web page.
Save your Camera position and OrbitControls target position when its ready to display on web like this:
const default_camera_position = { ...camera.position };
const default_controls_target = { ...controls.target };
Now in clickListener of button use this code.
createjs.Ticker.setFPS(60);
createjs.Tween.get(camera.position)
.to(default_camera_position, 500);
createjs.Tween.get(controls.target)
.to(default_controls_target, 500);
And That's all.
Related
I have an cube set as child to the camera, so that when you move the camera (using OrbitControls) the cube is in a fixed position (moves with the camera)
When dragging the cube using DragControls I want to transfer the cube from the camera into the scene, so that instead of moving with the camera, the cube is a normal object with no parent and just sits in the 3D scene.
The problem is that in DragControls when you mousedown the _offset of the cube gets set before the dragstart event: https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/DragControls.js#L159
So when I listen to the dragstart and then move the cube from camera to scene parent, then set the new position and updateMatrixWorld() it has no affect seeing as DragControls is remembering the old position/matrix when the click first occurred.
Here is my dragstart listener:
dragControls.addEventListener( 'dragstart', function (event) {
orbitControls.enabled = false;
if(event.object.parent.type === "OrthographicCamera") {
scene.attach(event.object);
event.object.position.set(5, 0, 0);
event.object.updateMatrixWorld();
}
} );
The current code works when you initial click the cube, but as soon as you move it (and the drag occurs the initial _offset causes the cube to ping back into an odd position.
Is there any way I can do this or would I need to modifier the DragControls module itself?
I'm doing a camera animation in Three.js with GSAP, I'm trying to animate it horizontally like the panning in a film.
Anyone knows if is possible to animate the pan in orbit controls or something similar?
If you are using OrbitControls and you want to manually animate a pan, you have to animate the camera position and OrbitControls.target which represents the focus point of the controls. The relevant code for the controls is:
gsap.to( controls.target, {
duration: 2,
x: 10,
onUpdate: function() {
controls.update();
}
} );
Full demo: https://jsfiddle.net/kerpm61q/
I built my scene in three js and everything was working properly when I rendered the scene on the . But now I need the scene to be on a div, 70% of the viewport to be specific, the other 30% being a left side panel with some info. I replaced every window.height and width for the width and height of the div itself, but now the events are all broken. I tried bubbling and capturing but the problem seems to be related with the camera or something in three js, because when I hover on a corner something is happening...but nothing is happening when i hover/click on the 3d globe. I google everything and didn't find an answer or people with similar issues..I'm hopeless, help? Thanks.
Edit: here's a fiddle: https://jsfiddle.net/2L686cnw/
Did you update all for the renderer relevant variables on window resize?
Just like this:
var onWindowResize = function(){
renderWidth = element.offsetWidth;
renderHeight = element.offsetHeight;
camera.aspect = renderWidth/renderHeight;
camera.updateProjectionMatrix();
renderer.setSize(renderWidth, renderHeight);
};
$(window).on('resize', function() {
onWindowResize();
});
The issue sounds like that you get wrong viewport coordinates for your click position. Most three.js examples add event listeners to window or document object and using event.clientX (and clientY) to transform the mouse screen coordinates to viewport coordinates to use it for raycasting.
Having the 3D scene within a separate div covering only part of the page, it should be a bit different:
function onClick(event) {
var mouse = new THREE.Vector2();
mouse.x = (event.offsetX / panelWidth) * 2 - 1;
mouse.y = - (event.offsetY / panelHeight) * 2 + 1;
// do raycasting
}
canvas.addEventListener('click', onClick);
I am trying to use dat.gui with a very simple three.js (r73) scene but am running into an issue with rotate and pan not working after adding "renderer.domElement" to the trackballControls initialization. Zoom works as expected.
Without renderer.domElement, I get a working rotate, zoom, pan functionality but the dat.gui interface sliders "latch" when clicked, which is just annoying and not functional. The issue as described here: Issue while using dat.GUI in a three.js example.
Looked over more info here but didn't see a great resolution: https://github.com/mrdoob/three.js/issues/828
Also found this issue. Defining the container element aka renderer.domElement doesn't work. I am unable to click within outside of the canvas area without the scene rotating.
Allow mouse control of three.js scene only when mouse is over canvas
Has anyone run into the same thing recently? If so, what workarounds are possible? Any help is appreciated.
-
The code is setup as follows:
// setup scene
// setup camera
// setup renderer
// ..
var trackballControls = new THREE.TrackballControls(camera, renderer.domElement);
trackballControls.rotateSpeed = 3.0;
trackballControls.zoomSpeed = 1.0;
trackballControls.panSpeed = 1.0;
// ..
// render loop
var clock = new THREE.Clock();
function render() {
stats.update();
var delta = clock.getDelta();
trackballControls.update(delta);
requestAnimationFrame( render );
renderer.render( scene, camera );
}
I debugged the issue with the help of this post: Three.js Restrict the mouse movement to Scene only.
Apparently, if you append the renderer.domElement child after initializing the trackballControls, it doesn't know anything about the renderer.domElement object. This also does something strange to dat.gui as described previously.
Basically, make sure this line:
document.getElementById("WebGL-output").appendChild(renderer.domElement);
appears before this line:
var trackballControls = new THREE.TrackballControls(camera, renderer.domElement);
Make sure the renderer DOM element is added to the html before it is being used as a reference.
document.body.appendChild(renderer.domElement);
Using three.js is it possible to rotate a panned object about its center. I have created a jsfiddle, http://jsfiddle.net/yKt6h/4/
When I checked the Auto rotate mode in the control panel, i am able to rotate the panned cube about its center. Is it possible to have a similar effect when i try to rotate the cube with mouse movement.
If it is possible please provide me sample code
I am getting an errors in the console when viewing your jsFiddle THREE is not defined However, what you are asking is not difficult. The trackball camera is designed to do exactly what you want it to. If you are rendering your object at the origin you just need to initialize the trackball controls. I created a simple moon demo that uses TrackballControls. You don't need to do any modifcation in TrackballControls.js.
In the above demo I call a function to initialize the trackball controls the function is defined in my ThreeUtil.js file as:
function initTrackball(camera, rotate, zoom, pan, damping) {
var controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = rotate || 1.0;
controls.zoomSpeed = zoom || 1.2;
controls.panSpeed = pan || 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = damping || 0.3;
return controls;
}
If you don't want the user to be able to pan or zoom, only to be able to rotate around your object, then simply set controls.noZoom = true and controls.noPan = true in the function above.
Since my moon object is at the origin of my scene all I have to do is set the camera some distance away from the origin. We will put it on the positive z axis so it is already looking at our object at the origin. Then we call the above function to set up the controls. I pass in a custom rotation speed:
controls = initTrackball(camera, 0.8);
Then in each frame all you have to do is call the update function in your anim loop:
controls.update(camera);