react函数组件实现四栏轮播图切换

  • Post author:
  • Post category:其他


实现的功能为一个轮播图,分为纵向四栏,切换的时候四部分延迟切换。

在这里插入图片描述

主题思想:将底部整体的div分为四部分,纵向四等分,每部分都是当前要展示的图片,通过定位拼接到一起,看起来跟原版的图片一样,给四部分css设置时间,从左往右依次递增,这样切换的时候就会依次出现了。css部分不细讲,这里主要讲一下函数组件怎么写

import React, { useState, useEffect } from "react";
import "./index.css";

export default function Staring() {
  const [activeSlide, setactiveSlide] = useState(-1);
  const [prevSlide, setprevSlide] = useState(-1);
  const [sliderReady, setsliderReady] = useState(false);
  let IMAGE_PARTS = 4;

  useEffect(() => {
    setTimeout(() => {
      setactiveSlide(0);
      setsliderReady(true);
    }, 0);
  }, []);

  function changeSlides(change) {
    const { length } = slides;
    const prevSlide1 = activeSlide;
    let activeSlide1 = prevSlide1 + change;
    if (activeSlide1 < 0) activeSlide1 = length - 1;
    if (activeSlide1 >= length) activeSlide1 = 0;
    setactiveSlide(activeSlide1);
    setprevSlide(prevSlide1);
  }

  const slides = [
    {
      name: "杨扬",
      message:
        "杨扬在2002年盐湖城冬奥会上,为中国获得了第一枚冬奥会金牌。2006年都灵冬奥会结束后,杨扬宣布退出国家队。2010年2月,她以退役运动员身份当选国际奥委会委员。",
      img: "img/stars/yangyang600.jpg",
    },
    {
      name: "张虹",
      message:
        "张虹在2014年索契冬奥会速度滑冰女子1000米决赛中,滑出了1分14秒02的成绩,力压其他选手夺冠,这是中国冬奥会历史上的第一枚速度滑冰金牌。",
      img: "img/stars/zhanghong600.jpg",
    },
    {
      name: "李坚柔",
      message:
        "李坚柔在索契冬奥会短道速滑女子500米决赛中获得冠军,为中国代表团夺得索契冬奥会首枚金牌。",
      img: "img/stars/lijianrou600.jpg",
    },
    {
      name: "王濛",
      message:
        "王濛在2006年都灵冬奥会获得短道速滑女子500米冠军,4年后又在温哥华冬奥会上夺得短道速滑女子500米、1000米以及3000米接力的金牌。",
      img: "img/stars/wangmeng600.jpg",
    },
    {
      name: "申雪/赵宏博",
      message:
        "申雪、赵宏博在2010年温哥华冬奥会上力压庞清、佟健及德国组合夺冠,完成花样滑冰双人滑项目的大满贯。2012年2月,两人退役。",
      img: "img/stars/shenxuezhaohongbo190.jpg",
    },

    {
      name: "韩晓鹏",
      message:
        "韩晓鹏在2006年都灵冬奥会上一鸣惊人,在决赛中以250.77分力挫群雄,以完美的两个动作获得了都灵冬奥会自由式滑雪男子空中技巧金牌,也是中国第一枚自由式滑雪项目的金牌 。",
      img: "img/stars/hanxiaopeng600.jpg",
    },
    {
      name: "金妍儿",
      message:
        "1990年9月出生,韩国著名女单花样滑冰运动员,出生于韩国京畿道富川市。7岁开始学习花样滑冰。2009年洛杉矶世锦赛上,金妍儿以创造女子短节目和总成绩两项记录的成绩获得冠军。",
      img: "img/stars/jinyaner_big.jpg",
    },
    {
      name: "浅田真央",
      message:
        "日本著名花样滑冰选手,出生于爱知县名古屋市,她是亚洲第一位三次夺得世界花样滑冰锦标赛金牌并赢得三次“世界冠军”头衔的女子单人滑选手。",
      img: "img/stars/qiantianzhenyang_big.jpg",
    },
    {
      name: "普鲁申科",
      message:
        "1982年11月出生,俄罗斯花样滑冰男子单人滑选手。国际滑冰联盟花样滑冰大奖赛分站冠军、世界花样滑冰青年锦标赛冠军、欧洲青年奥运会冠军、友好运动会冠军。",
      img: "img/stars/pulushenke_big.jpg",
    },
    {
      name: "安贤洙",
      message:
        "1985年出生,俄罗斯籍韩国裔男子短道速滑运动员。加入俄罗斯籍并出战2014年索契冬奥会,并获得男子个人1000米冠军,以及1500米季军,500米冠军和5000米接力金牌",
      img: "img/stars/name_ann.png",
    },
    {
      name: "奥拉·比约达伦",
      message:
        "挪威滑雪运动员,绰号“国王”,曾在2002年冬奥会冬季两项项目一人独得男子10公里、15公里和12.5公里追逐赛三枚金牌,被誉为“冬季两项之王”。",
      img: "img/stars/biyuedalun_big.jpg",
    },
    {
      name: "劳琳-威廉姆斯",
      message:
        "1983年出生,美国运动员,世界上跑的最快的女飞人之一,在2005年的赫尔辛基世界田径锦标赛上,威廉姆斯以10秒93获得了女子100米比赛金牌",
      img: "img/stars/weilianmusi.jpg",
    },
    {
      name: "肖恩-怀特",
      message:
        "1986年出生,单板滑雪运动员,曾获得2006年,2010年冬奥会单板滑雪U型槽男子冠军。绰号飞翔的番茄。他是世界上最好的单板滑雪选手、最有才能的滑板选手之一。",
      img: "img/stars/huaite.jpg",
    },
    {
      name: "佩希施泰因",
      message:
        "1972年出生,德国速度滑冰的女运动员。德国成就最大的冬奥会选手,共获得5枚奥运金牌、2枚奥运银牌和2枚奥运铜牌。",
      img: "img/stars/peisixidaien.jpg",
    },
  ];
  function slideName(index) {
    if (activeSlide === index && prevSlide === index) {
      return "slider__slide s--active s--prev";
    } else if (activeSlide === index && prevSlide !== index) {
      return "slider__slide s--active";
    } else if (activeSlide !== index && prevSlide === index) {
      return "slider__slide s--prev";
    } else if (activeSlide !== index && prevSlide !== index) {
      return "slider__slide";
    }
  }
  return (
    <>
      <div className={sliderReady ? "slider s--ready" : "slider"}>
        <p className="slider__top-heading">奥运明星</p>
        <div className="slider__slides">
          {slides.map((slide, index) => (
            <div className={slideName(index)} key={slide.name}>
              <div className="slider__slide-content">
                <h3 className="slider__slide-subheading">
                  {slide.message || slide.name}
                </h3>
                <h2 className="slider__slide-heading">
                  {slide.name.split("").map((l) => (
                    <span key={l}>{l}</span>
                  ))}
                </h2>
              </div>
              <div className="slider__slide-parts">
                {[...Array(IMAGE_PARTS).fill()].map((x, i) => (
                  <div className="slider__slide-part" key={i}>
                    <div
                      className="slider__slide-part-inner"
                      style={{ backgroundImage: `url(${slide.img})` }}
                    ></div>
                  </div>
                ))}
              </div>
            </div>
          ))}
        </div>
        <div className="slider__control" onClick={() => changeSlides(-1)}></div>
        <div
          className="slider__control slider__control--right"
          onClick={() => changeSlides(1)}
        ></div>
      </div>
    </>
  );
}

