2022-12-09 工作记录--React/JS-用swiper实现多行交错、同速、跑马灯效果的弹幕式轮播(总)+ 将一个含未知个数内容的数组,划分成num份

【一】、 React-用swiper实现多行交错、同速、跑马灯效果的弹幕式轮播(总)

一、实现效果

数据轮播(三行交错、同速、跑马灯效果),动图如下:👇🏻

请添加图片描述

二、配置swiper

react-swiper8

1、安装swiper8

npm i swiper@8

或者

yarn add swiper@8

请添加图片描述

2、在app.jsx全局引入

app.jsx

// swiper【Autoplay:自动播放 ,Pagination:分页 ,Navigation:标记页数】
import SwiperCore, { Autoplay, Pagination, Navigation } from 'swiper';
SwiperCore.use([Autoplay, Pagination, Navigation])

三、实现代码

1、先封装一个swiper写的弹幕item组件 —— swiperComponent ⭐️

请添加图片描述

swiperComponent.jsx

【关键点】 实现跑马灯效果的关键点用【关键👇🏻】标注出来了~

/** 
 * swiper写的弹幕item组件
 */

'use strict';
import React from 'react';
import { observer } from 'mobx-react';
import { Swiper, SwiperSlide } from "swiper/react"; // 引入swiper,实现轮播
import 'style-loader!css-loader!swiper/swiper-bundle.css'; // 引入swiper的css

import './swiperComponent.less';

@observer
class SwiperComponent extends React.Component {
    constructor(props) {
        super(props);
    }

	// 【非常重要】fixed: 多行swiper情况下,第一次进入页面时,某一行 出现 先快后慢、滑动一轮后才和其余几行达成一致 的步调
    componentDidMount() {
        this.carouselSwiper?.autoplay.stop(); // 关闭自动切换
        // 加个延时
        setTimeout(() => {
            this.carouselSwiper?.autoplay.start(); // 开启自动切换
        },500)
    }

    // TODO: 根据自己需求对下方两个数据进行调整(可以把autoplay关闭后慢慢调)
    firstContainerSlidesPerView = 1.25; // 第一个swiper-container的slidesPerView
    SecondSlidePaddingLeft = 0.8; // 第二个swiper-slide的paddingLeft值(第一个的值为0)

    render() {
        const {
            // 索引值
            index,
            // 当前轮播信息
            carouselInfo,
        } = this.props;

        return (
            <div className="barrageInner">
                {
                    carouselInfo?.length > 0 &&
                    <Swiper
                        className="barrage"
                        // 设置slider容器能够同时显示的slides数量(carousel模式)
                        slidesPerView={this.firstContainerSlidesPerView - index * 0.15}
                        //【关键👇🏻】匀速时间
                        speed={3000}
                        //【关键👇🏻】设置为true则变为free模式
                        freeMode={true}
                        // 设置为true 则开启loop(无限循环)模式
                        loop={true}
                        // 自动播放
                        autoplay={{
                            delay: 0, //【关键👇🏻】自动切换的时间间隔,单位ms
                        }}
                        onSwiper={swiper => { this.carouselSwiper = swiper; }}
                        style={{ paddingLeft: `${index * this.SecondSlidePaddingLeft}rem` }}
                    >
                        {
                            carouselInfo?.map((item, index) => {
                                return (
                                    <SwiperSlide className="barrageItem" key={index}>
                                        {/* slide背景图 */}
                                        <div className="barrageItemBg"></div>
                                        {/* slide内容 */}
                                        <div className="barrageText text-hidden-ellipsis">{item}</div>
                                    </SwiperSlide>
                                )
                            })
                        }
                    </Swiper>
                }
            </div>);
    }
}

export default SwiperComponent;

swiperComponent.less

【关键点】.swiper-wrapper增加样式transition-timing-function: linear;实现swiper匀速轮播~

.barrageInner {
  width: 100%;
  height: 100%;
  /** 相当于swiper-container */
  .barrage {
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    /**【关键👇🏻】swiper实现匀速轮播 */
    &>.swiper-wrapper {
      -webkit-transition-timing-function: linear;    /*之前是ease-out*/
      -moz-transition-timing-function: linear;
      -ms-transition-timing-function: linear;
      -o-transition-timing-function: linear;
      transition-timing-function: linear;
    }      
    /** 相当于swiper-slide */
    .barrageItem {
      position: relative;
      /** 不需要写宽度,用swiper-slide的默认宽度 */
      height: 62px;
      .barrageItemBg, .barrageText {
        /** slide背景图和slide内容的宽度 */
        width: 467px;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
      }
      /** slide背景 */
      .barrageItemBg {
        opacity: .4;
        background: url("../../assets/startPage/danmuBg.png") no-repeat center/cover;
      }
      /** slide内容 */
      .barrageText {
        padding: 0 10px;
        box-sizing: border-box;  
        font-size: 26px;
        color: #4478a0;
        text-align: center;
        line-height: 62px;
      }
      /** 文字展示固定宽度,超出省略号展示 */
      .text-hidden-ellipsis {
      	white-space: nowrap;
      	overflow: hidden;
      	text-overflow: ellipsis;
      	/** 设置文字方向:从左往右 */
      	direction: ltr;
      }
    }
  }
}
2、调用该组件 ⭐️

