来自对象数组的部分
Sections from an array of objects
我正在尝试在此处使用 React 和 gsap 重新创建此代码笔,我已经尝试重新创建它大约一个小时了,甚至不知道从哪里开始,请谁能提供帮助。我不想在那个代码笔中以相同的方式创建这些部分,而是从一组对象中形成细节,这意味着只创建一次组件,我对反应还很陌生,我想知道如何在反应中做类似的事情,从 vanillajs 的角度来看,我已经知道发生了什么,我也在 React 中创建了它,但我想要一种情况,我的代码最少,并且对象数组形成一个组件,使其更具动态性,因此我可以单击在上面获取有关每个部分的更多信息。请协助
下面的 Codepen link
https://codepen.io/designsbyharp/pen/jObpWZg
HTML
<div class="slider">
<div class="slider__slide slider__slide--1">
<div class="slider__img slider__img--1"></div>
<div class="slider__text slider__text--1">
<h1 class="slider__header">Rejuvenate your, true self.</h1>
<a href="ign.com" class="cta">discover</a>
</div>
</div>
<div class="slider__slide slider__slide--2">
<div class="slider__img slider__img--2"></div>
<div class="slider__text slider__text--2">
<h1 class="slider__header">Professonial, trust-worthy, and compassionate.</h1>
<a href="google.com" class="cta">learn more</a>
</div>
</div>
<div class="slider__slide slider__slide--3">
<div class="slider__img slider__img--3"></div>
<div class="slider__text slider__text--3">
<h1 class="slider__header">Trust in us.</h1>
<a href="youtube.com" class="cta">learn more</a>
</div>
</div>
<div class="slider__slide slider__slide--4">
<div class="slider__img slider__img--4"></div>
<div class="slider__text slider__text--4">
<h1 class="slider__header">What we do.</h1>
<a href="tsn.ca" class="cta">discover</a>
</div>
</div>
<div class="slider__navigation">
<div class="slider__count slider__count--top">
<p class="count count--top count--top-1">01</p>
<p class="count count--top count--top-2">02</p>
<p class="count count--top count--top-3">03</p>
<p class="count count--top count--top-4">04</p>
</div>
<div class="slider__bar">
<div id="sliderBarDynamic" class="slider__bar--dynamic"></div>
<div class="slider__bar--static"></div>
</div>
<div class="slider__count slider__count--bottom">
<p class="count count--bottom count--bottom-1">02</p>
<p class="count count--bottom count--bottom-2">03</p>
<p class="count count--bottom count--bottom-3">04</p>
<p class="count count--bottom count--bottom-3">01</p>
</div>
</div>
</div>
CSS
@import url('https://fonts.googleapis.com/css2?family=Gilda+Display&family=Roboto&display=swap');
*,
*::before,
*::after{
padding:0;
margin:0;
box-sizing:inherit;
}
html{
font-size:16px;
box-sizing:border-box;
}
body{
font-family: 'Roboto', sans-serif;
color:#444444;
font-weight: 300;
line-height: 1.6;
}
img{
max-width:100%;
}
h1{
font-size: 100px;
color: #fff;
font-family: 'Gilda Display', serif;
font-weight: 300;
line-height: 1;
}
h2{
}
h3{
}
P{
color: #fff;
}
a{
text-decoration:none;
color:#ffffff;
font-size: 24px;
}
ul{
list-style-type:none;
}
// Slider
.slider{
width: 100%;
height: 100vh;
overflow: hidden;
position: relative;
&__slide{
width: 100%;
height: 100%;
display: flex;
position: absolute;
top: 0;
left:0;
&--1{
z-index: 4;
}
&--2{
z-index: 3;
}
&--3{
z-index: 2;
}
&--4{
z-index: 1;
}
}
&__img{
width: 100%;
height: 100%;
position: absolute;
z-index: -1;
background-size: cover;
background-repeat: no-repeat;
background-position: 50% 50%;
&--1{
background-image: url('https://i.postimg.cc/Y0T3F1tc/about-landing.jpg');
}
&--2{
background-image: url('https://i.postimg.cc/FHHyKWyf/i-Stock-1148043788.jpg');
}
&--3{
background-image: url('https://i.postimg.cc/tTqp06QH/i-Stock-1064136816.jpg');
}
&--4{
background-image: url('https://i.postimg.cc/435R13K2/i-Stock-1179976698.jpg');
}
}
&__text{
align-self: flex-end;
padding: 0 0 5vw 15vh;
opacity: 0;
width: 80%;
max-width: 1005px;
.slider__header{
margin-bottom: 40px;
text-transform: capitalize;
}
.cta{
font-weight: 700;
text-transform: uppercase;
letter-spacing: 6px;
margin-left: 65px;
position: relative;
&:before{
content: '';
position: absolute;
top: 50%;
transform: translateY(-50%);
left: -55px;
width: 40px;
height: 1px;
background-color: white;
}
}
}
// Slider Navigation
&__navigation{
width: 21px;
height: 400px;
position: fixed;
top: 50%;
transform: translateY(-50%);
left: calc(100% - 5vw);
z-index: 10;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
.count--top{
position: absolute;
top: 0;
left: 0;
// position:
}
.count{
opacity: 0;
}
.count:first-child{
opacity: 1;
}
.count--bottom{
position: absolute;
bottom: 0;
left: 0;
}
&__bar{
width: 2px;
height: 250px;
position: relative;
&--dynamic{
width: 100%;
height: 100%;
background-color: #FF69B4;
transform-origin: top center;
position: absolute;
top: 0;
left: 0;
z-index: 2;
}
&--static{
width: 100%;
height: 100%;
background-color: darkgrey;
position: absolute;
top: 0;
left: 0;
}
}
}
// Slider end
/*
*/
// timeline to control animations everytime the timeline restarts/repeats
let tlRepeat = gsap.timeline();
// Need first slides elements - img and text to animate on each repeat of timeline
let repeatBeginning = ()=>{
gsap.set(bgImage[0], {opacity: 0, scale: 1.2, webkitFilter:"blur(" + 6 + "px)"})
tlRepeat
.add("slide1-in")
.fromTo([countTop[0], countBottom[0]], {opacity: 0}, {duration: 0.3, opacity: 1, ease: "Power2.easeIn"}, "slide1-in")
.to(bgImage[0], {duration: 1.8, scale: 1, opacity: 1, webkitFilter:"blur(" + 0 + "px)"}, "slide1-in")
.fromTo(text[0], {opacity: 0, x: -30, ease: "Power2.easeIn"}, {duration: 0.8, opacity: 1, x: 0}, "-=1")
}
// On start animations
// let onStartSlide1Animations = ()=>{
// // gsap.to(text[0], {duration: 0.7, opacity: 1, x: -15, ease: "Power2.easeIn"})
// }
// Variables
let slides = document.querySelectorAll('.slider__slide'),
dynamicBar = document.querySelector('#sliderBarDynamic'),
countTop = document.querySelectorAll(".count--top"),
countBottom = document.querySelectorAll(".count--bottom"),
bgImage = document.querySelectorAll(".slider__img"),
text = document.querySelectorAll(".slider__text"),
tl = gsap.timeline({repeat: 0, delay: 1, paused: false, onRepeat: repeatBeginning});
// Push all text back and only make first one visible
gsap.set(text, {x: -30});
gsap.set(text[0], {opacity: 1});
// Animate slide's elements but not the first one.
// Make first slide's elements animate when timeline is repeating,
// Follow the flow of rest of the slide's animations
slides.forEach((slide, i) =>{
tl
.fromTo(dynamicBar, {scaleY: 0}, {duration: 1.4, scaleY: 1}, "+=2")
.set(dynamicBar, {transformOrigin: "bottom center"})
.to(dynamicBar, {duration: 1, scaleY: 0}, "+=0.4")
.set(dynamicBar, {transformOrigin: "top center"})
.add("elements-in-out")
.to([countTop[i], countBottom[i]], {opacity: 0}, "elements-in-out")
.to([countTop[i+1], countBottom[i+1]], {opacity: 1}, "elements-in-out")
.to(bgImage[i], {duration: 0.2, opacity: 0}, "elements-in-out")
.set(bgImage[i+1], {scale: 1.2, webkitFilter:"blur(" + 6 + "px)"}, "elements-in-out")
.to(bgImage[i+1], {duration: 1.8, scale: 1, webkitFilter:"blur(" + 0 + "px)"}, "elements-in-out")
.to(text[i], {duration: 0.3, opacity: 0}, "elements-in-out")
.to(text[i+1], {duration: 0.8, opacity: 1, x: 0}, "-=1")
})
如果我对你的问题的理解正确,你需要更 DRY 的实现,这样幻灯片就不会在 HTML/JSX 中明确写出。
将每张幻灯片之间不同的值(即标题和图像源)收集到一个数组中,该数组可以映射到 return。
示例:
const slides = [
{
id: 0,
heading: "SCROLL",
image: {
src:
"https://images.unsplash.com/photo-1567016376408-0226e4d0c1ea?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMyMDUzOA&ixlib=rb-1.2.1&q=80&w=400",
alt: ""
},
overlay: {
src:
"https://images.unsplash.com/photo-1519710164239-da123dc03ef4?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMxOTU4Mw&ixlib=rb-1.2.1&q=80&w=800",
alt: ""
}
},
{
id: 1,
heading: "SWIPE",
image: {
src:
"https://images.unsplash.com/photo-1558603668-6570496b66f8?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMyMDUzOA&ixlib=rb-1.2.1&q=85&w=400",
alt: ""
},
overlay: {
src:
"https://images.unsplash.com/photo-1594666757003-3ee20de41568?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMxOTcwOA&ixlib=rb-1.2.1&q=80&w=800",
alt: ""
}
},
{
id: 2,
heading: "SCROLL",
image: {
src:
"https://images.unsplash.com/photo-1537165924986-cc3568f5d454?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMyMDU4NA&ixlib=rb-1.2.1&q=85&w=400",
alt: ""
},
overlay: {
src:
"https://images.unsplash.com/photo-1579830341096-05f2f31b8259?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMxOTQ5Ng&ixlib=rb-1.2.1&q=80&w=800",
alt: ""
}
},
{
id: 3,
heading: "SWIPE",
image: {
src:
"https://images.unsplash.com/photo-1589271243958-d61e12b61b97?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMyMDU4NA&ixlib=rb-1.2.1&q=80&w=400",
alt: ""
},
overlay: {
src:
"https://images.unsplash.com/photo-1603771628302-c32c88e568e3?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMxOTUxNg&ixlib=rb-1.2.1&q=80&w=800",
alt: ""
}
}
];
替换用于映射此 slides
数组的重复 JSX。
{slides.map((slide) => (
<section key={slide.id} class="slide">
<div class="slide__outer">
<div class="slide__inner">
<div class="slide__content">
<div class="slide__container">
<h2 class="slide__heading">{slide.heading}</h2>
<figure class="slide__img-cont">
<img
class="slide__img"
alt={slide.image.alt}
src={slide.image.src}
/>
</figure>
</div>
</div>
</div>
</div>
</section>
))}
<section class="overlay">
<div class="overlay__content">
<p class="overlay__count">
0<span className="count">1</span>
</p>
<figure class="overlay__img-cont">
{slides.map((slide) => (
<img
key={slide.id}
class="image"
src={slide.overlay.src}
alt={slide.overlay.alt}
/>
))}
</figure>
</div>
</section>
我正在尝试在此处使用 React 和 gsap 重新创建此代码笔,我已经尝试重新创建它大约一个小时了,甚至不知道从哪里开始,请谁能提供帮助。我不想在那个代码笔中以相同的方式创建这些部分,而是从一组对象中形成细节,这意味着只创建一次组件,我对反应还很陌生,我想知道如何在反应中做类似的事情,从 vanillajs 的角度来看,我已经知道发生了什么,我也在 React 中创建了它,但我想要一种情况,我的代码最少,并且对象数组形成一个组件,使其更具动态性,因此我可以单击在上面获取有关每个部分的更多信息。请协助 下面的 Codepen link https://codepen.io/designsbyharp/pen/jObpWZg
HTML
<div class="slider">
<div class="slider__slide slider__slide--1">
<div class="slider__img slider__img--1"></div>
<div class="slider__text slider__text--1">
<h1 class="slider__header">Rejuvenate your, true self.</h1>
<a href="ign.com" class="cta">discover</a>
</div>
</div>
<div class="slider__slide slider__slide--2">
<div class="slider__img slider__img--2"></div>
<div class="slider__text slider__text--2">
<h1 class="slider__header">Professonial, trust-worthy, and compassionate.</h1>
<a href="google.com" class="cta">learn more</a>
</div>
</div>
<div class="slider__slide slider__slide--3">
<div class="slider__img slider__img--3"></div>
<div class="slider__text slider__text--3">
<h1 class="slider__header">Trust in us.</h1>
<a href="youtube.com" class="cta">learn more</a>
</div>
</div>
<div class="slider__slide slider__slide--4">
<div class="slider__img slider__img--4"></div>
<div class="slider__text slider__text--4">
<h1 class="slider__header">What we do.</h1>
<a href="tsn.ca" class="cta">discover</a>
</div>
</div>
<div class="slider__navigation">
<div class="slider__count slider__count--top">
<p class="count count--top count--top-1">01</p>
<p class="count count--top count--top-2">02</p>
<p class="count count--top count--top-3">03</p>
<p class="count count--top count--top-4">04</p>
</div>
<div class="slider__bar">
<div id="sliderBarDynamic" class="slider__bar--dynamic"></div>
<div class="slider__bar--static"></div>
</div>
<div class="slider__count slider__count--bottom">
<p class="count count--bottom count--bottom-1">02</p>
<p class="count count--bottom count--bottom-2">03</p>
<p class="count count--bottom count--bottom-3">04</p>
<p class="count count--bottom count--bottom-3">01</p>
</div>
</div>
</div>
CSS
@import url('https://fonts.googleapis.com/css2?family=Gilda+Display&family=Roboto&display=swap');
*,
*::before,
*::after{
padding:0;
margin:0;
box-sizing:inherit;
}
html{
font-size:16px;
box-sizing:border-box;
}
body{
font-family: 'Roboto', sans-serif;
color:#444444;
font-weight: 300;
line-height: 1.6;
}
img{
max-width:100%;
}
h1{
font-size: 100px;
color: #fff;
font-family: 'Gilda Display', serif;
font-weight: 300;
line-height: 1;
}
h2{
}
h3{
}
P{
color: #fff;
}
a{
text-decoration:none;
color:#ffffff;
font-size: 24px;
}
ul{
list-style-type:none;
}
// Slider
.slider{
width: 100%;
height: 100vh;
overflow: hidden;
position: relative;
&__slide{
width: 100%;
height: 100%;
display: flex;
position: absolute;
top: 0;
left:0;
&--1{
z-index: 4;
}
&--2{
z-index: 3;
}
&--3{
z-index: 2;
}
&--4{
z-index: 1;
}
}
&__img{
width: 100%;
height: 100%;
position: absolute;
z-index: -1;
background-size: cover;
background-repeat: no-repeat;
background-position: 50% 50%;
&--1{
background-image: url('https://i.postimg.cc/Y0T3F1tc/about-landing.jpg');
}
&--2{
background-image: url('https://i.postimg.cc/FHHyKWyf/i-Stock-1148043788.jpg');
}
&--3{
background-image: url('https://i.postimg.cc/tTqp06QH/i-Stock-1064136816.jpg');
}
&--4{
background-image: url('https://i.postimg.cc/435R13K2/i-Stock-1179976698.jpg');
}
}
&__text{
align-self: flex-end;
padding: 0 0 5vw 15vh;
opacity: 0;
width: 80%;
max-width: 1005px;
.slider__header{
margin-bottom: 40px;
text-transform: capitalize;
}
.cta{
font-weight: 700;
text-transform: uppercase;
letter-spacing: 6px;
margin-left: 65px;
position: relative;
&:before{
content: '';
position: absolute;
top: 50%;
transform: translateY(-50%);
left: -55px;
width: 40px;
height: 1px;
background-color: white;
}
}
}
// Slider Navigation
&__navigation{
width: 21px;
height: 400px;
position: fixed;
top: 50%;
transform: translateY(-50%);
left: calc(100% - 5vw);
z-index: 10;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
.count--top{
position: absolute;
top: 0;
left: 0;
// position:
}
.count{
opacity: 0;
}
.count:first-child{
opacity: 1;
}
.count--bottom{
position: absolute;
bottom: 0;
left: 0;
}
&__bar{
width: 2px;
height: 250px;
position: relative;
&--dynamic{
width: 100%;
height: 100%;
background-color: #FF69B4;
transform-origin: top center;
position: absolute;
top: 0;
left: 0;
z-index: 2;
}
&--static{
width: 100%;
height: 100%;
background-color: darkgrey;
position: absolute;
top: 0;
left: 0;
}
}
}
// Slider end
/*
*/
// timeline to control animations everytime the timeline restarts/repeats
let tlRepeat = gsap.timeline();
// Need first slides elements - img and text to animate on each repeat of timeline
let repeatBeginning = ()=>{
gsap.set(bgImage[0], {opacity: 0, scale: 1.2, webkitFilter:"blur(" + 6 + "px)"})
tlRepeat
.add("slide1-in")
.fromTo([countTop[0], countBottom[0]], {opacity: 0}, {duration: 0.3, opacity: 1, ease: "Power2.easeIn"}, "slide1-in")
.to(bgImage[0], {duration: 1.8, scale: 1, opacity: 1, webkitFilter:"blur(" + 0 + "px)"}, "slide1-in")
.fromTo(text[0], {opacity: 0, x: -30, ease: "Power2.easeIn"}, {duration: 0.8, opacity: 1, x: 0}, "-=1")
}
// On start animations
// let onStartSlide1Animations = ()=>{
// // gsap.to(text[0], {duration: 0.7, opacity: 1, x: -15, ease: "Power2.easeIn"})
// }
// Variables
let slides = document.querySelectorAll('.slider__slide'),
dynamicBar = document.querySelector('#sliderBarDynamic'),
countTop = document.querySelectorAll(".count--top"),
countBottom = document.querySelectorAll(".count--bottom"),
bgImage = document.querySelectorAll(".slider__img"),
text = document.querySelectorAll(".slider__text"),
tl = gsap.timeline({repeat: 0, delay: 1, paused: false, onRepeat: repeatBeginning});
// Push all text back and only make first one visible
gsap.set(text, {x: -30});
gsap.set(text[0], {opacity: 1});
// Animate slide's elements but not the first one.
// Make first slide's elements animate when timeline is repeating,
// Follow the flow of rest of the slide's animations
slides.forEach((slide, i) =>{
tl
.fromTo(dynamicBar, {scaleY: 0}, {duration: 1.4, scaleY: 1}, "+=2")
.set(dynamicBar, {transformOrigin: "bottom center"})
.to(dynamicBar, {duration: 1, scaleY: 0}, "+=0.4")
.set(dynamicBar, {transformOrigin: "top center"})
.add("elements-in-out")
.to([countTop[i], countBottom[i]], {opacity: 0}, "elements-in-out")
.to([countTop[i+1], countBottom[i+1]], {opacity: 1}, "elements-in-out")
.to(bgImage[i], {duration: 0.2, opacity: 0}, "elements-in-out")
.set(bgImage[i+1], {scale: 1.2, webkitFilter:"blur(" + 6 + "px)"}, "elements-in-out")
.to(bgImage[i+1], {duration: 1.8, scale: 1, webkitFilter:"blur(" + 0 + "px)"}, "elements-in-out")
.to(text[i], {duration: 0.3, opacity: 0}, "elements-in-out")
.to(text[i+1], {duration: 0.8, opacity: 1, x: 0}, "-=1")
})
如果我对你的问题的理解正确,你需要更 DRY 的实现,这样幻灯片就不会在 HTML/JSX 中明确写出。
将每张幻灯片之间不同的值(即标题和图像源)收集到一个数组中,该数组可以映射到 return。
示例:
const slides = [
{
id: 0,
heading: "SCROLL",
image: {
src:
"https://images.unsplash.com/photo-1567016376408-0226e4d0c1ea?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMyMDUzOA&ixlib=rb-1.2.1&q=80&w=400",
alt: ""
},
overlay: {
src:
"https://images.unsplash.com/photo-1519710164239-da123dc03ef4?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMxOTU4Mw&ixlib=rb-1.2.1&q=80&w=800",
alt: ""
}
},
{
id: 1,
heading: "SWIPE",
image: {
src:
"https://images.unsplash.com/photo-1558603668-6570496b66f8?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMyMDUzOA&ixlib=rb-1.2.1&q=85&w=400",
alt: ""
},
overlay: {
src:
"https://images.unsplash.com/photo-1594666757003-3ee20de41568?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMxOTcwOA&ixlib=rb-1.2.1&q=80&w=800",
alt: ""
}
},
{
id: 2,
heading: "SCROLL",
image: {
src:
"https://images.unsplash.com/photo-1537165924986-cc3568f5d454?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMyMDU4NA&ixlib=rb-1.2.1&q=85&w=400",
alt: ""
},
overlay: {
src:
"https://images.unsplash.com/photo-1579830341096-05f2f31b8259?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMxOTQ5Ng&ixlib=rb-1.2.1&q=80&w=800",
alt: ""
}
},
{
id: 3,
heading: "SWIPE",
image: {
src:
"https://images.unsplash.com/photo-1589271243958-d61e12b61b97?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMyMDU4NA&ixlib=rb-1.2.1&q=80&w=400",
alt: ""
},
overlay: {
src:
"https://images.unsplash.com/photo-1603771628302-c32c88e568e3?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0NjMxOTUxNg&ixlib=rb-1.2.1&q=80&w=800",
alt: ""
}
}
];
替换用于映射此 slides
数组的重复 JSX。
{slides.map((slide) => (
<section key={slide.id} class="slide">
<div class="slide__outer">
<div class="slide__inner">
<div class="slide__content">
<div class="slide__container">
<h2 class="slide__heading">{slide.heading}</h2>
<figure class="slide__img-cont">
<img
class="slide__img"
alt={slide.image.alt}
src={slide.image.src}
/>
</figure>
</div>
</div>
</div>
</div>
</section>
))}
<section class="overlay">
<div class="overlay__content">
<p class="overlay__count">
0<span className="count">1</span>
</p>
<figure class="overlay__img-cont">
{slides.map((slide) => (
<img
key={slide.id}
class="image"
src={slide.overlay.src}
alt={slide.overlay.alt}
/>
))}
</figure>
</div>
</section>