#reactjs #carousel #element
#reactjs #карусель #элемент
Вопрос:
Я учусь создавать пользовательские Carousel
, используя React и Typescript. Для стилизации я использовал стилизованные компоненты и scss
. Я нашел в одной статье, как сделать карусель. Моя карусель работает нормально. Я создал четыре div
элемента. когда слайд с изображением карусели изменится, я хочу изменить цвет фона div
элементов inot orange color
. Но не знаю, как это сделать.
Я делюсь своим кодом в codesandbox
Это мой компонент карусели
import React, { useState, useEffect, useRef, memo, useCallback } from "react";
import styled from "styled-components";
interface ICarousel {
children: JSX.Element[];
currentSlide?: number;
autoPlay?: boolean;
dots?: boolean;
interval?: number;
arrow?: boolean;
}
const IMG_WIDTH = 320;
const IMG_HEIGHT = 700;
export default memo(
({
children,
autoPlay = false,
dots = false,
interval = 3000,
arrow = false
}: ICarousel) => {
const [currentSlide, setSlide] = useState(0);
const [isPlaying, setIsPlaying] = useState(autoPlay);
const timer = useRef<any>(undefined);
const slides = children.map((slide, index) => (
<CarouselSlide key={index}>{slide}</CarouselSlide>
));
const handleSlideChange = useCallback(
(index: number) =>
setSlide(
index > slides.length - 1 ? 0 : index < 0 ? slides.length - 1 : index
),
[slides]
);
const createInterval = useCallback(() => {
timer.current = setInterval(() => {
handleSlideChange(currentSlide 1);
}, interval);
}, [interval, handleSlideChange, currentSlide]);
const destroyInterval = useCallback(() => {
clearInterval(timer.current);
}, []);
useEffect(() => {
if (autoPlay) {
createInterval();
return () => destroyInterval();
}
}, [autoPlay, createInterval, destroyInterval]);
return (
<CarouselContainer
onMouseEnter={() => {
if (autoPlay) {
destroyInterval();
}
}}
onMouseLeave={() => {
if (autoPlay) {
createInterval();
}
}}
>
<CarouselSlides currentSlide={currentSlide}>{slides}</CarouselSlides>
{arrow ? (
<div>
<LeftButton onClick={() => handleSlideChange(currentSlide - 1)}>
amp;#10094;
</LeftButton>
<RightButton onClick={() => handleSlideChange(currentSlide 1)}>
amp;#10095;
</RightButton>
</div>
) : null}
{dots ? (
<Dots>
{slides.map((i, index) => (
<Dot
key={index}
onClick={() => handleSlideChange(index)}
active={currentSlide === index}
/>
))}
</Dots>
) : null}
</CarouselContainer>
);
}
);
const Buttons = styled.a`
cursor: pointer;
position: relative;
font-size: 18px;
transition: 0.6s ease;
user-select: none;
height: 50px;
width: 40px;
display: flex;
justify-content: center;
align-items: center;
align-content: center;
top: calc(50% - 25px);
position: absolute;
amp;:hover {
background-color: rgba(0, 0, 0, 0.8);
}
`;
const RightButton = styled(Buttons)`
border-radius: 3px 0 0 3px;
right: 0;
`;
const LeftButton = styled(Buttons)`
border-radius: 0px 3px 3px 0px;
left: 0;
`;
const Dots = styled.div`
display: flex;
justify-content: center;
align-items: center;
align-content: center;
margin-top: 10px;
`;
const Dot = styled.span<{ active: boolean }>`
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 10px;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
background-color: ${({ active }) => (active ? `red` : `#eeeeee`)};
`;
const CarouselContainer = styled.div`
overflow: hidden;
position: relative;
width: ${IMG_WIDTH}px;
height: ${IMG_HEIGHT}px;
img {
/* change the margin and width to fit the phone mask */
width: ${IMG_WIDTH - 20}px;
height: ${IMG_HEIGHT - 50}px;
margin-left: 10px;
margin-top: 15px;
}
z-index: 1;
`;
const CarouselSlide = styled.div`
flex: 0 0 auto;
transition: all 0.5s ease;
width: 100%;
`;
const CarouselSlides = styled.div<{
currentSlide: ICarousel["currentSlide"];
}>`
display: flex;
${({ currentSlide }) =>
` transform: translateX(-${currentSlide ? currentSlide * 100 `%` : 0})`};
transition: transform 300ms linear;
cursor: pointer;
`;
Здесь я использую компонент карусели
import * as React from "react";
import "./styles.scss";
import Carousel from "./carousel";
export const imgUrls = [
`https://images.unsplash.com/photo-1455849318743-b2233052fcff?ixlib=rb-1.2.1amp;ixid=eyJhcHBfaWQiOjEyMDd9amp;auto=formatamp;fit=cropamp;w=900amp;q=60`,
`https://images.unsplash.com/photo-1508138221679-760a23a2285b?ixlib=rb-1.2.1amp;ixid=eyJhcHBfaWQiOjEyMDd9amp;auto=formatamp;fit=cropamp;w=900amp;q=60`,
`https://images.unsplash.com/photo-1519125323398-675f0ddb6308?ixlib=rb-1.2.1amp;ixid=eyJhcHBfaWQiOjEyMDd9amp;auto=formatamp;fit=cropamp;w=900amp;q=60`,
`https://images.unsplash.com/photo-1494253109108-2e30c049369b?ixlib=rb-1.2.1amp;ixid=eyJhcHBfaWQiOjEyMDd9amp;auto=formatamp;fit=cropamp;w=900amp;q=60`
];
export default function App() {
return (
<div className="App">
<main className="Testeru">
<div className="phone-left">
// I want change background color of this div element
<div className="phone-left-upper">left upper</div>
<div className="phone-left-lower">left-lower</div>
</div>
<div className="phone-slider">
<div className="mobile_overlay">
<Carousel autoPlay>
{imgUrls.map((i) => {
return (
<img
key={i}
src={i}
alt=""
style={{
borderRadius: `20px`
}}
/>
);
})}
</Carousel>
</div>
</div>
// I want change background color of this div element
<div className="phone-right">
<div className="phone-right-upper">right upper</div>
<div className="phone-right-lower">right-lower</div>
</div>
</main>
</div>
);
}