In which you spin the scene around by pretending there's a trackball sitting on top of the viewport.
When the user lets go of the mouse, you could stop whatever transformation is being applied immediately. Or you could let it keep going. If there's a lot of inertia at the up event, then maybe the user wants the object to spin or fly for a while longer.
The mouse event properties movementX
and movementY
provide coarse measures of inertia by telling you how many pixels the mouse has moved between events. As a vector, these numbers describe the direction of the movement and the magnitude.
You want to consider these numbers at the up event, but they are only nonzero during move events. That means you need to record them in the move listener and act on them in the up listener:
let inertia = null;
function onMouseDrag(event) {
if (isButtonDown) {
inertia = [event.movementX, event.movementY];
}
}
function onMouseUp(event) {
if (isButtonDown) {
// if inertia is big
// set strength proportional to inertia
// fire off an animation
}
}
In the case of a trackball, the animation might keep spinning the object. The more inertia the mouse has, the faster it should spin. You could let the spin continue indefinitely, or you could make its speed decay over time with code like this:
function animate() {
// update transformation state according to strength
render();
strength *= decayRate;
if (strength > 0.001) {
requestAnimationFrame(animate);
}
}
This renderer uses a trackball with inertia and a decay rate of approximately 0.9:
Try spinning the torus with differing levels of oomph as you release the mouse.