Skip to content

Commit 12f60de

Browse files
committed
Optimized version of algorithm
1 parent 8b88467 commit 12f60de

File tree

1 file changed

+8
-35
lines changed

1 file changed

+8
-35
lines changed

example/components/chakra-boxes.tsx

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
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";
33
import { motion } from "framer-motion";
44

55
const MotionBox = motion(Box as any);
@@ -8,39 +8,11 @@ const numBoxes = 100;
88
const indentations = Array.from({ length: numBoxes }, (_, i) => i * 100);
99

1010
const ChakraBoxes = () => {
11-
const [highlightedIndex, setHighlightedIndex] = useState(null); // Index of the box in the center
11+
const [highlightedIndex, setHighlightedIndex] = useState(0); // Directly calculate index
1212
const [offset, setOffset] = useState(0);
1313
const [scrollPercentage, setScrollPercentage] = useState(0); // State for scroll percentage
14-
const boxRefs = useRef([]); // Ref array to hold references to each box
1514
const canvasRef = useRef();
1615

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-
4416
const calculateScrollPercentage = () => {
4517
const scrollTop = window.scrollY; // Distance from the top
4618
const docHeight = document.documentElement.scrollHeight; // Full document height
@@ -50,26 +22,28 @@ const ChakraBoxes = () => {
5022
const scrolled = (scrollTop / totalScrollable) * 100;
5123

5224
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]);
5330
};
5431

5532
useEffect(() => {
5633
// Call the function initially and on scroll
57-
calculateClosestBoxToCenter();
5834
calculateScrollPercentage();
5935

60-
window.addEventListener('scroll', calculateClosestBoxToCenter);
6136
window.addEventListener('scroll', calculateScrollPercentage);
6237

6338
// Cleanup the scroll event listener on component unmount
6439
return () => {
65-
window.removeEventListener('scroll', calculateClosestBoxToCenter);
6640
window.removeEventListener('scroll', calculateScrollPercentage);
6741
};
6842
}, [numBoxes]);
6943

7044
return (
7145
<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}>
7347
Scroll Percentage: {scrollPercentage.toFixed(2)}%
7448
</Text>
7549
<MotionBox
@@ -86,7 +60,6 @@ const ChakraBoxes = () => {
8660
{Array.from({ length: numBoxes }).map((_, index) => (
8761
<Box
8862
key={index}
89-
ref={(el) => (boxRefs.current[index] = el)} // Assign the ref to the box
9063
width="200px"
9164
height="50px"
9265
bg={highlightedIndex === index ? "yellow.300" : "teal.300"} // Highlight the box closest to center

0 commit comments

Comments
 (0)