Three.js rotate camera to specific position - css

I have an sphere with divs using CSS3DRenderer. When I click to one of the divs I'd like to position/rotate the camera so the element displays in the center of the screen.
I've tried several examples and I've read other answers but still I cant get it to work.
At the moment it moves the camera but the sphere gets repositioned in different places
What I'm trying to do is the following:
Gets the HTML element's class. Then loop through an array of THREE.CSS3DObject to get its position, then use that to position the camera.
function moveCamera(element) {
for ( var i = 0; i < objects.length; i ++ ) {
var object = objects[ i ];
if(object.element.className == element.className) {
position = object.position;
rotation = object.rotation;
found = true;
break;
}
}
if (found) {
camera.rotation = rotation;
render();
found = false;
} }
What I'm I doing wrong?
Here's the example http://jsfiddle.net/37R22/1/
Thanks

You were close. You just have to move the camera to the right place.
camera.rotation.copy( rotation );
camera.position.copy( position ).multiplyScalar( 4 );
Updated fiddles: http://jsfiddle.net/37R22/2/ or http://jsfiddle.net/37R22/3/
Be careful about going behind-the-back of TrackballControls and modifying the camera properties yourself. This appears to work, however.
three.js r.65

Related

Three.js - how to make objects with different positions look at Orthographic camera using vectors?

