private updateTargetPosition()

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 });
  }