Search

15. Scroll: Progress

15. Scroll: Progress

This example uses the useMotionValue() and useTransform() hooks to change the width of the bar at the bottom.

⚡️ Some Examples – 15 – Scroll: Progress
open in CodeSandbox

Here, we have a scrollY Motion value that we pass to the draggable div’s y.

This way, the scrollY Motion value will update whenever you drag the div, and we can change it with useTransform()to another Motion value that changes the width of the bottom div.

const items = [0, 1, 2, 3, 4];
const height = 70;
const padding = 10;
const size = 150;

export function Example() {
    const scrollY = useMotionValue(0);

    const width = useTransform(
        scrollY,
        [0, -getHeight(items) + size],
        ["calc(0% - 0px)", "calc(100% - 40px)"]
    );

    return (
        <>
            <motion.div
                style={{
                    width: 150,
                    height: 150,
                    borderRadius: 30,
                    overflow: "hidden",
                    position: "relative",
                    transform: "translateZ(0)",
                }}
            >
                <motion.div
                    style={{
                        width: 150,
                        height: getHeight(items),
                        y: scrollY
                    }}
                    drag="y"
                    dragConstraints={{
                        top: -getHeight(items) + size,
                        bottom: 0
                    }}
                >
                    {items.map((index) => {
                        return (
                            <motion.div
                                style={{
                                    width: 150,
                                    height: height,
                                    borderRadius: 20,
                                    backgroundColor: "#fff",
                                    position: "absolute",
                                    top: (height + padding) * index
                                }}
                                key={index}
                            />
                        );
                    })}
                </motion.div>
            </motion.div>
            <motion.div
                style={{
                    width,
                    height: 6,
                    borderRadius: 3,
                    backgroundColor: "#fff",
                    position: "absolute",
                    bottom: 20,
                    left: 20
                }}
            />
        </>
    );
}

function getHeight(items) {
    const totalHeight = items.length * height;
    const totalPadding = (items.length - 1) * padding;
    const totalScroll = totalHeight + totalPadding;
    return totalScroll;
}

We’re using CSS’s calc() to set the value to a maximum of the available width (100%) minus two times 20px for the margins left and right.

calc()

Leave a Reply

plugins premium WordPress
Scroll to Top