diff --git a/src/shared/lib/helpers/createCharacterComparison/createCharacterComparison.svelte.ts b/src/shared/lib/helpers/createCharacterComparison/createCharacterComparison.svelte.ts index fc88cbc..2867dda 100644 --- a/src/shared/lib/helpers/createCharacterComparison/createCharacterComparison.svelte.ts +++ b/src/shared/lib/helpers/createCharacterComparison/createCharacterComparison.svelte.ts @@ -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 }; diff --git a/src/widgets/ComparisonSlider/ui/ComparisonSlider/ComparisonSlider.svelte b/src/widgets/ComparisonSlider/ui/ComparisonSlider/ComparisonSlider.svelte index a9c00b8..5a8c088 100644 --- a/src/widgets/ComparisonSlider/ui/ComparisonSlider/ComparisonSlider.svelte +++ b/src/widgets/ComparisonSlider/ui/ComparisonSlider/ComparisonSlider.svelte @@ -68,6 +68,8 @@ const charComparison = createCharacterComparison( () => sizeControl.value, ); +let lineElements = $state<(HTMLElement | undefined)[]>([]); + /** Physics-based spring for smooth handle movement */ const sliderSpring = new Spring(50, { stiffness: 0.2, // Balanced for responsiveness @@ -138,12 +140,18 @@ $effect(() => { {#snippet renderLine(line: LineData, lineIndex: number)}
{#each line.text.split('') as char, charIndex} - {@const { proximity, isPast } = charComparison.getCharState(lineIndex, charIndex, line, sliderPos)} + {@const { proximity, isPast } = charComparison.getCharState( + charIndex, + sliderPos, + lineElements[lineIndex], + container, + ),} -
-
-