in client/src/components/translation-selector/word-scroll-list.ts [336:373]
private updateTargetPosition() {
if (!this.scrollContent || this.selectedWordIndex < 0) {
return;
}
const scrollContainer = this.hostElement.nativeElement as HTMLElement;
const scrollContent = this.scrollContent.nativeElement;
const items = scrollContent.getElementsByTagName('li');
if (!items) {
return;
}
const wordIndex = Math.min(this.selectedWordIndex, items.length - 1);
if (wordIndex < 0) {
return;
}
const containerBounds = scrollContainer.getBoundingClientRect();
const centerX = containerBounds.left + containerBounds.width * 0.5;
const currentItem = items[wordIndex];
const currentItemBounds = currentItem.getBoundingClientRect();
const currentItemCenterX = currentItemBounds.left + currentItemBounds.width * 0.5;
const dx = centerX - currentItemCenterX;
let maxSnapDx = currentItemBounds.width * 0.5; // max distance before snapping to next element
let adjacentItem = null;
if (dx < 0 && wordIndex > 0) {
adjacentItem = items[wordIndex - 1];
} else if (dx > 0 && wordIndex < items.length - 1) {
adjacentItem = items[wordIndex + 1];
}
if (adjacentItem) {
// has adjacent item - adjust max snap distance to point between the items
const otherItemBounds = adjacentItem.getBoundingClientRect();
const otherItemCenterX = otherItemBounds.left + otherItemBounds.width * 0.5;
maxSnapDx = Math.abs(centerX - (centerX + otherItemCenterX) * 0.5) + this.config.snapStickyDistance;
}
const currentItemCenterY = currentItemBounds.top + currentItemBounds.height * 0.5;
const targetX = currentItemCenterX - currentItemBounds.width * 0.5 *
Math.max(-1, Math.min(1, this.config.targetPositionRatio * dx / maxSnapDx));
this.targetPositionChanged.emit({ x: targetX, y: currentItemCenterY });
}