Issue
I am working on one small thing where I have to make my divs (card) scroll horizontally with animation kind of without any button click.
What I am trying to achieve
- I have some data of countries, which I am looping and showing horizontally on screen
- I am using flex display to show them, and when scroll giving overflow scroll as hidden and using below code to do the automatic scroll
My component and the function to scroll are below:
const useAnimationFrame = (callback) => {
const requestRef = useRef();
const animate = () => {
callback();
requestRef.current = requestAnimationFrame(animate);
};
useEffect(() => {
requestRef.current = requestAnimationFrame(animate);
return () => cancelAnimationFrame(requestRef.current);
}, []);
};
function Bubble({ Name, className}) {
const [position, setPosition] = useState(0);
console.log(CANVAS_WIDTH);
useAnimationFrame(() =>
setPosition((prevPosition) => {
const newPosition = prevPosition - SCROLL_SPEED;
return newPosition < -200 ? CANVAS_WIDTH : newPosition;
})
);
return (
<div
style={{
transform: `translate(${position}px, 20px)`,
}}
className=""
>
<div className="card m-2 pt-2">
<div className="py-1">
<div className="fs-5 mt-2">{Name}</div>
</div>
</div>
</div>
);
}
So in above code I have given initial position as 0, but the code I am following are taking it from data
Actually my use case is little different:
I am almost done with the code, but the thing is it is not scrolling properly as I think I have made some issue with
transform
or the CSSbelow I am including both code sandboxes of what I have done and what I resource I am following
This is what I have done till now
This is what I am following for help
I am okay with any other approach with CSS or with react-hooks, I am looking for the best approach here which will helpful for future as well.
Edit / update
- I have updated two code sandbox, The first one is How I am trying to do
- I have card and showing it horizontally using d-flex in row
- Now there are lot of cards so there are in form of scroll, Want to show that scroll automatically, do not want to scroll on click
The other code sand box
This one I found an example on google which I am using for my help, they are showing in form of bubbles which is not my case but I am using there approach
Now just stuck with scroll
Please see both the code sandbox example for better understanding
I am open to any other approach, be it totaly with CSS or mixture of css and JS in react.
Solution
I have switched from javaScript animations to css animations. App.js:
import { useRef, useEffect, useState, useLayoutEffect } from "react";
import Card from "./Card.js";
import "./styles.css";
export default function App() {
const ref = useRef(null);
const [containerWidth, setWidth] = useState(100 + "%");
const [animationState, setPlay] = useState("paused");
useEffect(() => {
if (ref.current) {
setWidth(ref.current.scrollWidth + "px");
setPlay("running");
}
}, []);
const renderCards = data.map((el, index) => {
return <Card key={index} cardName={el.Name} />;
});
return (
<div className="App">
<div
className="d-flex"
ref={ref}
style={{
width: `${containerWidth}`,
animationPlayState: animationState
}}
>
{renderCards}
</div>
</div>
);
}
Created another component for cards. Card.js:
import { useRef, useEffect, useState } from "react";
export default function Card({ cardName, refCard }) {
return (
<div className="bubble">
<div className="card m-2 pt-2">
<div className="py-1">
<div className="fs-5 mt-2">{cardName}</div>
</div>
</div>
</div>
);
}
And for css i used keyframes and translateX. Animation starts from right and ends on the left. In order to make d-flex translateX(-100%) of its exact width with keyframes i set its offsetWidth to its scrollWidth.
.App {
overflow: hidden;
}
.card {
width: 200px !important;
height: 200px;
background: #ffffff;
box-shadow: 0px 1px 4px 1px rgba(158, 151, 151, 0.25);
border-radius: 15px;
margin: 12px;
padding: 12px;
}
.d-flex {
display: flex;
transform: translateX(calc(100vw));
overflow: visible;
animation: animateContainer 10s linear forwards infinite;
animation-play-state: paused;
}
@keyframes animateContainer {
from {
transform: translateX(calc(100vw));
}
to {
transform: translateX(calc(-100%));
}
}
Answered By - Cacci
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.