fix(createCharacterComparison): improve characters measurment for better magnifying presicion

This commit is contained in:
Ilia Mashkov
2026-01-30 00:54:40 +03:00
parent 1a2c44fb97
commit fbaf596fef
2 changed files with 39 additions and 31 deletions

View File

@@ -204,37 +204,41 @@ export function createCharacterComparison<
/**
* precise calculation of character state based on global slider position.
*
* @param lineIndex - Index of the line
* @param charIndex - Index of the character in the line
* @param lineData - The line data object
* @param sliderPos - Current slider position (0-100)
* @param lineElement - The line element
* @param container - The container element
* @returns Object containing proximity (0-1) and isPast (boolean)
*/
function getCharState(
lineIndex: number,
charIndex: number,
lineData: LineData,
sliderPos: number,
lineElement?: HTMLElement,
container?: HTMLElement,
) {
if (!containerWidth) return { proximity: 0, isPast: false };
if (!containerWidth || !container) {
return {
proximity: 0,
isPast: false,
};
}
const charElement = lineElement?.children[charIndex] as HTMLElement;
// Calculate the pixel position of the character relative to the CONTAINER
// 1. Find the left edge of the centered line
const lineStartOffset = (containerWidth - lineData.width) / 2;
if (!charElement) {
return { proximity: 0, isPast: false };
}
// 2. Find the character's center relative to the line
const charRelativePercent = (charIndex + 0.5) / lineData.text.length;
const charPixelPos = lineStartOffset + (charRelativePercent * lineData.width);
// Get the actual bounding box of the character
const charRect = charElement.getBoundingClientRect();
const containerRect = container.getBoundingClientRect();
// 3. Convert back to global percentage (0-100)
const charGlobalPercent = (charPixelPos / containerWidth) * 100;
// Calculate character center relative to container
const charCenter = charRect.left + (charRect.width / 2) - containerRect.left;
const charGlobalPercent = (charCenter / containerWidth) * 100;
const distance = Math.abs(sliderPos - charGlobalPercent);
// Proximity range: +/- 15% around the slider
const range = 15;
const range = 5;
const proximity = Math.max(0, 1 - distance / range);
const isPast = sliderPos > charGlobalPercent;
return { proximity, isPast };