diff --git a/src/mol-canvas3d/canvas3d.ts b/src/mol-canvas3d/canvas3d.ts index 156219dead421927c46c3de787dc0a2740423850..5169f3f294581527fd08c255efce39de6923e58b 100644 --- a/src/mol-canvas3d/canvas3d.ts +++ b/src/mol-canvas3d/canvas3d.ts @@ -192,7 +192,7 @@ namespace Canvas3D { if (isIdentifying || isUpdating) return false let didRender = false - controls.update() + controls.update(currentTime); // TODO: is this a good fix? Also, setClipping does not work if the user has manually set a clipping plane. if (!camera.transition.inTransition) setClipping(); const cameraChanged = camera.updateMatrices(); @@ -230,6 +230,7 @@ namespace Canvas3D { } let forceNextDraw = false; + let currentTime = 0; function draw(force?: boolean) { if (render('draw', !!force || forceNextDraw)) { @@ -246,8 +247,8 @@ namespace Canvas3D { } function animate() { - const t = now(); - camera.transition.tick(t); + currentTime = now(); + camera.transition.tick(currentTime); draw(false) window.requestAnimationFrame(animate) } diff --git a/src/mol-canvas3d/controls/trackball.ts b/src/mol-canvas3d/controls/trackball.ts index 63234d324de095b95e09cd11ad07bd13354d4d95..b2e01c66d3206c082d0cbdd20b0da58f10eaf874 100644 --- a/src/mol-canvas3d/controls/trackball.ts +++ b/src/mol-canvas3d/controls/trackball.ts @@ -39,12 +39,12 @@ interface TrackballControls { readonly props: Readonly<TrackballControlsProps> setProps: (props: Partial<TrackballControlsProps>) => void - update: () => void + update: (t: number) => void reset: () => void dispose: () => void } namespace TrackballControls { - export function create (input: InputObserver, object: Object3D & { target: Vec3 }, props: Partial<TrackballControlsProps> = {}): TrackballControls { + export function create(input: InputObserver, object: Object3D & { target: Vec3 }, props: Partial<TrackballControlsProps> = {}): TrackballControls { const p = { ...PD.getDefaultValues(TrackballControlsParams), ...props } const viewport: Viewport = { x: 0, y: 0, width: 0, height: 0 } @@ -131,7 +131,7 @@ namespace TrackballControls { Vec3.normalize(rotAxis, Vec3.cross(rotAxis, rotMoveDir, _eye)) angle *= p.rotateSpeed; - Quat.setAxisAngle(rotQuat, rotAxis, angle ) + Quat.setAxisAngle(rotQuat, rotAxis, angle) Vec3.transformQuat(_eye, _eye, rotQuat) Vec3.transformQuat(object.up, object.up, rotQuat) @@ -150,7 +150,7 @@ namespace TrackballControls { Vec2.copy(_movePrev, _moveCurr) } - function zoomCamera () { + function zoomCamera() { const factor = 1.0 + (_zoomEnd[1] - _zoomStart[1]) * p.zoomSpeed if (factor !== 1.0 && factor > 0.0) { Vec3.scale(_eye, _eye, factor) @@ -207,9 +207,11 @@ namespace TrackballControls { } } + let lastUpdated = -1; /** Update the object's position, direction and up vectors */ - function update() { - if (p.spin) spin(); + function update(t: number) { + if (lastUpdated === t) return; + if (p.spin) spin(t - lastUpdated); Vec3.sub(_eye, object.position, target) @@ -226,6 +228,8 @@ namespace TrackballControls { if (Vec3.squaredDistance(lastPosition, object.position) > EPSILON.Value) { Vec3.copy(lastPosition, object.position) } + + lastUpdated = t; } /** Reset object's vectors and the target vector to their initial values */ @@ -299,15 +303,14 @@ namespace TrackballControls { } const _spinSpeed = Vec2.create(0.005, 0); - function spin() { - _spinSpeed[0] = (p.spinSpeed || 0) / 1000; + function spin(deltaT: number) { + const frameSpeed = (p.spinSpeed || 0) / 1000; + _spinSpeed[0] = 60 * Math.min(Math.abs(deltaT), 1000 / 8) / 1000 * frameSpeed; if (!_isInteracting) Vec2.add(_moveCurr, _movePrev, _spinSpeed); } // force an update at start - update(); - - if (props.spin) { spin(); } + update(0); return { viewport,