• 2022-06-28 工作记录--React-react-intersection-observer实现图片在可视范围内时加上其对应动图


    React-react-intersection-observer实现图片在可视范围内时加上其对应动图

    一、前言 ⭐️

    最近项目里遇到一个需求⚽️:在一个页面里需同时展示5张动图😎。那么。。。为了提高性能,防止卡顿,前端就需要进行单页面多动效优化处理啦🤔,处理方式如下:🌸

    • 页面一来先展示5张静态图片,只有当某张静态图片进入可视范围内时,才给其加上其对应的动图;未在可视范围内的,就不加上其对应的动图。
      在这里插入图片描述

    二、实现效果 ⭐️

    在这里插入图片描述

    三、实现步骤 ⭐️

    1、安装react-intersection-observer

    react-intersection-observer判断是否在可视范围内。

    yarn add react-intersection-observer
    
    • 1

    或者

    npm install react-intersection-observer --save
    
    • 1

    2、安装swiper

    实现图片轮播,我安装的是swiper3版本,版本根据需求选择即可。

    React-swiper的运用 可查看我的另外一篇博客
    在这里插入图片描述

    npm i swiper@3 
    
    • 1

    或者

     yarn add swiper@3
    
    • 1

    3、到package.json里去判断是否安装成功

    在这里插入图片描述

    4、对应代码 ⭐️

    我分为了三大点:「小萝卜儿们🥕依据这三个点查看对应代码哟」

    • 一、【判断是否在可视范围内】
    • 二、【图片匀速轮播】
      • 「项目需要」让5张图片实现匀速向下滚动的效果。
    • 三、【是否展示动图】
      • 对应索引值的图片出现在可视范围内了,就给其加上对应动图。
        在这里插入图片描述

    scenesPage.jsx

    import React, { useEffect, useState } from "react";
    import { InView } from 'react-intersection-observer'; // 【判断是否在可视范围内】
    import Swiper from "swiper"; // 【图片匀速轮播】—— 引入swiper,实现轮播
    import { SvgaPlayer } from '@spark/animation'; // 公司内部的组件【动图】
    import {RES_PATH} from '../../sparkrc.js';
    
    import "./scenesPage.less"; // 引入样式【根据自己需求编写】
    
    function ScenesPage() {
        // 【是否展示动图】—— 在state里设置变量currentIndex,初始值为0,改变变量的方法名为setCurrentIndex
        const [currentIndex, setCurrentIndex] = useState(0);
    
        useEffect(() => {
            // 【图片匀速轮播】—— 初始化swiper
            new Swiper('.swiper-container1', {
                direction: 'vertical', // 垂直方向
                freeMode: true, // 设置为true则变为free模式
                freeModeMomentum : false, // free模式下,若设置为false则关闭动量,释放slide之后立即停止不会滑动。【详情参考官网,对应位置截图放在最后面啦】
                // speed: 6000, // 匀速时间【在这儿不要加匀速时间,避免在第一页继续往上拉或最后一页继续往下拉出现大片空白区域的情况出现】
            });
        }, []);
    
        // 场景静图和动图-最好写在utils/constans.js里封装成公共的,避免代码冗余
        const scenes = [{
            imgSrc:`${RES_PATH}场景/场景一.png`,
            motionGraph: `${RES_PATH}svga/场景1.svga`,
        },{
            imgSrc:`${RES_PATH}场景/场景二.png`,
            motionGraph: `${RES_PATH}svga/场景2.svga`,
        },{
            imgSrc:`${RES_PATH}场景/场景三.png`,
            motionGraph: `${RES_PATH}svga/场景3.svga`,
        },{
            imgSrc:`${RES_PATH}场景/场景四.png`,
            motionGraph: `${RES_PATH}svga/场景4.svga`,
        },{
            imgSrc:`${RES_PATH}场景/场景五.png`,
            motionGraph: `${RES_PATH}svga/场景5.svga`,
        }]    
    
        return (
            <div className="scenesPage">
                {/* 【图片匀速轮播】—— Swiper */}
                <div className="swiper-container swiper-container1">
                    <div className="swiper-wrapper swiper-wrapper1">
                        {
                            scenes.map((item, index) => {
                                return (
                                    <div className="swiper-slide swiper-slide1"} key={index}>
                                        {/* 【判断是否在可视范围内】—— 需要判断哪些内容是否在可视范围内,就把这些内容写在InView里面 */}
                                        <InView as="div" onChange={(inView, entry) => {
                                            console.log(`${index + 1}张图 出现:`, inView);
                                            if (inView) { // inView:true-在可视范围内;false-不在可视范围内
                                                setTimeout(() => { // 定时器可加可不加,根据实际需求来
                                                    // 【是否展示动图】—— 改变变量currentIndex的值为index,相当于:currentIndex = index(赋值)
                                                    setCurrentIndex(index);
                                                }, 500)
                                            }
                                        }}>
                                            {/* 静图 */}
                                            <img src={item.imgSrc} alt="" />
                                        </InView>
                                        {
                                            // 【是否展示动图】动图 —— currentIndex等于index,就展示对应静图的动图;否则,不展示
                                            currentIndex == index && <SvgaPlayer
                                                className="motionGraph"
                                                src={item.motionGraph}
                                            />
                                        }
                                    </div>
                                )
                            })
                        }
                    </div>
                </div>
            </div>
        );
    }
    
    export default ScenesPage;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    scenesPage.less

    @import "../../../node_modules/swiper/dist/css/swiper.css"; /* 【图片匀速轮播】*/
    
    /* 公共方法 【图片匀速轮播】 */
    .swiper-container {
        width: 100%;
        height: 100vh;
    }
    .swiper-slide {
        text-align: center;
        font-size: 18px;
        background: #fff;
      
        /* Center slide text vertically */
        display: -webkit-box;
        display: -ms-flexbox;
        display: -webkit-flex;
        display: flex;
        -webkit-box-pack: center;
        -ms-flex-pack: center;
        -webkit-justify-content: center;
        justify-content: center;
        -webkit-box-align: center;
        -ms-flex-align: center;
        -webkit-align-items: center;
        align-items: center;
    }
    /* 非公共方法 */
    .scenesPage {
        position: relative;
        .swiper-slide1 {
          width: 750px;
          height: 1334px;
          position: relative;
          img,.motionGraph {
              position: absolute;
              top: 50%;
              left: 50%;
              transform: translate(-50%,-50%);
              width: 100%;
              height: 100%;
              object-fit: cover;
          }
      	}
      	/*【图片匀速轮播】*/
      	.swiper-container1>.swiper-wrapper1 {
    		-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;
      		margin: 0 auto;
      	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    sparkrc.js

    module.exports ={
      "RES_PATH": "/src/assets/",
    }
    
    • 1
    • 2
    • 3

    当当当当~大功告成🌶

    在这里插入图片描述

    【补充】swiper3-freeModeMomentum属性

    在这里插入图片描述

  • 相关阅读:
    oj渊子赛马——贪心算法
    电子元器件采购趋势:面临的挑战与机遇
    对于女生来说,软件测试和前端,学哪一个更好啊
    tiup cluster enable
    OData WebAPI实践-OData与EDM
    Maven历史版本下载
    行业沙龙第一期丨汽配供应链业务的解痛之道与数字化未来
    nvm下载安装+使用教程(管理nodejs版本,实现按需加载版本)
    TiDB混合部署拓扑
    0032【Edabit ★☆☆☆☆☆】【每秒帧数】Frames Per Second
  • 原文地址:https://blog.csdn.net/weixin_48850734/article/details/125522528