I attempted to implement the card component, gradient background, and animation but fell short of achieving the desired outcome as seen in the gif. How can I enhance the smoothness of the animation, replicate the exact gradient, and ensure the card stands out like in the image?
[NOTE: Please click on the gif link above if it didn't render correctly]
https://i.sstatic.net/xE3xw.gif
import { useCallback, useEffect, useRef, useState } from "react";
import { v4 as uuidv4 } from "uuid";
import Card from "../Card";
import demoCardData from "../../constants/cardData";
export const ScrollableCardList = ({
cardData: propCardData,
}: {
cardData?: Array<any>;
}) => {
const data = propCardData || demoCardData;
const containerRef = useRef<HTMLDivElement>(null);
const [activeIndex, setActiveIndex] = useState(0);
const handleScroll = useCallback(() => {
if (!containerRef.current) return;
const scrollTop = containerRef.current.scrollTop;
const scrollHeight = containerRef.current.scrollHeight;
const clientHeight = containerRef.current.clientHeight;
const scrollRatio = scrollTop / (scrollHeight - clientHeight);
const newActiveIndex = Math.floor(scrollRatio * data.length);
setActiveIndex(newActiveIndex);
}, [data]);
useEffect(() => {
if (!containerRef.current) return;
containerRef.current.addEventListener("scroll", handleScroll);
return () => {
if (!containerRef.current) return;
containerRef.current.removeEventListener("scroll", handleScroll);
};
}, [handleScroll]);
return (
<div
ref={containerRef}
className="flex flex-col items-center h-screen overflow-auto"
style={{ scrollBehavior: "smooth" }}
>
{data.map((card, index) => (
<Card
key={uuidv4()}
imageUrl={card.imageUrl}
avatarImageUrl={card.avatarImageUrl}
titleText={card.titleText}
subTitleText={card.subTitleText}
isActive={index === activeIndex}
/>
))}
</div>
);
};
import { Circular, Rectangular, SubTitle, Title } from "./placeholders";
type CardProps = {
isActive?: boolean;
cardContainerStyles?: string;
rectangleContainerStyles?: string;
circleContainerStyles?: string;
imageUrl?: string;
avatarImageUrl?: string;
titleText?: string;
subTitleText?: string;
};
const Card = ({
isActive,
cardContainerStyles,
rectangleContainerStyles,
circleContainerStyles,
imageUrl,
avatarImageUrl,
titleText,
subTitleText,
}: CardProps) => {
const activeClass = isActive ? "scale-110" : "";
// Ensure transition-transform is part of the base class string
const cardBaseStyles = "transition-transform duration-300 ease-in-out";
const cardDynamicStyles =
cardContainerStyles ||
"w-80 min-h-80 rounded-2xl shadow-4xl p-4 my-4 bg-gradient-to-br from-rose-500 to-rose-400";
const cardStyles = `${cardBaseStyles} ${activeClass} ${cardDynamicStyles}`;
const rectangleStyles =
rectangleContainerStyles ||
"bg-gradient-to-br from-rose-400 to-[#db7483] w-[100%] h-36 rounded-2xl shadow-2xl";
const circleStyles =
circleContainerStyles ||
"w-12 h-12 rounded-full bg-gradient-to-br from-rose-400 to-rose-300 shadow-md";
return (
<div className={cardStyles}>
<Rectangular rectangleStyles={rectangleStyles} imageUrl={imageUrl} />
<div className="flex items-center mt-5">
<Circular circleStyles={circleStyles} avatarImageUrl={avatarImageUrl} />
<div className="flex-grow ml-4">
<Title titleText={titleText} />
<SubTitle subTitleText={subTitleText} />
</div>
</div>
</div>
);
};
export default Card;
Should I have utilized an animation library for this task? What steps should I take to achieve the exact gradient, popup effect, and animation as depicted in the image? Any guidance or solution provided would be greatly appreciated.
Thank you.
For further implementation, visit the codesandbox link: https://codesandbox.io/p/github/Habi-Thapa/rockandscroll/main?import=true