设置三个值,当前页,上一页和是否开始

页面初始化阶段将是否开始设置为true,当前页为0。

点击上下页时调用函数,传入一个值,如果是下一个就传入1,如果上一页就传入-1

讲当前页的值加上传入的值,然后判断是否超出范围(小于0或者大于length),超出范围作出对应处理

内容中根据当前值去获取对应的数据,这样通过useState改变数据后页面数据也会对应改变,因为css时间的问题,所以就会产生层次变换。

最后附上css代码

h3,
h2 {
    color: #fff;
}

*,
*:before,
*:after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    font-family: "Roboto", Helvetica, Arial, sans-serif;
}

.slider {
    overflow: hidden;
    position: relative;
    height: 100vh;
    color: #fff;
}

.slider__top-heading {
    z-index: 12;
    position: absolute;
    left: 0;
    top: 100px;
    width: 100%;
    text-align: center;
    font-size: 20px;
    text-transform: uppercase;
    letter-spacing: 2.5px;
    transition: all 0.5s 1s;
    transform: translateY(-30px);
    opacity: 0;
}

.slider.s--ready .slider__top-heading {
    transform: translateY(0);
    opacity: 1;
}

.slider__slides {
    position: relative;
    height: 100%;
}

.slider__slide {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.slider__slide.s--active {
    pointer-events: auto;
}

.slider__slide-content {
    z-index: 6;
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    height: 100%;
    text-transform: uppercase;
}

.slider__slide-subheading {
    margin: 0 50px 50px 50px;
    font-size: 24px;
    letter-spacing: 2px;
    transform: translateY(20px);
    opacity: 0;
    transition: 0.5s;
}

.slider__slide.s--active .slider__slide-subheading {
    transition-delay: 0.65s;
    opacity: 1;
    transform: translateY(0);
}

.slider__slide-heading {
    display: flex;
    margin-bottom: 20px;
    font-size: 60px;
    letter-spacing: 12px;
}

.slider__slide-heading span {
    display: block;
    opacity: 0;
    transform: translateY(-60px);
    transition: all 0.3333333333s;
}

.slider__slide.s--prev .slider__slide-heading span {
    transform: translateY(60px);
}

.slider__slide.s--active .slider__slide-heading span {
    opacity: 1;
    transform: translateY(0);
}

.slider__slide-heading span:nth-child(1) {
    transition-delay: 0s;
}

.slider__slide.s--active .slider__slide-heading span:nth-child(1) {
    transition-delay: 0.3333333333s;
}

.slider__slide-heading span:nth-child(2) {
    transition-delay: 0.1s;
}

.slider__slide.s--active .slider__slide-heading span:nth-child(2) {
    transition-delay: 0.4333333333s;
}

.slider__slide-heading span:nth-child(3) {
    transition-delay: 0.2s;
}

.slider__slide.s--active .slider__slide-heading span:nth-child(3) {
    transition-delay: 0.5333333333s;
}

.slider__slide-heading span:nth-child(4) {
    transition-delay: 0.3s;
}

.slider__slide.s--active .slider__slide-heading span:nth-child(4) {
    transition-delay: 0.6333333333s;
}

.slider__slide-heading span:nth-child(5) {
    transition-delay: 0.4s;
}

.slider__slide.s--active .slider__slide-heading span:nth-child(5) {
    transition-delay: 0.7333333333s;
}

.slider__slide-heading span:nth-child(6) {
    transition-delay: 0.5s;
}

.slider__slide.s--active .slider__slide-heading span:nth-child(6) {
    transition-delay: 0.8333333333s;
}

.slider__slide-heading span:nth-child(n+7) {
    transition-delay: 0.6s;
}

.slider__slide.s--active .slider__slide-heading span:nth-child(n+7) {
    transition-delay: 0.9333333333s;
}

.slider__slide-readmore {
    position: relative;
    font-size: 14px;
    text-transform: lowercase;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
    transform: translateY(-20px);
    cursor: pointer;
    opacity: 0;
    transition: 0.5s;
}

.slider__slide.s--active .slider__slide-readmore {
    transition-delay: 0.65s;
    opacity: 1;
    transform: translateY(0);
}

.slider__slide-readmore:before {
    content: "";
    position: absolute;
    left: -2px;
    top: -3px;
    width: calc(100% + 4px);
    height: calc(100% + 6px);
    background: rgba(255, 255, 255, 0.4);
    transform: scaleX(0.3);
    transform-origin: 0 50%;
    transition: transform 0.3s;
}

.slider__slide-readmore:hover:before {
    transform: scaleX(1);
}

.slider__slide-parts {
    position: absolute;
    left: 0;
    top: 0;
    display: flex;
    width: 100%;
    height: 100%;
}

.slider__slide-parts:after {
    content: "";
    z-index: 5;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.1);
}

