最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用React+ts實現(xiàn)無縫滾動的走馬燈詳細過程

 更新時間:2023年08月17日 10:08:50   作者:林不羈  
這篇文章主要給大家介紹了關(guān)于使用React+ts實現(xiàn)無縫滾動的走馬燈詳細過程,文中給出了詳細的代碼示例以及圖文教程,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

一、走馬燈的作用

走馬燈是一種常見的網(wǎng)頁交互組件,可以展示多張圖片或者內(nèi)容,通過自動播放或者手動切換的方式,讓用戶能夠方便地瀏覽多張圖片或者內(nèi)容。本次實現(xiàn)的不是輪播圖而是像傳送帶一樣的無限滾動的形式。

二、需求梳理

走馬燈可設(shè)置一下屬性:

  • 滾動速度
  • 滾動方向
  • 一屏要顯示項的個數(shù)
  • 容器的寬度
  • 要展示的數(shù)據(jù)
  • 自定義展示項

1691745987770-30b3877e-d08e-433d-b670-b37ad66bc069.gif

三、實現(xiàn)思路

3.1 首先確定一下我們的dom元素

wrap>list>item*n

  • 最外層wrap用于限制顯示區(qū)域的寬度,超過寬度就隱藏。
  • list 用于滾動顯示數(shù)據(jù),所以我們的動畫加在這個元素上。
  • item 用于放置展示項。

3.2 實現(xiàn)無限滾動的動畫

我們用keyframes關(guān)鍵幀動畫來做。但是要滾動多少距離才能實現(xiàn)無限滾動呢?

1.計算動畫滾動距離

1691747412524-776d33fb-2379-404a-846d-bf82d6b5b59c.jpeg

從上面的圖中我們可以看到當(dāng)list的寬度<wrap的寬度(containerWidth)時,會出現(xiàn)滾動后出現(xiàn)空白的情況。那么第二張圖,list的寬度>=wrap的兩倍,就能在向左滾動完list的一半后,不會出現(xiàn)空白,而且為了給人一種無限滾動的效果,list的前后兩部分數(shù)據(jù)要保持一致。所以滾動的距離 = 展示數(shù)據(jù)的個數(shù) * 每項的寬度,而為了無限滾動效果,我們還需要對原始數(shù)據(jù)進行處理。分為以下幾種情況:

  • 數(shù)據(jù)個數(shù)>= 一屏展示個數(shù)(showNum)

此時重復(fù)兩次原始數(shù)據(jù)就能得到滾動數(shù)據(jù)

  • 數(shù)據(jù)個數(shù)< 一屏展示個數(shù)

首先我們要保證沒有空白,那要如何填充呢?只填充到=showNum,行不行呢?我們可以看一下:比如說原始數(shù)據(jù)為[1,2,3],填充完再進行重復(fù)則為 [1,2,3,1,1,2,3,1],這樣會出現(xiàn)1這一項連續(xù)出現(xiàn)了。所以最好的方式是直接填充原始數(shù)據(jù)直到>=showNum,所以最終我們得到的滾動數(shù)據(jù)是[1,2,3,1,2,3 ,1,2,3,1,2,3]

2.插入動畫

因為我們的動畫是根據(jù)傳入的變量得來的,所以不能直接寫在樣式文件里,我們通過在useEffect里插入樣式表對象的方式來實現(xiàn)。

四、完整代碼

組件代碼

import { ReactElement, useEffect } from "react";
import * as React from "react";
import "./index.less";
import { ItemProps } from "./demo";
interface Props {
  Item: (item: ItemProps) => ReactElement;
  showNum: number;
  speed: number;
  containerWidth: number;
  data: Array<any>;
  hoverStop?: boolean;
  direction?: "left" | "right";
}
const fillArray = (arr: any[], length: number): any[] => {
  const result: any[] = [];
  while (result.length < length) {
    result.push(...arr);
  }
  return result.concat(result);
};
function AutoplayCarousel({
  Item,
  showNum,
  speed,
  containerWidth,
  data,
  hoverStop = false,
  direction = "left"
}: Props) {
  const showData = fillArray(data, showNum);
  const length = showData.length;
  const itemWidth = containerWidth / showNum;
  useEffect(() => {
    // 創(chuàng)建一個新的樣式表對象
    const style = document.createElement("style");
    // 定義樣式表的內(nèi)容
    let start = "0";
    let end = `-${(itemWidth * length) / 2}`;
    if (direction === "right") {
      start = end;
      end = "0";
    }
    style.innerText = `
      @keyframes templates-partner-moving {
        0% {
           transform: translateX(${start}px);
        }
        100% {
          transform: translateX(${end}px);
        }
      }
    `;
    if (hoverStop) {
      style.innerText += `.list:hover {
      /*鼠標經(jīng)過后,動畫暫停*/
      animation-play-state: paused !important;
    }`;
    }
    // 將樣式表插入到文檔頭部
    document.head.appendChild(style);
    // 組件卸載時清除樣式表
    return () => document.head.removeChild(style) as any;
  }, []);
  return (
    <div style={{ width: `${containerWidth}px` }} className="wrap">
      <div
        className="list"
        style={{
          width: `${itemWidth * length}px`,
          animation: `templates-partner-moving ${
            (length / showNum / 2) * speed
          }s infinite linear`
        }}
      >
        {showData.map((item) => (
          <div style={{ width: `${itemWidth}px` }}>
            <Item {...item} />
          </div>
        ))}
      </div>
    </div>
  );
}
export default AutoplayCarousel;

