I have a div with some children an I have scroll animation inside, this is my code :
const { useRef, useEffect, useState } = React;
function Card({ cardName, refCard }) {
return (
<div className="bubble" ref={refCard}>
<div className="card m-2 pt-2">
<div className="py-1">
<div className="fs-5 mt-2">{cardName}</div>
</div>
</div>
</div>
);
}
let data = [
{
Name: "1"
},
{
Name: "2"
},
{
Name: "3"
},
{
Name: "4"
},
{
Name: "5"
}
];
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");
}
}, []);
console.log(containerWidth);
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}
{renderCards}
</div>
</div>
);
}
ReactDOM.createRoot(document.getElementById('app')).render(<App/>);
.App {
overflow: hidden;
}
.card {
width: 200px !important;
height: 200px;
background: #ffefef;
box-shadow: 0px 1px 4px 1px rgba(158, 151, 151, 0.25);
border-radius: 15px;
margin: 12px;
padding: 12px;
}
.d-flex {
overflow: visible;
animation: animateContainer 5s linear forwards infinite;
}
@keyframes animateContainer {
from {
transform: translateY(0);
}
to {
transform: translateY(-50%);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="app"></div>
In this example I have only 5 children to display each 5s because of ( animation: animateContainer 5s linear forwards infinite;
), but in case I have 100 childrens I can't see all items.. I've tried to change 5s to another variable but the speed change and it's so fast so I want to have the same speed, have you an idea how to achieve it ? I'm open if you have another idea to do it, not sure if the css animation will do the job
Speed = distance ÷ time. When there are more cards, this increases distance, so to keep the same speed, you'd want to increase time proportionally. Since you set 5 seconds in your example for 5 cards, then we could extrapolate this to say that the animation duration should be 1 second per card. You could set this as the animationDuration
property on the style
attribute, using the amount of cards that would render:
const { useRef, useEffect, useState } = React;
function Card({ cardName, refCard }) {
return (
<div className="bubble" ref={refCard}>
<div className="card m-2 pt-2">
<div className="py-1">
<div className="fs-5 mt-2">{cardName}</div>
</div>
</div>
</div>
);
}
const data = Array(100).fill().map((_, i) => ({ Name: i }));
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");
}
}, []);
console.log(containerWidth);
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,
animationDuration: `${data.length}s`,
}}
>
{renderCards}
{renderCards}
</div>
</div>
);
}
ReactDOM.createRoot(document.getElementById('app')).render(<App/>);
.App {
overflow: hidden;
}
.card {
width: 200px !important;
height: 200px;
background: #ffefef;
box-shadow: 0px 1px 4px 1px rgba(158, 151, 151, 0.25);
border-radius: 15px;
margin: 12px;
padding: 12px;
}
.d-flex {
overflow: visible;
animation: animateContainer 5s linear forwards infinite;
}
@keyframes animateContainer {
from {
transform: translateY(0);
}
to {
transform: translateY(-50%);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="app"></div>