.slider__slide-part {
    position: relative;
    width: 25%;
    height: 100%;
}

.slider__slide-part-inner {
    overflow: hidden;
    position: relative;
    width: 100%;
    height: 100%;
    background-size: 0 0;
    background-repeat: no-repeat;
    transition: transform 0.5s ease-in-out;
}

.slider__slide-part-inner:before {
    content: "";
    position: absolute;
    width: 100vw;
    height: 100%;
    background-image: inherit;
    background-size: cover;
    background-position: center center;
    transition: opacity 0.25s;
    opacity: 0;
}

.slider__slide-part:nth-child(1) .slider__slide-part-inner {
    z-index: 3;
    transition-delay: 0.24s;
    transform: translateX(-32.5%);
}

.slider__slide.s--active .slider__slide-part:nth-child(1) .slider__slide-part-inner {
    transition-delay: 0.28s;
}

.slider__slide-part:nth-child(1) .slider__slide-part-inner:before {
    left: 0vw;
    transition-delay: 0.365s;
}

.slider__slide.s--active .slider__slide-part:nth-child(1) .slider__slide-part-inner:before {
    transition-delay: 0.28s;
}

.slider__slide-part:nth-child(2) .slider__slide-part-inner {
    z-index: 2;
    transition-delay: 0.16s;
    transform: translateX(-65%);
}