homePage.jsx

【注意】多行交错、同速、跑马灯效果的弹幕式轮播 里的 行数 修改方法如下哦: 👇🏻

小萝卜儿们🥕,想实现好多行,就将如下代码里statedevideNum修改成对应理想行数即可哦~

/** 
 * 活动首页
 */

'use strict';
import React from 'react';
import { observer } from 'mobx-react';
import SwiperComponent from "@src/components/swiperComponent/swiperComponent"; // 引入弹幕item组件

import './homePage.less';

@observer
class HomePage extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      /** 弹幕信息 */
      fakeCarouselData: [],
      /** 需划分的swiper份数 */
      devideNum: 3,
    }
  }

  // 测试数据
  carouselInfo = ['嘻嘻嘻1', '啦啦啦啦1', '嘻嘻嘻2', '哈哈哈2', '嘻嘻嘻3'];

  componentDidMount() {
    const result = this.cut(this.state.devideNum, this.carouselInfo);
    console.log('result', result); // [['嘻嘻嘻1', '啦啦啦啦1'],['嘻嘻嘻2', '哈哈哈2'],['嘻嘻嘻3']]
    this.setState({
      fakeCarouselData: result,
    })
  }

  /*
  将一个含未知个数内容的数组,划分成num份
  * num {Int} 需划分的份数 
  * arr {Array} 数据源
  */
  cut = (num, arr) => {
    if (num < 2) {
      console.error("参数不合法");
    }
    const length = arr.length;
    if (length == 0) {
      return [];
    }
    const step = Math.ceil(length / num);
    const list = [];
    for (let i = 0; i < num; i++) {
      const start = i * step;
      const end = length - i * step > step ? (i + 1) * step : length;
      const part = arr.slice(start, end);
      list.push(part);
    }
    return list;
  }

  // 在组件卸载及销毁之前 清空掉swiper里的数据【数据为动态数据时,一定要加这步哦:https://blog.csdn.net/weixin_48850734/article/details/127509051?spm=1001.2014.3001.5501】
  componentWillUnmount() {
	this.carouselInfo = [];
  }

  render() {
    const { fakeCarouselData } = this.state;

    return (
      <div className="homePage">
        {/* 弹幕区域【swiper-no-swiping: 禁止手动滑动】*/}
        <div className="barrageContent swiper-no-swiping">
          {/* 遍历fakeCarouselData数组 */}
          {
            fakeCarouselData.map((item, index) => {
              return (
                <div className="barrageOuter" key={index}>
                  <SwiperComponent index={index} carouselInfo={item} />
                </div>
              )
            })
          }
        </div>
      </div>
    );
  }
}

export default HomePage;

homePage.less

.homePage {
  width: 750px;
  height: 100%;
  position: absolute;
  /** swiper实现的弹幕区域 */
  .barrageContent {
    width: 750px;
    height: 264px;
    position: absolute;
    left: 0;
    top: 1106px;
    /** 轮播的swiper */
    .barrageOuter {
      width: 100%;
      height: 62px;
      &:not(:last-child) {
        margin-bottom: 39px;
      }
    }
  }
}

【二】、JS-将一个含未知个数内容的数组,划分成num

/*
  将一个含未知个数内容的数组,划分成num份
  * @param {Int} num 需划分的份数 
  * @param {Array} arr 数据源
  * @return {Array}
  */
  function cut(num, arr) {
    if (num < 2) {
      console.error("参数不合法");
    }
    const length = arr.length;
    if (length == 0) {
      return [];
    }
    const step = Math.ceil(length / num);
    const list = [];
    for (let i = 0; i < num; i++) {
      const start = i * step;
      const end = length - i * step > step ? (i + 1) * step : length;
      const part = arr.slice(start, end);
      list.push(part);
    }
    return list;
  }

cut(3,['嘻嘻嘻1', '啦啦啦啦1', '嘻嘻嘻2', '哈哈哈2', '嘻嘻嘻3']); // [['嘻嘻嘻1', '啦啦啦啦1'], ['嘻嘻嘻2', '哈哈哈2'], ['嘻嘻嘻3']]

请添加图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小呀小萝卜儿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值