Three.js 76
I start to use Orthographic camera instead Perspective - has some troubles.
I use stemkoski's shader-glow for point animation in scene: he created some sphere and then use shader for it transparancy, i just add animation to it.
function animatePoints() {
var alphas;
var count;
var time;
let j = 0;
while ( animatedPoints[j] ) {
let threeGlow = animatedPoints[j];
let finishAnimation = threeGlow.meta.state.finishAnimation;
let itFinished = 0;
let pointGlowMat = threeGlow.material;
let pointGlowGeom = threeGlow.geometry;
// ########## make glow look at camera
pointGlowMat.uniforms.viewVector.value = new THREE.Vector3().subVectors( threeGlow.position, camera.position);
alphas = pointGlowGeom.attributes.alpha;
count = alphas.count;
time = 0.001* Date.now();
if ( finishAnimation ) {
....
} else {
....
}
alphas.needsUpdate = true;
j++;
}
}
Main goal - to make glow look at camera. When camera was perspective i use solution with subtracts two vectors - camera position and glow position, so it look like glow looking at camera.
pointGlowMat.uniforms.viewVector.value = new THREE.Vector3().subVectors( camera.position, threeGlow.position );
But now, when i use Orthographic camera this solution doesn't work correctly.
The problem is that now the glow should look not at camera position point, it should look at plane of the camera.
I make some pic scheme for that situation:look it, it very useful
So for each new glow (it's positions of course different) i must get new red vector, to make each glow look at orto cam.
Any ideas?
What you need to do to get the red vector in your image, is project vector sub on the vector representing the direction in which the camera is looking.
I think this is what you need:
pointGlowMat.uniforms.viewVector.value = new THREE.Vector3()
.subVectors( camera.position, threeGlow.position )
.projectOnVector( camera.getWorldDirection() );
One way to make an object "look at" an orthographic camera by using this pattern:
object.quaternion.copy( camera.quaternion );
The object's view direction will be perpendicular to the camera's projection plane.
This approach is appropriate if neither the object nor the camera have a rotated parent.
three.js r.84

Rotate css3 bug

I'm making a 3d cube based on http://www.paulrhayes.com/experiments/cube-3d/
but mine react on mouse event and touch event on mobile.
I introduce RotateZ to evitate the strange behaviour of the original Hayes cube.
But when if i try to go left -> down and left again it bug.
-webkit-transform:rotateX(-90deg) rotateY(-90deg) rotateZ(0deg);
RotateX and Z make move cube on the same axis I don't know why.
Does it a bug or there is a solution ?
here's is a detailled jsfiddle of my problem :
http://jsfiddle.net/uq2cr/6/
Thank's for your answers !
Problem
This is because when you move the mouse up/down, whilst moving left/right and clicking it will reside to the up/down action.
Current Strucutre
I benchmarked the update of x co-ords.
For both left and right directions, x 0, doesn't seem relative.
The xAngle, yAngle, zAngle increment, but do not reset to 0.
Suggestion
I suggest making some changes to the structure of cubePointerMove(). Make each direction their own stack. That way, there will be no forthcoming problems with the 4 directions.
The way it's set out now, is with duplicate up/down actions in the left/right blocks.
Current
// Left
if( xMove < 0) {
// Up
if( yMove < 0 ) {
if(xMove < yMove){
}
}
// Down
else {
}
}
// Right
else
{
}
Revised
// Up
if( yMove < 0 ) {
}
// Down
else {
}
// Left
if( xMove < 0) {
}
// Right
else {
}

Image Rotate 3D in Flex, but display another image on back of this image?

i want to rotate 3D an Image called img1 in Flex. I want to rotate it around y axis 180 degree. I can do this by using 3D effect already built in Flex but i want to do a bit more different.
I want during rotating, there's another image called img2 appear on back of img1 (in default case, the image appear on the back is img1) and when rotating finish, the image will be img2.
How can i do this ?
Thank you.
If you need no perspective effect, it's quite easy to do. A rough implementation (not tested!):
// Event.ENTER_FRAME event listener
void on_enter_frame(event:Event):void
{
// m_angle is a member of the class/flex component where on_enter_frame is declared
// ANGLE_DELTA is just a constant
m_angle += ANGLE_DELTA;
// Angle clamping to the range [0, PI * 2)
m_angle %= Math.PI * 2;
if (m_angle < 0)
m_angle += Math.PI * 2;
// If we currently look at the front side...
if (m_angle < Math.PI)
{
img1.visible = true;
img2.visible = false;
img1.scaleX = Math.cos(m_angle);
}
else
{
img1.visible = false;
img2.visible = true;
// If you omit negation, the back-side image will be mirrored
img2.scaleX = -Math.cos(m_angle);
}
}
So every frame we increase the rotation angle, clamp it to the range [0, PI * 2). Then depending on the value of the rotation angle, we hide/show the pair of your images, and then perform x-scaling of the visible image.
Thank you, now i found a solution. Please check it here, it's very easy to do.
http://forums.adobe.com/thread/921258

flex: Drag and drop- object centering

In a drag+drop situation using Flex, I am trying to get the object center aligned to the point of drop- somehow, irrespective of the adjustments to height and width, it is always positioning drop point to left top.
here is the code..
imageX = SkinnableContainer(event.currentTarget).mouseX;
imageY = SkinnableContainer(event.currentTarget).mouseY;
// Error checks if imageX/imageY dont satisfy certain conditions- move to a default position
// img.width and img.height are both defined and traced to be 10- idea to center image to drop point
Image(event.dragInitiator).x = imageX-(img.width)/2;
Image(event.dragInitiator).y = imageY-(img.height)/2
The last 2 lines don't seem to have any effect. Any ideas why-must be something straightforward, that I am missing...
You can use the following snippet:
private function on_drag_start(event:MouseEvent):void
{
var drag_source:DragSource = new DragSource();
var drag_initiator:UIComponent = event.currentTarget as UIComponent;
var thumbnail:Image = new Image();
// Thumbnail initialization code goes here
var offset:Point = this.localToGlobal(new Point(0, 0));
offset.x -= event.stageX;
offset.y -= event.stageY;
DragManager.doDrag(drag_initiator, drag_source, event, thumbnail, offset.x + thumbnail.width / 2, offset.y + thumbnail.height / 2, 1.0);
}
Here is one important detail. The snippet uses stage coordinate system.
If you use event.localX and event.localY, this approach will fail in some cases. For example, you click-and-drag a movie clip. If you use localX and localY instead of stage coordinates, localX and localY will define coordinates in currently clicked part of the movie clip, not in the whole movie clip.
Use the xOffset and yOffset properties in the doDrag method of DragManager.
Look here for an example.

How do I allow a user to smoothly resize elements in Flex 3

I have a Flex 3 app that has elements that a user can add to the main canvas then resize and reposition.
There are 3 key functions I am using for the resize which are as follows:
When the resize begins:
private function startResize(event:MouseEvent):void
{
RESIZE_START_MOUSE_X = event.localX;
RESIZE_START_MOUSE_Y = event.localY;
RESIZE_START_WIDTH = this.width;
RESIZE_START_HEIGHT = this.height;
RESIZE_START_X = this.x;
RESIZE_START_Y = this.y;
RESIZE_BOUND = calculateResizeBound(event);
addEventListener(MouseEvent.MOUSE_MOVE, resizeMouseHandler);
isResizing = true;
}
When the resize is complete:
private function endResize():void
{
RESIZE_START_MOUSE_X = -1;
RESIZE_START_MOUSE_Y = -1;
RESIZE_START_WIDTH = this.width;
RESIZE_START_HEIGHT = this.height;
RESIZE_START_X = -1;
RESIZE_START_Y = -1;
RESIZE_BOUND = '';
removeEventListener(MouseEvent.MOUSE_MOVE, resizeMouseHandler);
isResizing = false;
}
Whilst the user is resizing:
private function resizeMouseHandler(event:MouseEvent):void
{
var deltaX:Number = event.localX - RESIZE_START_MOUSE_X;
var deltaY:Number = event.localY - RESIZE_START_MOUSE_Y;
if (RESIZE_BOUND.indexOf('T') > -1)
//We are fixing the top so move the bottom edge
{
this.height = RESIZE_START_HEIGHT + deltaY;
}
if (RESIZE_BOUND.indexOf('B') > -1)
//We are fixing the bottom so move the top edge
{
this.y = RESIZE_START_Y + deltaY;
this.height = RESIZE_START_HEIGHT - deltaY;
}
if (RESIZE_BOUND.indexOf('L') > -1)
//We are fixing the left so move the right edge
{
this.width = RESIZE_START_WIDTH + deltaX;
}
if (RESIZE_BOUND.indexOf('R') > -1)
//We are fixing the right so move the left edge
{
this.x = RESIZE_START_X + deltaX;
this.width = RESIZE_START_WIDTH - deltaX;
}
}
There is another function referenced in these called calculateResizeBound(). What this does is return a string indicating which edge / corner should remain fixed during the resize. Eg 'TL' means that the top left corner should stay fixed, 'BR' means bottom right, 'L' means just the left edge etc etc
When the resize starts from the 'normal' position, ie the top left corner stays fixed, everything works great. Similarly with the left or top edges fixed. However for the bottom and right cases, I need to reposition the element at the same time as resizing it since all the co-ordinates are calculated from the top left.
The problem that I have is that when it does this, the resize is not smooth, it keeps jumping up and down slightly as you resize it. Not only that but when you resize from the 'normal' edges the cursor position remains fixed relative to the fixed edge / corner however from one of the other edges, you can see it start to drift away from the edge / corner as you resize.
With this kind of thing, it is easy to get the + / - of the different bits of the calculation muddled but since the resize is working in the correct direction each time, I assume I have these correct.
So presumably the problem is coming from the simultaneous moving and resizing but I can't find a work-around for it. Any thoughts / suggestions would be much appreciated
Doug McCune has an awesome Resize wrapper that you can use to resize elements. Then you just need to add a mover on it. See the blog post for code/sample: http://dougmccune.com/blog/2007/08/17/my-360flex-slides-and-code/

Resources