
【react无缝轮播组件】
【代码】【react无缝轮播组件】
·
使用react浅显的了解一下无缝轮播图是如何实现的
- 首先接收一个url, 类型为Array的数组, 使用map对数组进行循环渲染,数组渲染前放入"<img"标签,渲染数组的最后一项
- 在数组渲染后放"<img"标签, 渲染数组的第一项;
- 没什么难的,随便看看,我嘴笨,直接把url数组链接放进去 打开就可以看, 然后根据注释慢慢了解3分钟就懂了。
return (
<>
//添加事件的大盒子
<div
className='box'
onMouseDown={(e) => mouseDown(e)}
onMouseMove={(e) => mouseMove(e)}
onMouseUp={(e) => mouseUp(e)}
style={{ width: innerWidth, height: innetHeight, overflow: 'hidden' }}>
//包裹图片的盒子
<div className='loop' ref={domLoop}>
//数组的最后一张图片
<img src={url[url.length - 1]} ref={domWidth} onMouseDown={(e) => e.preventDefault()} style={{ width: innerWidth, height: innetHeight }} alt="" />
{
url && url.length > 0 ? url.map((item, index) => {
return <img src={item} onMouseDown={(e) => e.preventDefault()} style={{ width: innerWidth, height: innetHeight }} key={index} alt="" />
}) : ''
}
//数组的第一张图片
<img src={url[0]} onMouseDown={(e) => e.preventDefault()} style={{ width: innerWidth, height: innetHeight }} alt="" />
</div>
</div>
</>
)
import React, { useState, useRef, useEffect } from 'react'
import './index.css';
export default function LoopChart(props) {
const { url, width, height } = props;
const domWidth = useRef(null);//当前图片宽度
const domLoop = useRef(null);//图片包裹的盒子 需要对其进行 transform
const innerWidth = width ? width : '100%';
const innetHeight = height ? height : '100%';
const [point, setPoint] = useState(0);//按下
const [drop, setDrop] = useState(0);//移动
const [flag, setFlag] = useState(false);//按键开关 true 关闭transition动画 false 开启动画
const [global, setGlobal] = useState(0);//数组下标
const [direction, setDirection] = useState(0); //因为默认有动画 这个作用是取消第一次加载的时候的动画
// 判断是否传入数组
useEffect(() => {
if (url instanceof Array) {
} else {
throw ('需传入一个长度大于1的数组!')
}
}, [url])
useEffect(() => {
if (direction == 0) {
domLoop.current.style.transition = 'none'
setDirection(1)
} else {
//按键开关 true 关闭transition动画 false 开启动画
if (flag) {
domLoop.current.style.transition = 'none'
} else {
domLoop.current.style.transition = 'transform 0.2s'
}
}
}, [flag])
// 4 [ 1, 2, 3, 4] 1
// 到达数组的临界点, 关闭动画 跳转到 之前手动添加的<img>标签上面
//如果为1 则在无动画跳转到 array[0]
//如果是4 则在无动画跳转到 array[ array.length -1 ]
useEffect(() => {
if (global > url.length - 1) {
setTimeout(() => {
domLoop.current.style.transition = 'transform 0s'
setGlobal(0)
}, 200);
}
if (global < 0) {
setTimeout(() => {
domLoop.current.style.transition = 'transform 0s'
setGlobal(url.length - 1);
}, 200);
}
getLoop()
}, [global])
const mouseDown = (e) => {
setFlag(true)
setPoint(e.pageX);
}
// 手动拖拽的时候 不开启动画 translateX 跟随鼠标移动
const mouseMove = (e) => {
if (flag) {
setDrop(point - e.pageX);
domLoop.current.style.transform = `translateX(-${domWidth.current.clientWidth + (global * domWidth.current.clientWidth) + drop}px)`
}
}
// 判断是否达到换页标砖
const mouseUp = (e) => {
setFlag(false)
if (domWidth.current.clientWidth / 4 < Math.abs(drop)) {
if (drop >= 0) {
setGlobal(global + 1);
} else {
setGlobal(global - 1);
}
} else {
getLoop()
}
setPoint(0)
setDrop(0)
}
const getLoop = () => {
domLoop.current.style.transform = `translateX(-${domWidth.current.clientWidth + (global * domWidth.current.clientWidth)}px)`;
}
if (url.length < 1 || !url) {
throw ('最少接收一个长度为1的数组')
}
if (url.length == 1) {
return <img src={url[0]} onMouseDown={(e) => e.preventDefault()} style={{ width: innerWidth, height: innetHeight }} alt='' />
}
return (
<>
<div
className='box'
onMouseDown={(e) => mouseDown(e)}
onMouseMove={(e) => mouseMove(e)}
onMouseUp={(e) => mouseUp(e)}
style={{ width: innerWidth, height: innetHeight, overflow: 'hidden' }}>
<div className='loop' ref={domLoop}>
<img src={url[url.length - 1]} ref={domWidth} onMouseDown={(e) => e.preventDefault()} style={{ width: innerWidth, height: innetHeight }} alt="" />
{
url && url.length > 0 ? url.map((item, index) => {
return <img src={item} onMouseDown={(e) => e.preventDefault()} style={{ width: innerWidth, height: innetHeight }} key={index} alt="" />
}) : ''
}
<img src={url[0]} onMouseDown={(e) => e.preventDefault()} style={{ width: innerWidth, height: innetHeight }} alt="" />
</div>
</div>
</>
)
}
更多推荐
所有评论(0)