I have two scenes, scene1 and scene2. For dragging I have tried with three js draggable but it did not allow me to drag objects outside of scene1. I need to drag objects from scene1 and drop it to scene2.I have attached an image of it. Thanks in Advance.
[The image with two scenes]
"Draggable" in three.js simple means you can transform an object within the space where it exists. To move it between scenes, you would need to view it more as a transaction.
Mousedown on the item you want to drag
Save a reference to the object (var tempobj = selectedObj;)
Start dragging
Detect when your cursor exits the first viewport
Remove the object from scene 1 (scene1.remove(tempobj);)
Detect when your cursor enters the second viewport
Add the object to scene 2 (scene2.add(tempobj);)
Continue dragging the object until you mouse-up
Related
I have a simple Threejs code where I am testing the click event with Raycaster. I used the BOX geometry to create three cubes. Using CSS2DRenderer.js, I have added a label above one of the cubes. I want to click on the label to bring up a popup with some information. I see that the cubes are detected when I click, but the label is not. Is the raycaster limited to meshes? If that's the case, how do I detect my label on click? You can find the click event code below:
window.addEventListener('click', event => {
raycaster.setFromCamera(clickMouse, camera);
const found = raycaster.intersectObjects(scene.children);
console.log(found);
});
You can only use Raycaster for detecting 3D objects like meshes, point clouds or lines. For labels rendered via CSS2DRenderer, you can just add a pointerdown event listener to the respective label DOM element.
I am designing a UI that allows the user to drag and drop a box (red outline) to determine its position on the screen (black box).
UI
It can also be moved by changing the inputs on the right.
I am using Angulars cdkDrag for the drag and drop functionality which applies a
transform: translate3d(x, y, z)
to move the box (i use the event listener to update the input values on the right).
When a user input is applied I update this property depending on the input.
Unfortunately, when the box is dragged again, Angular reapplies a translate3d creating two properties that are conflicting with each other, creating terrible UX when dragging after user input.
two transform properties
Is there a way around this?
Turns out, there is a way to set the drag position of the element manually. Which in my case I can do on user input.
[cdkDragFreeDragPosition]="dragPosition"
dragPosition = {x: 50, y: 100};
This maintains a single translate property and creates a smooth UX
I have an object created from importing an .obj
I want to clone this object and give it it's own coordinates.
To be more precise, I have a wall, for which I attach another object (a window) as a child. It all works fine when dragging the window along the wall. Now, when I want to clone the wall and rotate it 180 degrees, dragging the child along it's parent goes exactly the opposite way from the mouse movement.
I would like to reuse the same obj wall for all sides of my building.
You are describing two problems.
One is how to clone an object and give it a different position:
var wallCopy = wall.clone();
scene.add(wallCopy);
wallCopy.position.set( 10,20,30 );
The other question is moving an object in Object space instead of World space.
I.e. if you change the position.x of an object (the window) that is a child of a rotated object, the object will move relative to its rotated parent.
If you are building some sort of editor, you can use SceneUtils to make this easier...
https://threejs.org/docs/#examples/utils/SceneUtils
At the start of your edit, you would detach the window and attach it to the scene, using SceneUtils.detach... then apply your edit movement, and when the movement is done, attach it back to the wall using SceneUtils.attach.
SceneUtils takes care of keeping the visual transform consistent between the detach and attach operations between different places on the scene hierarchy.
edit: So a way to handle the case you describe in comments, without doing anything fiddly, is to just use more intermediate nodes. You can always set up your scaling and stuff on the child nodes, (You can always update thier matrices and then set their matrixAutoUpdate = false; if you're paranoid about the performance impact.}
Here's what I mean:
{"root", scale:1, children:[anchor1, anchor2]}
{"anchor1" scale:1, children:[wall]} {"anchor2" scale:1, children:[wall2]}
Then you can just manipulate the anchors or root to move things around, and the scaling of "wall" will be isolated to its own little sub tree.
I have a web page that is based on the following ThreeJS sample:
http://threejs.org/examples/#css3d_molecules
I create new nodes (atoms) dynamically by attaching them to existing nodes (atoms). After creating it and adding it to the scene, I want to bring the new atom/child element to the forefront using the minimum number of rotate, pan, & zoom operations needed to do so. However, although I know how to do each of those operations, I don't know how to calculate the optimal sequence based on the current position/quaternion of the node (atom) where I created it in the scene, and its new position which will be (0, 0, ). I will be animating the change from the old place in the scene to the new so I don't want to just change the new element's position/quaternion to the new value via an assignment. I want animate the change over time, performing a slice of each operation (pan/zoom/rotate) each animation frame.
Are there any ThreeJS methods to help me do this?
See how to: get the global/world position of a child object to get world position of any mesh in your hierarchy. Then have your camera.lookAt() to that location.
Is it possible to move any elements added using
chart.renderer
as we update the range or the navigator handles?
There is a square in this fiddle. Can we shift its position as we update the navigator?
Or can you point me to the function in the source code that can help?
Thanks
Update: i want to draw trendlines/ fibonnacci retracements etc. based on user events. Currently, i draw & drag the lines using chart.renderer until the mouseup event, calculate the x,y values of the end points, delete the rendered lines & then add new series which visually imitate those rendered lines. This is surely not the best solution. The issue is how to remember the position of the user selection & show/scale the same only when those lines are in the visible range.
So i am wondering if we could directly use some internal "scaling" function that calculates the visible points of the series based on the current extremes.
Rendered object's position is basend on pixels, so when you use navigator, pixels "are the same" so object stay in the same position. But you can catch navigator "sliding" by setExtremes and aftersetExtremes functions and then move element by translate().
Simple example of using translate():
obj.translate(120,20);
http://jsfiddle.net/Ne7QV/1/
Only what you need is common both elements, according to your expectations.