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/
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 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.
Im started to develop my project, where fabric js canvas used as a texture on my 3d object, loaded by three js library. Unfortunately I don`t have a full working snippet now, maybe you can show me solution or right way to solve my problem
The problem is the controls drawing on the lower canvas and its transfer on my 3d object, i want to render it on the upper canvas. Is it possible?
The second problem is the brush at first rendered on the upper canvas and after event 'mouse: up' its rendered on the lower canvas. How to render brush line by event 'mouse; move' on the lower canvas at the moment drawing?
p.s. sorry for my english, its really hard to say for me. Hope, you understand my mind
Here you can see my first issue:
https://1drv.ms/u/s!AqtIFlFVWz4MhNtBc3g1DQElfA6_7Q?e=y7ly37
Thank you for you response!
Woow! this is a very good code example! And it works pretty smooth too. It shows the problem a lot better.
I found a solution for the first problem (that is kind of a three.js problem) in the fabric js demo: http://fabricjs.com/controls-customization.
I'm not good with fabric so there might be a more elegant solution than this. You can hide the controls, render to three.js and then show them again. You also have to force the canvas to render, it won't work otherwise.
function animate() {
requestAnimationFrame(animate);
//find the selected object on the fabric canvas
let selected = canvas.getActiveObject();
//hide controles and render on the fabric canvas;
if (selected){
selected.hasControls = false;
selected.hasBorders = false;
canvas.renderAll();
}
//update texture and render
texture.needsUpdate = true;
renderer.render(scene, camera);
//show controls and render on the fabric canvas
if (selected){
selected.hasControls = true;
selected.hasBorders = true;
canvas.renderAll();
}
}
The second problem is a bit harder to understand. I'm not sure what the 'lower canvas' is and if that is a part of fabric that i don't understand. This is the closest i can get. I almost made it work on the three.js renderer. If i understood the idea correctly...
You need to have a variable to know if you are pressing the mouse or not. Only if you are pressing the mouse AND moving the mouse, it draws a circle.
To do the same with fabric 'mouse:move' you will at least have to disable that selectionbox on the fabric canvas. But i do not know how that works in fabric.
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var mouseDown = false;///////////////////////////// global boolean
var onClickPosition = new THREE.Vector2();
container.addEventListener("mousedown", function(){
mouseDown = true;
canvas.selection = false;
onMouseEvt(); //draw circle
}, false);
container.addEventListener("mouseup", function(){
mouseDown = false
canvas.selection = true;
}, false);
container.addEventListener("mousemove", function(e){
if (mouseDown){
onMouseEvt(); //draw circle
}
}, false);
///This code does not work, it goes into selection mode..
canvas.on('mouse:down', function(){
mouseDown = true;
addCircle();
}, false);
canvas.on('mouse:up', function(){
mouseDown = false;
}, false);
canvas.on('mouse:move', function(){
if ( mouseDown ){
addCircle();
}
}, false);
This is a hard question and it's not really a three.js thing, it has more to do with fabric.js and drawing to a canvas. The three.js part of texturing the object seems to work fine.
If I understand correctly you have an overlaying canvas on which you want to render the controls, but they are also rendered to the actual texture canvas? If in case you are actually rendering the controls on the texture; don't do that :p
It should be possible to make it work the way you want to. It would be helpful to post a small code example on https://jsfiddle.net/ or something.
I have two scenes: one with the plane and another with the box. I want to blur the box.
Rendering loop:
renderer.clear();
renderer.render( scene, camera );
renderer.clearDepth();
composer.render();
In this case only blurred box appeared, but plane is missing.
Here is a fiddle: http://jsfiddle.net/bq5m1u6v/36/
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);