tsx代码:
import React, { useRef } from 'react';
import './top.css'
import { useEffect } from 'react';
import { useState } from 'react';
import { Button } from 'antd';
import { LeftOutlined,RightOutlined} from '@ant-design/icons';
function Top(props: any) {
const { imgUrl, isAuto } = props;
const images = [...imgUrl];
images.unshift(imgUrl[imgUrl.length - 1]);
images.push(imgUrl[0]);
const imgRef = useRef<HTMLImageElement>(null);
const [currentIndex, setCurrentIndex] = useState(1);
const domLoop = useRef<HTMLUListElement>(null);//图片包裹的盒子 需要对其进行 transform
let interval: NodeJS.Timeout;
useEffect(() => {
if (isAuto) {
// eslint-disable-next-line react-hooks/exhaustive-deps
interval = setInterval(() => {
setCurrentIndex((prevIndex) =>
prevIndex === images.length - 1 ? 1 : prevIndex + 1
);
}, 3000);
}
return () => clearInterval(interval);
}, [currentIndex, isAuto, images.length]);
//处理第一张和最后一张图片的跳转
useEffect(() => {
if (currentIndex === 0) {
if(domLoop.current){
domLoop.current.style.transition = 'none';//移除动画样式
clearInterval(interval);//清除定时器
}
setCurrentIndex(images.length - 2);
} else if (currentIndex === images.length - 1) {
if(domLoop.current){
domLoop.current.style.transition = 'none';//移除动画样式
clearInterval(interval);//清除定时器
}
setCurrentIndex(1);
}
}, [currentIndex, images.length]);
const handlePrev = () => {
setCurrentIndex((prevIndex) =>
prevIndex === 1 ? images.length - 2 : prevIndex - 1
);
};
const handleNext = () => {
setCurrentIndex((prevIndex) =>
prevIndex === images.length - 2 ? 1 : prevIndex + 1
);
};
return (
<div className="carousel">
<ul
ref={domLoop}
style={{
width: `${images.length * 100}%`,
transform: `translateX(-${currentIndex * (100 / images.length)}%)`,
transition: 'transform ease-out 0.45s',
}}
>
{images.map((item: string, i: number) => (
<li key={i} style={{ width: `${100 / images.length}%` }}>
<img
ref={imgRef}
src={item}
alt=""
style={{ width: '100%', height: '100%' }}
/>
</li>
))}
</ul>
<LeftOutlined className='leftButton' onClick={handlePrev}/>
<RightOutlined className='rightButton' onClick={handleNext}/>
</div>
);
}
export default Top;
css
/*轮播容器*/
.carousel{
width: 400px;
height: 200px;
/* border: 1px solid red; */
overflow: hidden;
margin:0 auto;
position: relative;
}
/*图片容器*/
.carousel ul{
list-style: none;
/* border: 1px solid black; */
height: 100%;
padding: 0;
margin: 0;
display: flex;
}
.carousel li{
width: 100%;
height: 100%;
display: 'inline-block'
}
.carousel li img{
width: 100%;
height: 100%;
}
.left{
width:100px;
height:50px;
border:1px solid green;
position: absolute;
left: 0;
top: 75px;
}
.leftButton{
position: absolute;
top: 75px;
left: 0;
}
.rightButton{
position: absolute;
top: 75px;
right: 0;
}