react轮播图-环形效果

文章探讨了在React项目中使用Swiper库、react-slick库以及手写动画代码实现轮播图效果的情况。作者遇到理想效果的问题,尝试了不同的解决方案,包括使用CSS动画和react-flip库,但都未能达到预期。最终,作者选择了手写并利用transition和动态改变类名来创建轮播效果,尽管过程中遇到了页面卡顿的问题,但通过调整优化解决了这一问题。
摘要由CSDN通过智能技术生成

先看效果

 完整的项目地址:

https://konnect.chat/

最开始使用swiper +css 动画效果不理想

import { Swiper, SwiperSlide } from "swiper/react";
import swiperTop from "../styles/TopSwiper.module.scss";
import swiper, { Autoplay } from "swiper";
swiper.use([Autoplay]);
import "swiper/css";
const imageArr = [
  "/static/card-alice.png",
  "/static/card-evan.png",
  "/static/card-lloyd.png",
  "/static/card-russell.png",
  "/static/card-alice.png",
  "/static/card-evan.png",
  "/static/card-lloyd.png",
  "/static/card-russell.png",
];
export default () => {
  return (
    <div className="head-top-swiper">
      <Swiper
        className={`container swiper-no-swiping`}
        autoplay={{
          delay: 5000,
        }}
        loop
        spaceBetween={10}
        slidesPerView={2}
      >
        {imageArr.map((image, index) => {
          return (
            <SwiperSlide key={index} className="pc-slide">
              <img src={image} alt="img" />
            </SwiperSlide>
          );
        })}
      </Swiper>
      <style global jsx>{`
        .pc-slide {
          width: 372px ;
          height: 537px;
          display: flex;
          align-items: center;
          justify-content: center;
          border-radius: 40px;
          overflow: hidden;
        }
        .pc-slide img {
          width: 372px ;
          height: 537px ;
          object-fit: contain;
        }
      `}</style>
      <style jsx>{`
        .head-top-swiper {
          width: calc((100vw - 1200px) / 2 + 429px );
          min-width: 800px;
          margin-top: 114px;
          height: 537px;
        }


      `}</style>
    </div>
  );
};
.swiper.container {
  .swiper-wrapper {
    transition-timing-function:  ease-in-out;
  }
  .swiper-slide-prev {
    opacity: 0;
  }
  .swiper-slide-active {
    transform:  scale(1);
    animation: fadeOut 1s forwards !important;
  }
  .swiper-slide-next {
    transform:  scale(0.9);
    animation: fadeIn 1s forwards 0.2s !important;
  }
  .swiper-slide-next + .swiper-slide {
    animation: fade 1s forwards 0.2s !important;
  }

}

// @keyframes fadeNext {
//   0% {
//     transform:  translate(-50%) scale(0.9);
//   }
//   100% {
//     transform: translateY(-50%) scale(0.9);
//   }
// }

@keyframes fadeOut {
  0% {
    opacity: 1;
    transform:  translateY(-50%) scale(1);
  }
  100% {
    opacity: 0;
    transform: translateY(-50%) scale(0.1);
  }
}

@keyframes fadeIn {
  0% {
    transform:  scale(0.9);
  }
  100% {
    transform:  scale(1) translate3d(-80px,0,0);
  }
}

@keyframes fade {
  0% {
    transform:  scale(0.9);
  }
  100% {
    transform: scale(0.9) translateX(-80px);
  }
}

然后使用react-sclick 依旧不理想

import React, { PureComponent } from "react";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import Slider from "react-slick";
const settings = {
  centerMode: true,
  infinite: true,
  centerPadding: "0",
  slidesToShow: 2,
  slidesToScroll: 1,
  speed: 1000,
  autoplay: true,
  autoplaySpeed: 2000,
  arrows:false,
  swipe: false,
  pauseOnHover: false
};
export default class handleSwiper extends PureComponent {
  state = {
    imageArr: [
      "/static/card-alice.png",
      "/static/card-evan.png",
      "/static/card-lloyd.png",
      "/static/card-russell.png",
      "/static/card-alice.png",
      "/static/card-evan.png",
      "/static/card-lloyd.png",
      "/static/card-russell.png",
      "/static/card-alice.png",
      "/static/card-evan.png",
      "/static/card-lloyd.png",
      "/static/card-russell.png",
    ],
  };


  render() {
    const { imageArr = [] } = this.state;
    return (
      <div className="handleSwiper">
        <Slider {...settings}>
          {imageArr.map((item, idx) => {
            return (
              <div className={`item`} key={item}>
                <img src={item} alt="img" />
              </div>
            );
          })}
        </Slider>
        <style jsx>
          {`
            .handleSwiper {
                width: calc((100vw - 1200px) / 2 + 429px );
                min-width: 800px;
                margin-top: 114px;
                height: 537px;
            }
            .item {
              width: 378px!important;
              height: 537px;
              margin-right: 40px;
              border-radius: 52px;
              overflow: hidden;
            }
            .item img {
              width: 372px;
              height: 537px;
              object-fit: contain;
            }
          `}
        </style>
      </div>
    );
  }
}

然后手写+react-flip库写依旧不理想

通过修改数组的内容,比如每隔3s将第一个元素的位置改到最后,前三个是固定动画类

这样会导致页面重排重绘 导致页面明显卡顿。抛弃

最后使用手写 利用transition 和动态改变选中类名

import React, { PureComponent } from "react";
import FlipMove from "react-flip-move";
export default class handleSwiper extends PureComponent {
  state = {
    imageArr: Array(20).fill(' ').map(()=>{
      return [ "/static/card-alice.png",
      "/static/card-evan.png",
      "/static/card-lloyd.png",
      "/static/card-russell.png"]
    }).flat(),
    index: 0,
    transition: true
  };

  computerClass(idx,index) {
    if(idx === index) { 
      return "item-active";
    }else if(idx-1== index) {
      return "item-next";
    }else {
      return "item-hidden";
    }
  }
  componentDidMount() {
    clearInterval(this.timer);
    this.timer = setInterval(() => {
      const {index,imageArr} = this.state 
      let targetIndex = 0
      if( index==imageArr.length-2) {
        targetIndex = 0;
        this.setState({
          transition: false,
          index: targetIndex,
        },()=>{
          this.setState({
            transition: true
          })
        })
        return false
      }else if(index+1<imageArr.length) {
        targetIndex = index +1
      }
      this.setState({
        index: targetIndex
      });
    }, 3000);
  }

  render() {
    const { imageArr = [],index,transition } = this.state;
    return (
      <FlipMove>
        <div className="handleSwiper">
          {imageArr.map((item, idx) => {
            return (
              <div className={`item ${this.computerClass(idx,index)}`} key={item} style={{
                transition: transition? `all 0.6s`: 'none'
              }}>
                <img src={item} alt="img" />
              </div>
            );
          })}
          <style jsx>
            {`
              .handleSwiper {
                margin-top: 114px;
                width: 100%;
                height: 537px;
                display: flex;
                align-items: center;
                transition: all 0.8s;
                position: relative;
              }
              .item {
                width: 378px;
                height: 537px;
                margin-right: 40px;
                border-radius: 52px;
                overflow: hidden;

              }
              .item img {
                width: 372px;
                height: 537px;
                object-fit: contain;
              }
            `}
          </style>
        </div>
      </FlipMove>
    );
  }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥肥呀呀呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值