阅读 286

React-hooks封装无缝滑动轮播图(js动画,css动画)

前言

由于现在在基础架构组,写的项目也没有ui框架,基本上都是要自己去封装的。于是需要写一个

轮播图组件,心想这不是分分钟的事情嘛。说写就写...

第一版

思路:用ul li 的结构,再结合js定时器去实现轮播动画,说干就干...

无缝滑动原理: 红色的1, 3都是克隆的过渡元素. index从 3 4 动画结束时,马上将指针滑动到1, 这样就可以实现无缝轮播. image.png

下面上js动画伪代码

Carousel.tsx

 interface Props {     children: React.ReactNode } const PERCENTAGE = 100; // 百分比 const Carousel = (props: Props) => {   const [left, setLeft] = useState(0)   let  tempLeft = useRef(left);      const transform = (target) => {       let timer = setInterval(() => {           if (Math.abs(tempLeft.current - target) <= 1 ) {             clearInterval(timer)             tempLeft.current = target;             setLeft(target);                          if (target/PERCENTAGE >= len + 1) {                 // 此时已经滑动到我们克隆的最后一张元素了                 setIndex(1). // 这里就直接滑动到第一张完成无缝.                 setLeft(100)                 return             }                        }                                 let step = (target - tempLeft.current) / 10;           step = step > 0 ? Math.ceil(step) : Math.floor(step);           tempLeft.current = tempLeft.current + step;           setLeft(() => tempLeft.current);       }, 20)   }     return (         <div className="carousel">             <ul                  className="carousel__container"                 style={{                   left: `-${left}%`,                   width: (len + 2) * PERCENTAGE + "%"                 }}             >                 {children[len - 1]} // 这里将最后一个元素克隆到第一个                 {children}                 {children[0]} // 这里将第一个元素克隆到最后一个             </ul>                      </div>     ) } 复制代码

基本上无缝轮播就实现了,具体还需要加一个正在动画的标识,防止用户点的太快,发生异常。

  • 这样实现还会有几个问题,频繁改变state, 组件渲染次数过多. 因此我们可以考虑使用css实现动画.

  • 使用定时器去完成动画,可能还会发生不可描述的事...

第二版

css动画

 const transform = (target) => {       timeoutId.current && clearTimeout(timeoutId.current);       needAnimate.current = true;       setLeft(target);       if (target / 100 >= len + 1) {         // 下面要不带动画的 滚动到真正的第一个元素         timeoutId.current = setTimeout(() => {           needAnimate.current = false;           setLeft(100);           setIndex(1);         }, 350);       }      }     <ul         style={{             left: `-${index * 100}%`,             width: (len + 2) * 100 + '%',             transition: needAnimate.current ? "all 0.3s" : "none"         }}          >         ...     </ul> 复制代码

上面就是这两种写法, 推荐还是用css动画比较好


作者:唯依绾青丝
链接:https://juejin.cn/post/6986165918720245791


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