Как реализовать смену картинок с переворотом?
Мне нужно реализовать бесконечную смену картинок, но чтобы при смене они переворачивались, как это лучше сделать? То что сейчас у меня есть работает не совсем правильно. Что мне нужно изменить в моем коде. Только начал изучать анимацию
JS Сделал слайдер чтобы картинки менялись через 5 сек
const [activeIndex, setActiveIndex] = useState<number>(0);
const img = [
<img key={orden1} src={orden1} />,
<img key={orden2} src={orden2} />,
<img key={orden3} src={orden3} />,
<img key={orden4} src={orden4} />,
<img key={orden5} src={orden5} />,
<img key={orden6} src={orden6} />,
<img key={orden7} src={orden7} />
]
useEffect(() => {
const interval = setInterval(() => {
setActiveIndex((current) => {
const res = current === img.length - 1 ? 0 : current + 1
return res
})
}, 5000)
return () => clearInterval(interval)
}, [])
// Вычисляем индекс следующего слайда
const nextImgIndex = activeIndex === img.length - 1 ? 0 : activeIndex + 1
HTML У меня есть карточка с картинками с двух сторон
<div className={s.slider}>
<div className={s.sliderImg} key={activeIndex}>
<div className={s.front}>{img[activeIndex]}</div>
<div className={s.back}>{img[nextImgIndex]}</div>
</div>
</div>
CSS Картинки переворачиваются но это работает не правильно
.slider {
position: absolute;
top: 348px;
left: 776px;
width: 395px;
height: 400px;
margin: auto;
box-sizing: border-box;
display: flex;
align-items: center;
overflow: hidden;
perspective: 1000;
}
.sliderImg {
position: absolute;
width: 100%;
height: 100%;
transition: all 0.6s;
transform-style: preserve-3d;
}
.slider:hover .sliderImg {
transform: rotateY(180deg);
}
.sliderImg img {
width: 100%;
height: 100%;
}
.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
.front {
z-index: 2;
}
.back {
transform: rotateY(180deg);
}
Ответы (2 шт):
Автор решения: Александр Окостень
→ Ссылка
Вы можете попробовать сделать следующее:
const [activeIndex, setActiveIndex] = useState<number>(0);
const images = [
{ src: orden1, frontVisible: true },
{ src: orden2, frontVisible: true },
{ src: orden3, frontVisible: true },
{ src: orden4, frontVisible: true },
{ src: orden5, frontVisible: true },
{ src: orden6, frontVisible: true },
{ src: orden7, frontVisible: true },
];
useEffect(() => {
const interval = setInterval(() => {
setActiveIndex((current) => {
const res = current === images.length - 1 ? 0 : current + 1;
return res;
});
}, 5000);
return () => clearInterval(interval);
}, []);
// Вычисляем индекс следующего слайда
const nextImgIndex = activeIndex === images.length - 1 ? 0 : activeIndex + 1;
// Переворачиваем картинку при смене слайда
images[activeIndex].frontVisible = false;
images[nextImgIndex].frontVisible = true;
.slider {
position: absolute;
top: 348px;
left: 776px;
width: 395px;
height: 400px;
margin: auto;
box-sizing: border-box;
display: flex;
align-items: center;
overflow: hidden;
perspective: 1000;
}
.sliderImg {
position: absolute;
width: 100%;
height: 100%;
transition: all 0.6s;
transform-style: preserve-3d;
}
.slider:hover .sliderImg {
transform: rotateY(180deg);
}
.sliderImg img {
width: 100%;
height: 100%;
}
.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
.front {
z-index: 2;
}
.back {
transform: rotateY(180deg);
}
<div className={s.slider}>
<div className={s.sliderImg} key={activeIndex}>
<div className={`${s.front} ${images[activeIndex].frontVisible ? '' : s.back}`}>
<img src={images[activeIndex].src} alt="Front" />
</div>
<div className={`${s.back} ${images[nextImgIndex].frontVisible ? '' : s.front}`}>
<img src={images[nextImgIndex].src} alt="Back" />
</div>
</div>
</div>
Автор решения: darinka poznyak
→ Ссылка
Если хочется что-то повращать бесконечно, на автомате, без hover, то можно попробовать что-то такое:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Слайдер</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<style type="text/css">
body {
background-color: gray;
}
.stage1, .stage2, .stage3 {
width: 150px;
height: 150px;
margin: auto;
}
@keyframes spincube1 {
from,to {
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
}
16% {
transform: rotateY(-90deg);
}
33% {
transform: rotateY(-90deg) rotateZ(90deg);
}
50% {
transform: rotateY(-180deg) rotateZ(90deg);
}
66% {
transform: rotateY(-270deg) rotateX(90deg);
}
83% {
transform: rotateX(90deg);
}
}
.cubespinner1 {
animation: spincube1 ease-in-out infinite 10s;
transform-style: preserve-3d;
transform-origin: 60px 60px 0;
}
.cubespinner1 div {
position: absolute;
width: 150px;
height: 150px;
border: 1px solid black;
}
.cubespinner1 .face1 {
transform: translateZ(60px);
}
.cubespinner1 .face2 {
transform: rotateY(90deg) translateZ(60px);
}
.cubespinner1 .face3 {
transform: rotateY(90deg) rotateX(90deg) translateZ(60px);
}
.cubespinner1 .face4 {
transform: rotateY(180deg) rotateZ(90deg) translateZ(60px);
}
.cubespinner1 .face5 {
transform: rotateY(-90deg) rotateZ(90deg) translateZ(60px);
}
.cubespinner1 .face6 {
transform: rotateX(-90deg) translateZ(60px);
}
@keyframes spincube2 {
from,to {
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
}
16% {
transform: rotateY(-90deg);
}
33% {
transform: rotateY(-90deg) rotateZ(90deg);
}
50% {
transform: rotateY(-180deg) rotateZ(90deg);
}
66% {
transform: rotateY(-270deg) rotateX(90deg);
}
83% {
transform: rotateX(90deg);
}
}
.cubespinner2 {
animation: spincube2 ease-in-out infinite 10s;
transform-style: preserve-3d;
transform-origin: 60px 60px 0;
}
.cubespinner2 div {
position: absolute;
width: 150px;
height: 150px;
border: 1px solid black;
}
.cubespinner2 .face1 {
transform: translateZ(60px);
}
.cubespinner2 .face2 {
transform: rotateY(90deg) translateZ(60px);
}
.cubespinner2 .face3 {
transform: rotateY(90deg) rotateX(90deg) translateZ(60px);
}
.cubespinner2 .face4 {
transform: rotateY(180deg) rotateZ(90deg) translateZ(60px);
}
.cubespinner2 .face5 {
transform: rotateY(-90deg) rotateZ(90deg) translateZ(60px);
}
.cubespinner2 .face6 {
transform: rotateX(-90deg) translateZ(60px);
}
@keyframes spincube3 {
from,to {
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
}
16% {
transform: rotateY(-90deg);
}
33% {
transform: rotateY(-90deg) rotateZ(90deg);
}
50% {
transform: rotateY(-180deg) rotateZ(90deg);
}
66% {
transform: rotateY(-270deg) rotateX(90deg);
}
83% {
transform: rotateX(90deg);
}
}
.cubespinner3 {
animation: spincube3 ease-in-out infinite 10s;
transform-style: preserve-3d;
transform-origin: 60px 60px 0;
}
.cubespinner3 div {
position: absolute;
width: 150px;
height: 150px;
border: 1px solid black;
}
.cubespinner3 .face1 {
transform: translateZ(60px);
}
.cubespinner3 .face2 {
transform: rotateY(90deg) translateZ(60px);
}
.cubespinner3 .face3 {
transform: rotateY(90deg) rotateX(90deg) translateZ(60px);
}
.cubespinner3 .face4 {
transform: rotateY(180deg) rotateZ(90deg) translateZ(60px);
}
.cubespinner3 .face5 {
transform: rotateY(-90deg) rotateZ(90deg) translateZ(60px);
}
.cubespinner3 .face6 {
transform: rotateX(-90deg) translateZ(60px);
}
.carousel-inner {
text-align: center;
}
.container {
background-color: violet;
}
</style>
</head>
<body>
<div class="container">
<div id="carouselExampleSlidesOnly" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<div class="stage1">
<div class="cubespinner1">
<div class="face1"><img src="https://img0.liveinternet.ru/images/attach/d/3/159/312/159312496_preview_RyoRRRSRRRRRyoR_20230128_213651055.png" alt="winter"></div>
<div class="face2"><img src="https://images.apksecure.com/logos/com.jwwallpapers.animehdscreenwalls_150x150.png" alt="summer"></div>
<div class="face3"><img src="https://img0.liveinternet.ru/images/attach/d/3/159/312/159312496_preview_RyoRRRSRRRRRyoR_20230128_213651055.png" alt="winter"></div>
<div class="face4"><img src="https://images.apksecure.com/logos/com.jwwallpapers.animehdscreenwalls_150x150.png" alt="summer"></div>
<div class="face5"><img src="https://img0.liveinternet.ru/images/attach/d/3/159/312/159312496_preview_RyoRRRSRRRRRyoR_20230128_213651055.png" alt="winter"></div>
<div class="face6"><img src="https://images.apksecure.com/logos/com.jwwallpapers.animehdscreenwalls_150x150.png" alt="summer"></div>
</div>
</div>
</div>
<div class="carousel-item">
<div class="stage2">
<div class="cubespinner2">
<div class="face1"><img src="https://img0.liveinternet.ru/images/attach/d/3/159/312/159312496_preview_RyoRRRSRRRRRyoR_20230128_213651055.png" alt="winter"></div>
<div class="face2"><img src="https://images.apksecure.com/logos/com.jwwallpapers.animehdscreenwalls_150x150.png" alt="summer"></div>
<div class="face3"><img src="https://img0.liveinternet.ru/images/attach/d/3/159/312/159312496_preview_RyoRRRSRRRRRyoR_20230128_213651055.png" alt="winter"></div>
<div class="face4"><img src="https://images.apksecure.com/logos/com.jwwallpapers.animehdscreenwalls_150x150.png" alt="summer"></div>
<div class="face5"><img src="https://img0.liveinternet.ru/images/attach/d/3/159/312/159312496_preview_RyoRRRSRRRRRyoR_20230128_213651055.png" alt="winter"></div>
<div class="face6"><img src="https://images.apksecure.com/logos/com.jwwallpapers.animehdscreenwalls_150x150.png" alt="summer"></div>
</div>
</div>
</div>
<div class="carousel-item">
<div class="stage3">
<div class="cubespinner3">
<div class="face1"><img src="https://img0.liveinternet.ru/images/attach/d/3/159/312/159312496_preview_RyoRRRSRRRRRyoR_20230128_213651055.png" alt="winter"></div>
<div class="face2"><img src="https://images.apksecure.com/logos/com.jwwallpapers.animehdscreenwalls_150x150.png" alt="summer"></div>
<div class="face3"><img src="https://img0.liveinternet.ru/images/attach/d/3/159/312/159312496_preview_RyoRRRSRRRRRyoR_20230128_213651055.png" alt="winter"></div>
<div class="face4"><img src="https://images.apksecure.com/logos/com.jwwallpapers.animehdscreenwalls_150x150.png" alt="summer"></div>
<div class="face5"><img src="https://img0.liveinternet.ru/images/attach/d/3/159/312/159312496_preview_RyoRRRSRRRRRyoR_20230128_213651055.png" alt="winter"></div>
<div class="face6"><img src="https://images.apksecure.com/logos/com.jwwallpapers.animehdscreenwalls_150x150.png" alt="summer"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
</body>
</html>