in client/src/components/translation-selector/word-scroll-list.ts [380:423]
private updateSnapPosition(lastProperties: {position: number, velocity: number, time: number}, snapWordIndex: number) {
let velocity = lastProperties.velocity;
if(lastProperties.position < this.minScrollPosition && velocity < 0) {
velocity = 0;
} else if(lastProperties.position > 0 && velocity > 0) {
velocity = 0;
} else if (Math.abs(velocity) > this.config.snapMaxSpeed) {
velocity = Math.sign(velocity) * this.config.snapMaxSpeed;
}
const snapPosition = this.getWordSnapPosition(snapWordIndex);
const t = WordScrollListComponent.getTime();
const dt = t - lastProperties.time;
const snapDx = snapPosition - lastProperties.position;
velocity += snapDx < 0 ? - this.config.snapAcceleration * dt : this.config.snapAcceleration * dt;
let maxSpeed = this.config.snapMaxSpeed;
if (Math.abs(snapDx) <= this.config.snapDecelerationDistance) {
// near snap position - start slowing down
maxSpeed *= Math.abs(snapDx) / this.config.snapDecelerationDistance;
}
if (Math.abs(velocity) > maxSpeed) {
// over max speed
velocity = Math.sign(velocity) * maxSpeed;
}
if (Math.abs(velocity) < this.config.snapMinSpeed) {
// under min speed
velocity = Math.sign(velocity) * this.config.snapMinSpeed;
}
const dx = 0.5 * (velocity + lastProperties.velocity) * dt;
if (Math.sign(dx) === Math.sign(snapDx) && Math.abs(dx) >= Math.abs(snapDx) && Math.abs(dx) < 10) {
// close enough - end snap
this.setScrollPosition(snapPosition);
clearInterval(this.snapInterval);
this.snapInterval = null;
this.selectedWordIndex = this.getWordIndexFromScrollPosition(snapPosition);
} else {
const position = lastProperties.position + dx;
this.setScrollPosition(position);
lastProperties.velocity = velocity;
lastProperties.position = position;
lastProperties.time = t;
this.selectedWordIndex = this.getWordIndexFromScrollPosition(position);
}
this.updateTargetPosition();
}