前端组件

编程入门 行业动态 更新时间:2024-10-22 16:41:19

前端<a href=https://www.elefans.com/category/jswz/34/1771375.html style=组件"/>

前端组件

目录

一、预览图

二、源码


一、预览图

 

 

 

二、源码

import React, { useState, useEffect, useRef } from "react";
import Store from "./store";
import ReIcon from "bases/ReIcon";
import Loading from "./Loading";
import "./index.less";const getQueryParams = () => {const searchParams = new URLSearchParams(window.location.search);const queryParams = {};for (const [key, value] of searchParams.entries()) {queryParams[key] = isNaN(value) ? value : Number(value);}return queryParams;
};const IntroductionImageViewer = ({ name, history }) => {const [currentIndex, setCurrentIndex] = useState(0);const [isButtonDisabled, setButtonDisabled] = useState(false);const [multipleImagesUrlList, setMultipleImagesUrlList] = useState([]);const [selectedThumbnailIndex, setSelectedThumbnailIndex] = useState(0);const [currentPageIndex, setCurrentPageIndex] = useState(1); // Define currentPageIndex stateconst [totalItemCount, setTotalItemCount] = useState(0);const [currentItemCount, setCurrentItemCount] = useState(0);const [loading, setLoading] = useState(false);const scrollContainerRef = useRef(null);const queryParams = getQueryParams();const store = Store.stores[name]? Store.stores[name]: new Store({ name, history });useEffect(() => {if (Store.stores[name]) {store.afterMethodOnEvent();} else {store.mount();}fetchData(queryParams.english,queryParams.userId,queryParams.listId,queryParams.coverIndex);return () => {store.unMount();};}, []);const handlePrev = (imagesData) => {if (isButtonDisabled) {return;}setSelectedThumbnailIndex(-1);setCurrentIndex((prevIndex) => {const newIndex = prevIndex === 0 ? imagesData.length - 1 : prevIndex - 1;return newIndex;});setButtonDisabled(true);handleScrollLeft();setLoading(true);setTimeout(() => {setSelectedThumbnailIndex(-1); // 重置 selectedThumbnailIndexsetButtonDisabled(false);if (currentIndex === 0) {// 到达第一页,滚动到最后一页的位置if (scrollContainerRef.current) {const scrollContainerWidth = scrollContainerRef.current.offsetWidth;const scrollContentWidth = scrollContainerRef.current.scrollWidth;scrollContainerRef.current.scrollLeft =scrollContentWidth - scrollContainerWidth;}}setLoading(false);}, 500);};const handleNext = (imagesData) => {if (isButtonDisabled) {return;}setSelectedThumbnailIndex(-1);setCurrentIndex((prevIndex) => (prevIndex + 1) % imagesData.length);setButtonDisabled(true);handleScrollRight();setLoading(true);setTimeout(() => {setSelectedThumbnailIndex(-1);setButtonDisabled(false);if (currentIndex + 1 === imagesData.length) {if (shouldFetchNextPage(currentItemCount, totalItemCount)) {fetchNextPageData(currentPageIndex);setCurrentIndex(currentItemCount);setSelectedThumbnailIndex(currentItemCount);}if (scrollContainerRef.current) {scrollContainerRef.current.scrollLeft = 0;}}setLoading(false);}, 500);};const shouldFetchNextPage = (currentPage, totalPages) => {return currentPage < totalPages;};const fetchNextPageData = (currentPage) => {const nextPageNumber = currentPage + 1;setCurrentPageIndex(nextPageNumber);fetchData(queryParams.english,queryParams.userId,queryParams.listId,queryParams.coverIndex,nextPageNumber);};const handleThumbnailClick = (index) => {setSelectedThumbnailIndex(index === selectedThumbnailIndex ? -1 : index);setCurrentIndex(index);};const handleScrollLeft = () => {console.log("向左滚动");if (scrollContainerRef.current) {const scrollAmount = isMobile() ? 60 : 122; // 根据移动端或非移动端设备调整滚动距离scrollContainerRef.current.scrollLeft -= scrollAmount;}};const handleScrollRight = () => {console.log("向右滚动");if (scrollContainerRef.current) {const scrollAmount = isMobile() ? 60 : 122; // 根据移动端或非移动端设备调整滚动距离scrollContainerRef.current.scrollLeft += scrollAmount;}};const isMobile = () => {return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);};const fetchData = (english, userId, listId, coverIndex, pageNumber = 1) => {stores.Frame.showLoading();let url = "";let albumRequestData = {id: listId,pageNumber,pageSize: 50,};let requestData = {userId,};switch (english) {case "#research":url = api.getResearchList;break;case "#treatise":url = api.getTreatiseList;break;case "#newsReport":url = api.getNewsReport;break;case "#bigEvent":url = api.getHistoryList;break;case "#artist":url = api.getAwardList;break;case "#activityAlbum":url = api.getActivityAlbumList;setCurrentIndex(coverIndex);setSelectedThumbnailIndex(coverIndex);break;default:return;}request({url,data: english === "#activityAlbum" ? albumRequestData : requestData,}).then((res) => {if (res && res.code === 200 && res.data && Array.isArray(res.data)) {stores.Frame.hideLoading();const multipleImagesUrlDataList = res.data.filter((item) => item.id === listId);const { multipleImagesUrl } = multipleImagesUrlDataList[0];const parsedMultipleImagesUrlList = JSON.parse(multipleImagesUrl);setMultipleImagesUrlList(parsedMultipleImagesUrlList);} else if (english === "#activityAlbum" &&res.code === 200 &&res.data &&Array.isArray(res.data.list)) {stores.Frame.hideLoading();setTotalItemCount(res.data.total);const multipleImagesUrlDataList = res.data.list.map((Item) => {if (!isValidFileFormat(Item.url)) {return Item.cover;}return Item.url;});setMultipleImagesUrlList((prevList) => [...prevList,...multipleImagesUrlDataList,]);setCurrentItemCount(multipleImagesUrlDataList.length + (pageNumber - 1) * 50);if (shouldFetchNextPage(pageNumber, Math.ceil(totalItemCount / 50))) {fetchNextPageData(pageNumber);}}}).catch((err) => {stores.Frame.error(err.message);});};const isValidFileFormat = (url) => {// Remove query parameters from the URLconst cleanUrl = url.split("?")[0];// List of valid file extensions or formatsconst validExtensions = /\.(jpg|jpeg|png|gif|mp4)$/i;// Use the regular expression to test if the URL's format is validreturn validExtensions.test(cleanUrl);};const conditionalRender = () => {const currentItem = multipleImagesUrlList[currentIndex];if (utils.isVideo(currentItem)) {return (<videocontrolsclassName="video_page"alt={`multipleImagesUrlList ${currentIndex + 1}`}muted // 添加 muted 属性key={`multipleImagesUrlList ${currentIndex + 1}`} // 添加 key 属性><sourcesrc={utils.pictureThumb(currentItem, false)}type="video/mp4"/></video>);} else {return (<imgsrc={utils.pictureThumb(currentItem, false)}alt={`multipleImagesUrlList ${currentIndex + 1}`}className="cover"/>);}};const renderImages = () => {return multipleImagesUrlList.map((item, index) => (<divkey={index}className={`scroll_cover ${selectedThumbnailIndex === index ? "selected" : ""} ${currentIndex === index ? "highlight" : ""}`}onClick={() => handleThumbnailClick(index)}><imgsrc={utils.pictureThumb(utils.isVideo(item)? item +"?x-oss-process=video%2Fsnapshot%2Ct_7000%2Cf_jpg%2Cw_800%2Ch_600%2Cm_fast": item,!utils.isVideo(item))}alt={`${item}${currentIndex + 1}`}className="cover_image"/>{utils.isVideo(item) && (<div className="artwork-cover-mask"><ReIcon icon="shipin1" className="icon" /></div>)}</div>));};return (<div className="introduction_image_viewer"><div className="image-container"><div className="nav-buttons"><spanclassName="prev-button"onClick={() => handlePrev(multipleImagesUrlList)}disabled={isButtonDisabled}><ReIcon icon="prev" /></span><spanclassName="next-button"onClick={() => handleNext(multipleImagesUrlList)}disabled={isButtonDisabled}><ReIcon icon="next" /></span></div><div className="image_page">{conditionalRender()}<div className="index_Page">{`${currentIndex + 1} / ${multipleImagesUrlList.length}`}</div></div></div>{/* Scrollable container */}<div className="scroll_image_container_page"><span className="scoll_icon" onClick={handleScrollLeft}><ReIcon icon="prev" /></span><div className="scroll_image_list" ref={scrollContainerRef}>{renderImages()}</div><span className="scoll_icon" onClick={handleScrollRight}><ReIcon icon="next" /></span></div>{/* {loading && <Loading />} */}</div>);
};export default IntroductionImageViewer;
@import "~styles/constant.less";.introduction_image_viewer {display: flex;justify-content: center;align-items: center;width: 100%;height: 100vh;background: #222222;position: relative;flex-direction: column;.root-page-loading {background-color: rgba(0, 0, 0, 0.5) !important; /* 设置背景半透明颜色 */}::selection {background-color: transparent;}.scroll_image_container_page {display: flex;justify-content: center;align-items: center;width: 72%;position: absolute;height: 102 / @remScale;bottom: 5%;@media (max-width: @max1) {width: 80%;}.scoll_icon {width: 39 / @remScale;height: 102 / @remScale;background: rgba(0, 0, 0, 0.4);backdrop-filter: blur(1 / @remScale);display: flex;justify-content: center;align-items: center;color: #999999;cursor: pointer;@media (max-width: @max1) {height: 50 / @remScale;}.re-icon-root {width: 28 / @remScale;height: 28 / @remScale;@media (max-width: @max1) {width: 15 / @remScale;height: 15 / @remScale;}}}.scroll_image_list {width: 100%;height: 100%;display: flex;justify-content: flex-start; /* 将内容靠左对齐 */align-items: center;overflow: auto; /* 修改为auto */overflow-x: hidden; /* 隐藏水平滚动条 */overflow-y: hidden; /* 隐藏垂直滚动条 */position: relative;.selected {border: 2px solid #ffff;}.highlight {border: 2px solid #ffff;}.scroll_cover {width: 102 / @remScale;height: 102 / @remScale;margin-right: 20 / @remScale;cursor: pointer;position: relative;@media (max-width: @max1) {width: 56 / @remScale;height: 56 / @remScale;margin-right: 10 / @remScale;}.artwork-cover-mask {position: absolute;width: 100%;height: 100%;background: rgba(0, 0, 0, 0.4);color: @white;display: flex;z-index: 9;top: 0;@media (max-width: @max1) {border-radius: 4 / @remScale 4 / @remScale 0 0;}.icon {width: 40 / @remScale;height: 30 / @remScale;opacity: 0.6;@media (max-width: @max1) {width: 20 / @remScale;height: 10 / @remScale;}}}.cover_image {width: 100%;height: 100%;white-space: normal;object-fit: cover;@media (max-width: @max1) {width: 52 / @remScale;height: 52 / @remScale;margin-right: 10 / @remScale;white-space: normal;object-fit: cover;}}&:first-child {margin-left: 20 / @remScale;}}}}.image-container {display: flex;justify-content: center;align-items: center;margin-bottom: 8%;position: relative;width: 100%;.nav-buttons {position: absolute;width: 100%;top: 50%;transform: translateY(-50%);display: flex;justify-content: space-between;padding: 0 46 / @remScale;color: #ffff;font-size: 20 / @remScale;z-index: 99;@media (max-width: @max1) {padding: 0 5 / @remScale;}.re-icon-root {width: 28 / @remScale;height: 28 / @remScale;@media (max-width: @max1) {width: 15 / @remScale;height: 15 / @remScale;}}.prev-button {cursor: pointer;width: 60 / @remScale;height: 60 / @remScale;background: rgba(153, 153, 153, 0.4);backdrop-filter: blur(1 / @remScale);border-radius: 50%;text-align: center;line-height: 60 / @remScale;color: #ffff;@media (max-width: @max1) {width: 30 / @remScale;height: 30 / @remScale;line-height: 30 / @remScale;}}.next-button {cursor: pointer;width: 60 / @remScale;height: 60 / @remScale;background: rgba(153, 153, 153, 0.4);backdrop-filter: blur(1 / @remScale);line-height: 60 / @remScale;border-radius: 50%;text-align: center;@media (max-width: @max1) {width: 30 / @remScale;height: 30 / @remScale;line-height: 30 / @remScale;}}}.image_page {width: 72%;height: 730 / @remScale;position: relative;@media (max-width: @max1) {width: 15rem;}.video_page{ width: 100%;height: 100%;object-fit: contain;@media (max-width: @max1) { height: 90%;}}.cover {width: 100%;height: 100%;object-fit: contain;}.index_Page {position: absolute;bottom: 0;right: 0%;width: 58 / @remScale;height: 29 / @remScale;background: rgba(0, 0, 0, 0.4);backdrop-filter: blur(1 / @remScale);color: #fff;text-align: center;line-height: 29 / @remScale;@media (max-width: @max1) {right: 50%;bottom: 20%;transform: translateX(50%);}}}}
}

更多推荐

前端组件

本文发布于:2024-02-12 19:56:06,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1689200.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:组件

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!