效果
实现思路
代码
html
<div className="flex select-wrap" ref={containerRef}>
<div className="flex" style={{width: '100%', transform: `translateX(${translateX})`, transition: 'transform 500ms'}}>
{list.map((item, i) => <div className={'swiper-slide item' + ((i == num) ? ' active' : '')} style={{width: itemWidth + 'px'}}>
<img src={item.img} className="img" />
</div>)}
</div>
</div>
js
let containerRef = useRef(null)
const list = responseStudentVoiceList
const [num, setnum] = useState(0)
const [translateX, settranslateX] = useState('0px')
const slidesPerView = 7
const [itemWidth, setitemWidth] = useState(0)
const [totalWidth, settotalWidth] = useState(0)
const slideTo = (num: number, type: string) => {
// translateX值
const left = +(translateX.replace('px', ''))
let width = (num) * itemWidth
// 右侧边界处
if(type == 'right' && Math.abs(((width % totalWidth) / itemWidth) + (left / itemWidth) % slidesPerView) == 0){
let _n = list.length - num
let n = _n > slidesPerView ? slidesPerView : _n
let v = - (itemWidth * n)
settranslateX(`${v + left}px`)
}
// 左侧边界
if(type == 'left' && Math.abs(width) == Math.abs(left)){
settranslateX(`${num > slidesPerView ? left - (-totalWidth) : 0}px`)
}
}
const onLeft = () => {
if (num <= 0) return
setnum(num - 1)
slideTo(num , 'left')
}
const onRight = () => {
if (num >= list.length - 1) return
setnum(num + 1)
slideTo(num + 1, 'right')
}
useEffect(() => {
const totalWidth = +getComputedStyle(containerRef.current).width.replace('px', '')
settotalWidth(totalWidth)
setitemWidth(totalWidth / slidesPerView)
}, [])
--end--