一個頭像圖片滾動輪播組件(React實現)

遇到一個效果,組件庫里沒有現成能用的組件,于是手搓了一個,傳入圖片url列表,和其他配置項即可直接使用。

輪播效果

頭像輪播效果

實現思路

假設共有10張圖片輪流滾動,輪播圖展示3張圖片。給正在輪播的圖片綁定visible類,輪播過的圖片綁定left類,待輪播的下一個圖片綁定right。其中,綁定了visible類的圖片以此從左往右排開,綁定了left類的在左側并且隱藏,綁定了right的在右側并隱藏(分左右是為了實現在右側出現、在左側消失的動畫效果)。

  .visible {transform: translateX(calc(var(--index) * @image-width * (1 - var(--overlap))));z-index: calc(var(--index) + 1);opacity: 1;}.left {transform: translateX(-30px);z-index: 1;opacity: 0;}.right {transform: translateX(calc(var(--number) * @image-width * (1 - var(--overlap))));z-index: 1;opacity: 0;}

初始時,給10張圖片分別綁定上不同的類,每次將這些類依次向后調整一格,最后的類挪到最前面。只有綁定了visible類的才會顯示。

圖片圖片1圖片2圖片3圖片4圖片5圖片6圖片10
初始時visiblevisiblevisiblerightleftleftleft
第二leftvisiblevisiblevisiblerightleftleft
第三leftleftvisiblevisiblevisiblerightleft

代碼

核心代碼

新建一個組件,編寫tsx代碼

import { useCallback, useEffect, useRef, useState } from 'react';
import './index.less';interface ImageBannerProps {imagesData: string[];visibleNumber?: number; // 可以看見的數量overlapRate?: number; // 重疊率,默認值0.6interval?: number; // 間隔時間imageSize?: string; // 尺寸
}const ImageBanner: React.FC<ImageBannerProps> = (props) => {const { visibleNumber = 3, overlapRate = 0.3, interval = 1000, imageSize = '40px' } = props;let { imagesData } = props;// 復制到長度>=5,輪播組件最小長度要求while (imagesData.length && imagesData.length < 5) {imagesData = imagesData.concat(imagesData);}let initClassList = Array.from({ length: visibleNumber - 1 },(_, index) => `visible-${index + 1}`,);initClassList = [...initClassList, 'right', 'visible-0'];// 例如當visibleNumber=3時,初始值為["visible-1", "visible-2", "right", "visible-0"]const [classList, setClassList] = useState<string[]>(initClassList); // 每個圖片的class,通過改變class更改樣式const imgListRef = useRef<HTMLDivElement>(null);const initialize = useCallback((classList: string[]) => {if (imgListRef.current) {const imgList = Array.from(imgListRef.current.children);for (let i = 0; i < imgList.length; i++) {if (classList[i].includes('visible')) {const match = classList[i].match(/visible-(\d+)/); // 提取數字imgList[i].className = 'imgBannerItem visible';if (match) {(imgList[i] as HTMLDivElement).style.setProperty('--index', match[1]);}} else {imgList[i].className = 'imgBannerItem ' + classList[i];}}}}, []);const next = useCallback(() => {setClassList((prev) => {const newClassList = [...prev];newClassList.unshift(newClassList.pop()!);initialize(newClassList);return newClassList;});}, [initialize]);useEffect(() => {if (imagesData.length < 1) {return;}let timer;if (imgListRef.current) {const imgList = imgListRef.current.children;for (let i = 0; i < visibleNumber - 1; i++) {imgList[i].className = 'imgBannerItem ' + classList[i];}imgList[visibleNumber].className = 'imgBannerItem ' + classList[visibleNumber];const fillLeft = Array(imagesData.length - visibleNumber - 1).fill('left'); // 填入class為leftconst newClassList = [...classList.slice(0, visibleNumber),...fillLeft,...classList.slice(visibleNumber),];setClassList(newClassList);initialize(newClassList);timer = setInterval(next, interval);}return () => {if (timer) {clearInterval(timer);}};}, []);if (imagesData.length < 1) {return null;}return (<divclassName="imgBannerContainer"ref={imgListRef}style={{'--number': visibleNumber,'--overlap': overlapRate,'--size': imageSize,} as React.CSSProperties}>{imagesData.map((item, idx) => (<img className="imgBannerItem" src={item} alt="" key={idx} />))}</div>);
};export default ImageBanner;

樣式代碼

less代碼