demo代碼

import React from "react";
import AutoplayCarousel from "./index";
const data = new Array(5).fill(0).map((item, index) => {
  return { num: index };
});
console.log("data", data);
export interface ItemProps {
  num: number;
}
const itemStyle = {
  border: "1px solid #ccc",
  background: "#fff",
  height: "50px",
  color: "red",
  marginRight: "15px"
};
function Demo() {
  const Item = (item: ItemProps) => {
    return <div style={itemStyle}>{item.num}</div>;
  };
  return (
    <AutoplayCarousel
      Item={Item}
      containerWidth={500}
      showNum={5}
      speed={8}
      data={data}
    />
  );
}
export default Demo;

樣式代碼

* {
	margin: 0;
	padding: 0;
}
.wrap {
	overflow: hidden;
	.list {
		position: relative;
		top: 0px;
		left: 0px;
		height: 100%;
		display: flex;
	}
}

總結(jié) 

到此這篇關(guān)于使用React+ts實現(xiàn)無縫滾動的走馬燈的文章就介紹到這了,更多相關(guān)React+ts實現(xiàn)無縫滾動走馬燈內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入理解React Native核心原理(React Native的橋接(Bridge)

    深入理解React Native核心原理(React Native的橋接(Bridge)

    這篇文章主要介紹了深入理解React Native核心原理(React Native的橋接(Bridge),本文重點給大家介紹React Native的基礎(chǔ)知識及實現(xiàn)原理,需要的朋友可以參考下
    2021-04-04
  • React Native中Mobx的使用方法詳解

    React Native中Mobx的使用方法詳解

    這篇文章主要給大家介紹了關(guān)于React Native中Mobx的使用方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • 淺談react useEffect閉包的坑

    淺談react useEffect閉包的坑

    筆者最近用react useEffect閉包,其中踩到了一些坑在此與大家分享一下。需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • React中重新實現(xiàn)強制實施表單的流程步驟

    React中重新實現(xiàn)強制實施表單的流程步驟

    這篇文章主要介紹了React中重新實現(xiàn)強制實施表單的流程步驟,就像設(shè)計人員一樣,在添加邏輯之前,您需要為不同的狀態(tài)“模擬”或創(chuàng)建“模擬”,例如,這里只是表單的視覺部分的模擬,文中通過代碼示例講解的非常詳細,需要的朋友可以參考下
    2024-05-05
  • React和Vue組件更新的實現(xiàn)及區(qū)別

    React和Vue組件更新的實現(xiàn)及區(qū)別

    React 和 Vue 都是當(dāng)今最流行的前端框架,它們都實現(xiàn)了組件化開發(fā)模式,本文將從React和Vue的組件更新原理入手,剖析兩者虛擬DOM difer算法的異同點,具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • 淺談React中的元素、組件、實例和節(jié)點

    淺談React中的元素、組件、實例和節(jié)點

    這篇文章主要介紹了淺談React中的元素、組件、實例和節(jié)點,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • react中的forwardRef 和memo的區(qū)別解析

    react中的forwardRef 和memo的區(qū)別解析

    forwardRef和memo是React中用于性能優(yōu)化和組件復(fù)用的兩個高階函數(shù),本文給大家介紹react中的forwardRef 和memo的區(qū)別及適用場景,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • React Native 混合開發(fā)多入口加載方式詳解

    React Native 混合開發(fā)多入口加載方式詳解

    這篇文章主要介紹了React Native 混合開發(fā)多入口加載方式詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • React路由封裝的實現(xiàn)淺析

    React路由封裝的實現(xiàn)淺析

    路由是React項目中相當(dāng)重要的概念,對于功能較為復(fù)雜的網(wǎng)頁來說,必然會涉及到不同功能間的頁面跳轉(zhuǎn),本篇文章將對React官方維護的路由庫React-Router-Dom的使用和常用組件進行講解,同時對路由組件傳遞param參數(shù)的方式進行講解,希望對各位讀者有所參考
    2022-08-08
  • React組件對子組件children進行加強的方法

    React組件對子組件children進行加強的方法

    這篇文章主要給大家介紹了關(guān)于React組件中對子組件children進行加強的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用React具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06

最新評論

萝北县| 社旗县| 金山区| 九寨沟县| 华蓥市| 盖州市| 凯里市| 博湖县| 克东县| 新沂市| 宜兴市| 静乐县| 临沧市| 崇阳县| 文安县| 洛宁县| 孟村| 秦皇岛市| 多伦县| 西安市| 济阳县| 黄龙县| 宜兴市| 赤水市| 故城县| 永新县| 工布江达县| 丘北县| 馆陶县| 崇义县| 马关县| 澎湖县| 罗定市| 台江县| 澎湖县| 多伦县| 抚顺市| 宁波市| 延吉市| 区。| 金溪县|