Skip to content

Commit 54032bd

Browse files
committed
Tween camera when changing targets
1 parent 84e2bb1 commit 54032bd

File tree

1 file changed

+45
-18
lines changed

1 file changed

+45
-18
lines changed

controls.jsx

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,29 @@ import {
44
TOUCH,
55
Vector3,
66
Spherical,
7+
Clock,
78
} from 'three';
89

910

10-
const rotateSpeed = 0.005;
11-
const dollySpeed = 1.0003;
12-
1311
export class OrreryControls extends Controls {
14-
target;
15-
offset;
16-
state;
17-
constructor( object, domElement = null, target ) {
12+
offset = new Spherical( 1, 1, 0 );
13+
rotateSpeed = 0.005;
14+
dollySpeed = 1.0003;
15+
easingSpeed = 0.5;
16+
easingFunction = (t) => {
17+
return 1 - Math.pow(1 - t, 3);
18+
};
19+
// we don't allow panning, so that there's always an object which is the target
20+
mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: null };
21+
touches = { ONE: TOUCH.ROTATE, TWO: null };
22+
constructor( object, domElement = null, target, params = {} ) {
1823
super( object, domElement );
1924

20-
this.target = target;
21-
this.offset = new Spherical( 1, 1, 0 );
22-
// we don't allow panning, so that there's always an object which is the target
23-
this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: null };
24-
this.touches = { ONE: TOUCH.ROTATE, TWO: null };
25+
Object.assign(this, params);
26+
27+
this._target = target;
28+
this._oldPosition = new Vector3();
29+
this._clock = new Clock();
2530

2631
this._onMouseMove = onMouseMove.bind(this);
2732
this._onMouseWheel = onMouseWheel.bind(this);
@@ -54,23 +59,45 @@ export class OrreryControls extends Controls {
5459
this.offset.radius,
5560
this.target.geometry.parameters.radius + this.object.near,
5661
);
57-
let cameraPosition = new Vector3()
62+
63+
// hacky way of getting the camera to point in the right direction
64+
// in theory it should be possible to directly set the camera's rotation to the inverse of
65+
// the offset's orientation, but I couldn't figure out the right conversions
66+
let invLerpFactor = 1 - this.easingFunction(
67+
Math.min( 1, this._clock.getElapsedTime() / this.easingSpeed )
68+
);
69+
let fromPosition = this._oldPosition.clone();
70+
let toPosition = new Vector3()
5871
.setFromSpherical(this.offset)
5972
.add(this.target.position);
60-
this.object.position.copy(cameraPosition);
61-
this.object.lookAt(this.target.position);
73+
let invDeltaPosition = fromPosition.clone().sub(toPosition).multiplyScalar(invLerpFactor);
74+
let tweenPosition = toPosition.clone().add(invDeltaPosition);
75+
let lookPosition = this.target.position.clone().add(invDeltaPosition);
76+
77+
this.object.position.copy(tweenPosition);
78+
this.object.lookAt(lookPosition);
79+
}
80+
81+
set target(target) {
82+
this._oldPosition = this.object.position.clone();
83+
this._target = target;
84+
this._clock.start();
85+
}
86+
87+
get target() {
88+
return this._target;
6289
}
6390
}
6491

6592
function onMouseMove(event) {
6693
if (event.buttons & 1) {
67-
this.offset.phi -= event.movementY * rotateSpeed;
68-
this.offset.theta -= event.movementX * rotateSpeed;
94+
this.offset.phi -= event.movementY * this.rotateSpeed;
95+
this.offset.theta -= event.movementX * this.rotateSpeed;
6996
this.offset.makeSafe();
7097
}
7198
}
7299

73100
function onMouseWheel(event) {
74101
event.preventDefault();
75-
this.offset.radius *= Math.pow(dollySpeed, event.deltaY);
102+
this.offset.radius *= Math.pow(this.dollySpeed, event.deltaY);
76103
}

0 commit comments

Comments
 (0)