35
Create a Slideshow With React
Let's create a simple slideshow component today. It's easy and only take few steps to achieve.
Here is a demo and source code.
Here is a demo and source code.
In order to create a slideshow, we need to have two components:
For a slideshow, we need a container that can:
First, let's create a basic container with style:
export function Slideshow({ children, className, style }) {
return (
<div
style={{
height: "600px",
width: "600px",
position: "relative",
overflow: "hidden"
}}
>
{children}
</div>
);
}
Second, let's add a context that will track activated slide and a timer:
const SlideshowContext = createContext();
export function Slideshow({ children, className, style }) {
const [context, setContext] = useState({
items: [],
edge: false
});
const timer = useRef(null);
useEffect(() => {
if (timer.current) clearTimeout(timer.current);
timer.current = setTimeout(() => {
// Move deactivated slide out when edge is false
// Move activated slide in when edge is true
if (context.items.length > 1 && context.edge) {
const head = context.items.shift();
context.items.push(head);
}
context.edge = !context.edge;
setContext({ ...context });
}, 2500);
return () => clearTimeout(timer.current);
});
console.log(context.items);
return (
<SlideshowContext.Provider value={[context, setContext]}>
<div
style={{
height: "600px",
width: "600px",
position: "relative",
overflow: "hidden"
}}
>
{children}
</div>
</SlideshowContext.Provider>
);
}
And that's all for the container.
The slide will have at least three stages:
The reason we don't move out the slide at "off stage", is because, for this slideshow, we want to move "off" slide after the "on" slide completely cover the "off" one.
Slide will update it's stage when received signal from the container, so it will like:
So, we can have something like this:
export function SlideshowItem({ children }) {
const name = useRef(`${performance.now()}_${Math.random()}`);
// Generate a name for this slide.
const [context] = useContext(SlideshowContext);
const [stage, setStage] = useState("ready");
useEffect(() => {
// register self with the name.
context.items.push(name.current);
return () => {
// Remove the name when slide is removed.
const index = context.items.indexOf(name.current);
context.items.splice(index, 1);
};
}, []);
useEffect(() => {
const activeName = context.items[0];
if (activeName === name.current) {
setStage("on");
}
if (activeName !== name.current && stage === "on") {
setStage("off");
}
if (activeName !== name.current && stage === "off") {
setStage("ready");
}
}, [context]);
let left = 0;
let zIndex = 0;
switch (stage) {
case "ready":
left = "100%";
break;
case "on":
left = "0";
zIndex = 1;
break;
case "off":
zIndex = 0;
break;
default:
}
return (
<div
style={{
transition: "0.5s",
position: "absolute",
top: 0,
left: left,
zIndex: zIndex
}}
>
{children}
</div>
);
}
And now, we have a simple Slideshow.
Thanks all!
Thanks all!
35