UI
2023-04-22 21:56
npm install @emotion/styled
bashnpm install @emotion/react @emotion/styled
bashimport styled from "@emotion/styled";
import React, { useEffect, useState } from "react";
const RollingBanner = ({ speed, children }) => {
const [moveX, setMoveX] = useState(0);
const [direction, setDirection] = useState(1);
useEffect(() => {
if (typeof window !== "object") return;
if (children.length > 3) {
const scroll = document.querySelector("#slide-wrapper").scrollWidth;
const offset = document.querySelector("#slide-wrapper").offsetWidth;
const check = Math.floor(scroll / offset);
const move = setInterval(() => {
setMoveX((prev) => prev + speed * direction);
document.querySelector("#slide-wrapper").style.transform = `translateX(-${moveX}px)`;
}, 100);
if (moveX >= offset * (check - 1) + scroll - offset * check) {
setDirection(-1);
} else if (moveX <= 0) {
setDirection(1);
}
return () => {
clearInterval(move);
};
}
}, [moveX, direction]);
return (
<Container id="container">
<SlideWrapper id="slide-wrapper">
{children.length > 1 ? (
children.map((v, i) => {
return <SlideItem key={i}>{v}</SlideItem>;
})
) : (
<SlideItem>{children}</SlideItem>
)}
</SlideWrapper>
</Container>
);
};
export default RollingBanner;
const Container = styled.div`
overflow: hidden;
`;
const SlideWrapper = styled.ul`
display: flex;
gap: 1rem;
padding: 2rem;
@media (max-width: 768px) {
padding: 1rem;
}
transition: all 0.3s;
`;
const SlideItem = styled.li`
padding: 1rem;
display: flex;
justify-content: center;
align-items: center;
> img {
width: 50px;
height: auto;
}
`;
javascript<RollingBanner speed={5}>
<슬라이드 아이템1/>
<슬라이드 아이템2/>
<슬라이드 아이템3/>
<슬라이드 아이템4/>
<슬라이드 아이템5/>
</RollingBanner>
javascript