.slider__slide.s--active .slider__slide-part:nth-child(2) .slider__slide-part-inner {
    transition-delay: 0.36s;
}

.slider__slide-part:nth-child(2) .slider__slide-part-inner:before {
    left: -25vw;
    transition-delay: 0.285s;
}

.slider__slide.s--active .slider__slide-part:nth-child(2) .slider__slide-part-inner:before {
    transition-delay: 0.36s;
}

.slider__slide-part:nth-child(3) .slider__slide-part-inner {
    z-index: 1;
    transition-delay: 0.08s;
    transform: translateX(-97.5%);
}

.slider__slide.s--active .slider__slide-part:nth-child(3) .slider__slide-part-inner {
    transition-delay: 0.44s;
}

.slider__slide-part:nth-child(3) .slider__slide-part-inner:before {
    left: -50vw;
    transition-delay: 0.205s;
}

.slider__slide.s--active .slider__slide-part:nth-child(3) .slider__slide-part-inner:before {
    transition-delay: 0.44s;
}

.slider__slide-part:nth-child(4) .slider__slide-part-inner {
    z-index: 0;
    transition-delay: 0s;
    transform: translateX(-130%);
}

.slider__slide.s--active .slider__slide-part:nth-child(4) .slider__slide-part-inner {
    transition-delay: 0.52s;
}

.slider__slide-part:nth-child(4) .slider__slide-part-inner:before {
    left: -75vw;
    transition-delay: 0.125s;
}

.slider__slide.s--active .slider__slide-part:nth-child(4) .slider__slide-part-inner:before {
    transition-delay: 0.52s;
}

.slider__slide.s--active .slider__slide-part-inner {
    transform: translateX(0);
    transition-timing-function: ease;
}

.slider__slide.s--active .slider__slide-part-inner:before {
    opacity: 1;
}

.slider__control {
    z-index: 100;
    position: absolute;
    left: 50px;
    top: 50%;
    width: 50px;
    height: 50px;
    margin-top: -25px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.4);
    transform: translateX(-50px);
    opacity: 0;
    transition: all 0.5s 1s;
    cursor: pointer;
}

.slider__control:before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 20px;
    height: 20px;
    margin-left: -10px;
    margin-top: -10px;
    border: 2px solid #000;
    border-bottom: none;
    border-right: none;
    transform: translateX(5px) rotate(-45deg);
}

.slider__control--right {
    left: auto;
    right: 50px;
    transform: translateX(50px);
}

.slider__control--right:before {
    transform: translateX(-5px) rotate(135deg);
}

.slider.s--ready .slider__control {
    transform: translateX(0);
    opacity: 1;
}

.icon-link {
    z-index: 100;
    position: absolute;
    left: 5px;
    bottom: 5px;
    width: 32px;
}

.icon-link img {
    width: 100%;
    vertical-align: top;
}

.icon-link--twitter {
    left: auto;
    right: 5px;
}



版权声明:本文为small_shadow原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。