@image-width: var(--size);
@image-height: var(--size);.imgBannerContainer {width: 100%;height: 100%;position: relative;.visible {transform: translateX(calc(var(--index) * @image-width * (1 - var(--overlap))));z-index: calc(var(--index) + 1);opacity: 1;}.left {transform: translateX(-30px);z-index: 1;opacity: 0;}.right {transform: translateX(calc(var(--number) * @image-width * (1 - var(--overlap))));z-index: 1;opacity: 0;}
}.imgBannerItem {width: @image-width;height: @image-height;position: absolute;top: 0;transition: 0.3s;border-radius: 50%;border: 2px solid #fff;
}

使用

引入組件,傳入圖片列表進行使用

import ImageBanner from "../ImageBanner";const urlList = ["url1","url2","url3","url4","url5",	
];const Index = () => {return ( <><div style={{width: 300, height: 40, marginLeft: 20}}><ImageBanner imagesData={urlList} /></div></>);
}export default Index;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/96906.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/96906.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/96906.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

從入門到理解:支持向量機的核心原理與實戰思路

一、SVM 的核心目標&#xff1a;找 “最好” 的超平面。1.1 什么是 “超平面”&#xff1f;超平面是一個幾何概念&#xff0c;簡單來說&#xff1a;在 2 維空間&#xff08;平面&#xff09;中&#xff0c;超平面是一條直線&#xff08;1 維&#xff09;&#xff1b;在 3 維空間…

Python 辦公自動化實戰:Excel 批量處理 + 自動發郵件

Python 辦公自動化實戰&#xff1a;Excel 批量處理 自動發郵件關鍵詞&#xff1a; Python辦公自動化 ? Pandas ? OpenPyXL ? Email ? 定時任務 摘要&#xff1a; 每月底還在手動處理幾十份Excel報表并郵件發送&#xff1f;快來學習如何用Python全自動完成&#xff01;本文…

高教杯數學建模2021-C 生產企業原材料的訂購與運輸

某建筑和裝飾板材的生產企業所用原材料主要是木質纖維和其他植物素纖維材料, 總體可分為 A&#xff0c;B&#xff0c;C 三種類型。該企業每年按 48 周安排生產&#xff0c;需要提前制定 24 周的原 材料訂購和轉運計劃&#xff0c;即根據產能要求確定需要訂購的原材料供應商&…

【Python系列】Flask 和 FastAPI對比

博客目錄1. 類型和設計目標2. 性能3. 異步支持4. 數據驗證和文檔5. 學習曲線和生態6. 使用場景示例對比Flask&#xff08;同步&#xff09;FastAPI&#xff08;異步&#xff09;總結Flask 和 FastAPI 都是 Python 中流行的 Web 框架&#xff0c;但它們的設計目標、特性和適用場…

把 AI 塞進「空調遙控器」——基于 MEMS 溫濕陣列的 1 分鐘極速房間熱場掃描

標簽&#xff1a;MEMS 陣列、熱場掃描、極速空調、TinyML、RISC-V、零樣本、離線推理、節能 ---- 背景&#xff1a;為什么空調遙控器要「畫圖」&#xff1f; 傳統空調只有一個溫濕度探頭&#xff0c;經常“東邊冷、西邊熱”。 ? 大客廳 30 ㎡&#xff0c;溫差 5 ℃&#xff1…

【機器學習】8 Logistic regression

