1
1
import React , { useState , useEffect , useRef } from "react" ;
2
- import { Box , Input , VStack , Text } from "@chakra-ui/react" ;
2
+ import { Box , VStack , Text } from "@chakra-ui/react" ;
3
3
import { motion } from "framer-motion" ;
4
4
5
5
const MotionBox = motion ( Box as any ) ;
@@ -8,39 +8,11 @@ const numBoxes = 100;
8
8
const indentations = Array . from ( { length : numBoxes } , ( _ , i ) => i * 100 ) ;
9
9
10
10
const ChakraBoxes = ( ) => {
11
- const [ highlightedIndex , setHighlightedIndex ] = useState ( null ) ; // Index of the box in the center
11
+ const [ highlightedIndex , setHighlightedIndex ] = useState ( 0 ) ; // Directly calculate index
12
12
const [ offset , setOffset ] = useState ( 0 ) ;
13
13
const [ scrollPercentage , setScrollPercentage ] = useState ( 0 ) ; // State for scroll percentage
14
- const boxRefs = useRef ( [ ] ) ; // Ref array to hold references to each box
15
14
const canvasRef = useRef ( ) ;
16
15
17
- const calculateClosestBoxToCenter = ( ) => {
18
- if ( ! canvasRef . current ) {
19
- return ;
20
- }
21
- const viewportHeight = window . innerHeight ;
22
- const viewportCenter = viewportHeight / 2 ;
23
-
24
- let closestIndex = null ;
25
- let closestDistance = Infinity ;
26
-
27
- boxRefs . current . forEach ( ( box , index ) => {
28
- if ( ! box ) {
29
- return ;
30
- }
31
- const boxRect = box . getBoundingClientRect ( ) ;
32
- const boxCenter = boxRect . top + boxRect . height / 2 ;
33
- const distanceToCenter = Math . abs ( boxCenter - viewportCenter ) ;
34
- if ( distanceToCenter < closestDistance ) {
35
- closestDistance = distanceToCenter ;
36
- closestIndex = index ;
37
- }
38
- } ) ;
39
-
40
- setHighlightedIndex ( closestIndex ) ;
41
- setOffset ( indentations [ closestIndex ] ) ;
42
- } ;
43
-
44
16
const calculateScrollPercentage = ( ) => {
45
17
const scrollTop = window . scrollY ; // Distance from the top
46
18
const docHeight = document . documentElement . scrollHeight ; // Full document height
@@ -50,26 +22,28 @@ const ChakraBoxes = () => {
50
22
const scrolled = ( scrollTop / totalScrollable ) * 100 ;
51
23
52
24
setScrollPercentage ( scrolled ) ;
25
+
26
+ // Calculate the index based on the scroll percentage
27
+ const calculatedIndex = Math . round ( ( scrolled / 100 ) * ( numBoxes - 1 ) ) ;
28
+ setHighlightedIndex ( calculatedIndex ) ;
29
+ setOffset ( indentations [ calculatedIndex ] ) ;
53
30
} ;
54
31
55
32
useEffect ( ( ) => {
56
33
// Call the function initially and on scroll
57
- calculateClosestBoxToCenter ( ) ;
58
34
calculateScrollPercentage ( ) ;
59
35
60
- window . addEventListener ( 'scroll' , calculateClosestBoxToCenter ) ;
61
36
window . addEventListener ( 'scroll' , calculateScrollPercentage ) ;
62
37
63
38
// Cleanup the scroll event listener on component unmount
64
39
return ( ) => {
65
- window . removeEventListener ( 'scroll' , calculateClosestBoxToCenter ) ;
66
40
window . removeEventListener ( 'scroll' , calculateScrollPercentage ) ;
67
41
} ;
68
42
} , [ numBoxes ] ) ;
69
43
70
44
return (
71
45
< Box overflowX = { 'hidden' } >
72
- < Text position = "fixed" top = { 0 } left = { 0 } p = { 4 } fontSize = "lg" bg = "white " zIndex = { 1 } >
46
+ < Text position = "fixed" top = { 0 } right = { 0 } p = { 4 } fontSize = "lg" zIndex = { 1 } >
73
47
Scroll Percentage: { scrollPercentage . toFixed ( 2 ) } %
74
48
</ Text >
75
49
< MotionBox
@@ -86,7 +60,6 @@ const ChakraBoxes = () => {
86
60
{ Array . from ( { length : numBoxes } ) . map ( ( _ , index ) => (
87
61
< Box
88
62
key = { index }
89
- ref = { ( el ) => ( boxRefs . current [ index ] = el ) } // Assign the ref to the box
90
63
width = "200px"
91
64
height = "50px"
92
65
bg = { highlightedIndex === index ? "yellow.300" : "teal.300" } // Highlight the box closest to center
0 commit comments