本章目錄 8 Logistic regression 245 8.1 Introduction 245 8.2 Model specification 245 8.3 Model fitting 245 8.3.1 MLE 246 8.3.2 Steepest descent 247 8.3.3 Newton’s method 249 8.3.4 Iteratively reweighted least squares (IRLS) 250 8.3.5 Quasi-Newton (variabl…

C++中如何使用互斥(1)------std::lock_guard

操作系統&#xff1a;ubuntu22.04 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 std::lock_guard 是 C11 引入的一個 RAII&#xff08;Resource Acquisition Is Initialization&#xff09;風格的鎖管理類&#xff0c;用于自動管理互斥鎖&#xff08;mutex&#x…

AI算力提升7.5倍!英偉達發布新一代機器人超級計算機Jetson Thor,驅動物理AI革命

今天&#xff0c;NVIDIA 宣布其專為物理 AI 和機器人打造的新一代機器人計算機 Jetson Thor 正式發售。其中&#xff0c;Jetson AGX Thor 開發者套件售價為 3499 美元&#xff08;約合人民幣 2.5 萬元&#xff09;。NVIDIA 創始人兼首席執行官黃仁勛表示&#xff1a;“Jetson T…

【數學建模】如何總結數學建模中的層次分析法最好

模型簡介模型名稱&#xff1a;層次分析法核心問題類型&#xff1a;評價類核心思想和適用場景 核心思想&#xff1a;將大決策問題拆解成小比較問題&#xff0c;通過數學計算綜合最終結論&#xff1a;本質是人的主觀判斷轉換為客觀數據的工具[[適用場景]] 個人決策企業 / 項目決策…

`mmap` 系統調用詳解

mmap 是 Unix/Linux 系統中一個強大且多用途的系統調用&#xff0c;用于將文件或設備映射到進程的地址空間&#xff0c;實現內存映射I/O。 1. 函數的概念與用途 mmap&#xff08;內存映射&#xff09;函數允許程序將文件或其他對象直接映射到其地址空間&#xff0c;這樣文件內容…

深度剖析Spring AI源碼(二):Model抽象層 - “馴服”天下AI的“緊箍咒”

深度剖析Spring AI源碼&#xff08;二&#xff09;&#xff1a;Model抽象層 - “馴服”天下AI的“緊箍咒”上一章我們鳥瞰了Spring AI的宏偉藍圖&#xff0c;今天&#xff0c;我們要深入這座大廈的基石——Model抽象層。如果說Spring AI是連接Java與AI世界的橋梁&#xff0c;那…

永磁同步電機無速度算法--高頻脈振正弦波注入到兩相靜止坐標系

一、原理介紹采用一種改進的永磁同步電機低速無位置傳感器控制策略。與傳統的旋轉高頻信號注入法和脈振高頻信號注入法不同&#xff0c;該策略選擇向靜止坐標軸系注入高頻脈振信號&#xff0c;轉子位置估計信息可以通過載波電流響應提取。并使用一種類似于簡化型擴展卡爾曼濾波…

嵌入式學習日志————ADC模數轉換器之實驗

1.配置ADC的步驟①開啟RCC時鐘&#xff0c;包括ADC和GPIO的時鐘②配置GPIO&#xff0c;把相應端口配置成模擬輸入模式③配置多路開關&#xff0c;把左邊的通道接入右邊的規則組列表里④配置ADC轉換器⑤調用ADC_Cmd函數&#xff0c;開啟ADC2.庫函數配置ADCCLK分頻器void RCC_ADC…

Java設計模式之《狀態模式》

目錄 1、狀態模式 1.1、介紹 1.2、設計背景 1.3、適用場景 2、實現 2.1、if-else實現 2.2、狀態模式實現 2.3、最終版 1、關于if-else的優化 2、狀態模式下的優化 3、ArrayList 配置“狀態流” 3、總結 前言 關于Java的設計模式分類如下&#xff1a; 對于狀態模式…

three.js+WebGL踩坑經驗合集(9.2):polygonOffsetFactor工作原理大揭秘

本篇延續上篇內容&#xff1a; three.jsWebGL踩坑經驗合集(9.1):polygonOffsetUnits工作原理大揭秘-CSDN博客 跟polygonOffsetUnits相比&#xff0c;polygonOffsetFactor的系數m要復雜得多&#xff0c;因為它跟平面的視角相關&#xff0c;而不像r那樣&#xff0c;在一個固定的…

C++高級特性與設計模式答案

目錄 C++高級特性與設計模式:從資源管理到架構設計 一、C++高級特性:超越基礎語法的利器 1. 什么是RAII(資源獲取即初始化)?它有什么作用? 實現原理 核心作用 2. 什么是Pimpl慣用法?它有什么優勢? 實現方式 核心優勢 3. 什么是CRTP(奇異遞歸模板模式)?它的應用場景是…

論文閱讀:arxiv 2025 Can You Trick the Grader? Adversarial Persuasion of LLM Judges

總目錄 大模型安全相關研究&#xff1a;https://blog.csdn.net/WhiffeYF/article/details/142132328 Can You Trick the Grader? Adversarial Persuasion of LLM Judges https://arxiv.org/pdf/2508.07805 https://www.doubao.com/chat/17534937260220418 文章目錄論文翻譯…

6pen Art

本文轉載自&#xff1a;6pen Art - Hello123工具導航 ** 一、&#x1f3a8; 6pen 是什么&#xff1f; 6pen 是一款由國內團隊開發的 AI 繪畫工具&#xff0c;讓你只需用文字描述想法&#xff0c;就能瞬間生成驚艷的視覺畫作。不管是寫實風景還是抽象概念&#xff0c;它都能理…

Let‘s Encrypt證書在 Android5.x 的設備上報錯

報錯信息&#xff1a; com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.at com.android.volley.toolbox.NetworkUtility.shouldRetryException(N…

C語言數組名與sizeof的深層關聯

要理解 “數組名本質代表整個數組的類型和內存塊” 與 “sizeof(arr) 輸出總字節數” 的關聯&#xff0c;核心是抓住 sizeof 運算符的設計邏輯 和 數組類型的本質屬性—— 這兩者是直接掛鉤的&#xff0c;我們一步步拆解&#xff1a;第一步&#xff1a;先明確 sizeof 的核心作用…