当前位置: 首页 > news >正文

React 图片瀑布流

 思路:

根据浏览器宽度,确定列数,请求的图片列表数据是列数的10倍,按列数取数据渲染

Index.js:

import React from 'react'
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import { SinglePageHeader } from '../../../../../components/light'
import InfiniteScroll from 'react-infinite-scroll-component'
import { Divider, Skeleton } from 'antd'
import useList from './useList'
import LazyLoad from 'react-lazy-load'import './index.css'function Index(props) {const {dataSource,isHasMore,columnCount,handleSearch,handleImgDrawSameStyleClick,} = useList(props)return (<div className="m-ai-img-wrap-box"><div className={`m-ai-img-wrap-chat`}><SinglePageHeader title="AI绘画作品展示"></SinglePageHeader><div className="m-ai-img-list" id="scrollableDiv"><InfiniteScrolldataLength={dataSource.length}next={handleSearch}refreshFunction={() => handleSearch({ page: 1, isRefresh: true })}pullDownToRefreshpullDownToRefreshThreshold={50}pullDownToRefreshContent={<h3 style={{ textAlign: 'center' }}>&#8595; 下拉刷新</h3>}releaseToRefreshContent={<h3 style={{ textAlign: 'center' }}>&#8593; 释放刷新</h3>}hasMore={isHasMore}loader={<Skeletonavatarparagraph={{rows: 3,}}activeclassName="m-h5-lesson-play-skeleton"/>}endMessage={dataSource.length === 0 ? null : (<Divider plain>已经到底啦~</Divider>)}scrollableTarget="scrollableDiv"><div className="m-ai-img-list-inner">{Array.from({ length: columnCount }, () => '').map((item, index) => (<div className="m-ai-img-list-column" key={index}>{dataSource.filter((item, dataSourceIndex) =>dataSourceIndex % columnCount === index).map((item) => (<div key={item.imgUid}><LazyLoad className="m-ai-img-lazy-load"><imgsrc={item.imgUrlCdn}className="m-ai-img"alt="图片"onClick={() => handleImgDrawSameStyleClick(item)}></img></LazyLoad></div>))}</div>))}</div>{dataSource.length === 0 ? (<Skeletonavatarparagraph={{rows: 3,}}activeclassName="m-h5-lesson-play-skeleton"/>) : null}</InfiniteScroll></div></div></div>)
}const mapStateToProps = (state) => {return {collapsed: state.getIn(['light', 'collapsed']),isRNGotToken: state.getIn(['light', 'isRNGotToken']),}
}const mapDispatchToProps = (dispatch) => {return {onSetState(key, value) {dispatch({ type: 'SET_LIGHT_STATE', key, value })},onDispatch(action) {dispatch(action)},}
}export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Index))

useList.js:

import { useState, useEffect } from 'react'
import { Form } from 'antd'
import Api from '../../../../../api'
import { message } from 'antd'
import * as clipboard from 'clipboard-polyfill/text'export default function useList(props) {const [total, setTotal] = useState(10)const [current, setCurrent] = useState(1)let tempCount = Math.floor((window.innerWidth - 10) / 180)tempCount = Math.floor((window.innerWidth - (5 + tempCount * 5)) / 180)console.log('tempCount1', tempCount)//把dataSource和pageSize单独放在一起是为了避免切换pageSize时的bugconst [state, setState] = useState({dataSource: [],pageSize: tempCount * 10,})const [isHasMore, setIsHasMore] = useState(true)// eslint-disable-next-lineconst [username, setUsername] = useState(localStorage.getItem('username'))const [form] = Form.useForm()// eslint-disable-next-lineconst [initValues, setInitValues] = useState({})// eslint-disable-next-lineconst [columnCount, setColumnCount] = useState(tempCount)//搜索const handleSearch = ({page = current,pageSize = state.pageSize,isRefresh = false,} = {}) => {if (isRefresh) {setState({dataSource: [],pageSize: tempCount * 10,})}let searchData = { pageNum: page, pageSize }Api.h5.sdImgSearch(searchData).then((res) => {if (res.code === 200) {const { pageNum, pageSize, total } = res.datalet list = res.data.listif (isRefresh) {setState({dataSource: [...list],pageSize: res.data.pageSize,})} else {setState({dataSource: [...state.dataSource, ...list],pageSize: res.data.pageSize,})}setTotal(res.data.total)const currentTemp = res.data.pageNum + 1setCurrent(currentTemp)setIsHasMore(pageNum < Math.ceil(total / pageSize))}})}//添加或编辑const handleFinish = (values) => {console.log('Success:', values)Api.h5.exchangeCodeAppUse(values).then((res) => {if (res.code === 200) {message.success('恭喜您,兑换成功')//props.history.push('/h5/index/me')}})}//校验失败const handleFinishFailed = (errorInfo) => {console.log('Failed:', errorInfo)}//退出const handleQuit = () => {Api.light.userLogout().then((res) => {if (res.code === 200) {props.history.push('/h5/login')window.localStorage.removeItem('username')window.localStorage.removeItem('token')}})}//跳转const handleJumpPage = (path) => {// eslint-disable-next-lineprops.history.push(path)}const handleCopy = (text) => {clipboard.writeText(text).then(() => {message.success('复制成功')})}const handleImgDrawSameStyleClick = (item) => {console.log(item)props.history.push(`/single/home/sdSimple?modelId=${item.id}&name=${item.name}&link=${item.link}&imgUid=${item.imgUid}`)}useEffect(() => {if (window.platform === 'rn') {if (props.isRNGotToken === true) {handleSearch()}} else {handleSearch()}// eslint-disable-next-line}, [props.isRNGotToken])return {username,form,initValues,dataSource: state.dataSource,total,current,pageSize: state.pageSize,isHasMore,columnCount,handleFinish,handleFinishFailed,handleQuit,handleJumpPage,handleCopy,handleSearch,handleImgDrawSameStyleClick,}
}

index.css:

.m-ai-img-wrap-box{display: flex;justify-content: center;background: #ddd;background: #ddd;position: absolute;top: 0;left: 0;right: 0;bottom: 0;overflow: hidden;}
.m-ai-img-wrap-chat{position: relative; display: flex;flex-direction: column;width: 100%;background: #ededed;}
.m-ai-img-main{flex:1;display: flex;flex-direction: column;overflow-y: auto;}
.m-ai-img-list{flex: 1;padding: 0px 0;overflow-y: auto;}
.m-ai-img-list-inner{position: relative;padding: 0 0 0 5px; display: flex; flex-wrap: wrap;justify-content: center;}
.m-ai-img-list-column{display: flex;flex-direction: column;width: 175px;margin: 0 5px 0 0;}
.m-ai-img-lazy-load{position: relative;min-width: 175px; display: flex;flex-direction: column;justify-content: center; min-height: 175px;margin: 0 0 5px 0;border-radius: 5px; background: #dddddd;}
.m-ai-img{width: 175px;border-radius: 5px;}

效果图:

参考链接:

https://chat.xutongbao.top/

相关文章:

React 图片瀑布流

思路&#xff1a; 根据浏览器宽度&#xff0c;确定列数&#xff0c;请求的图片列表数据是列数的10倍&#xff0c;按列数取数据渲染 Index.js: import React from react import { connect } from react-redux import { withRouter } from react-router-dom import { SinglePag…...

C++数据结构X篇_21_插入排序(稳定的排序)

文章目录 1. 插入排序原理2. 算法图解3. 核心代码&#xff1a;4. 插入排序整体代码实现 1. 插入排序原理 插入排序是一种最简单直观的排序算法&#xff0c;它的工作原理是通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相…...

【Unity】3D跑酷游戏

展示 finish_all * 方块跑酷 1.教程链接 翻墙&#xff1a;https://www.youtube.com/watch?v9ZEu_I-ido4&listPLPV2KyIb3jR53Jce9hP7G5xC4O9AgnOuL&index3 2.基础制作 最终成果 2.1 基本场景 1.创建Cube作为跑道 1&#xff09;记得把位置Reset&#xff1b; 2&#…...

bp前端验证码绕过及token绕过

前端验证码绕过及token绕过 原文参考&#xff1a;xiu 文章目录 前端验证码绕过及token绕过原文参考&#xff1a;[xiu](http://www.xiusafe.com/2023/10/25/%E9%AA%8C%E8%AF%81%E7%A0%81%E7%BB%95%E8%BF%87/)1 验证码爆破1. 登录Pikachu&#xff0c;先获取登录的api接口2 验证码…...

Jmeter(十四):跨线程组传递jmeter变量及cookie的处理详解

setUp线程组 setUp thread group 一种特殊类型的线程组&#xff0c;用于在执行常规线程组之前执行一些必要的操作。 在 setup线程组下提到的线程行为与普通线程组完全相同。不同的是执行顺序--- 它会在普通线程组执行之前被触发&#xff1b; 应用场景举例&#xff1a; A、测…...

css实现圆形进度条

能用现成组件就用&#xff0c;实现不行再自己写&#xff0c;因为牵扯到上传文件&#xff0c;进度实时出不来&#xff0c;所以只能使用dom元素操作&#xff1b; 1.实现 效果&#xff1a; 上图是100%&#xff0c;如果需要根据百分比显示&#xff0c;我们需要看下代码里面left和…...

适用于 Windows 10 和 Windows 11 设备的笔记本电脑管理软件

便携式计算机管理软件使 IT 管理员能够简化企业中使用的便携式计算机的部署和管理&#xff0c;当今大多数员工使用Windows 笔记本电脑作为他们的主要工作机器&#xff0c;他们确实已成为几乎每个组织不可或缺的一部分。由于与台式机相比&#xff0c;笔记本电脑足够便携&#xf…...

YOLOv5论文作图教程(1)— 软件介绍及下载安装(包括软件包+下载安装详细步骤)

前言:Hello大家好,我是小哥谈。在学习YOLOv5算法的过程中,很多同学都有发表论文的需求。作为文章内容的支撑,图表是最直接的整合数据的工具,能够更清晰地反映出研究对象的结果、流程或趋势。在发表论文的时候,审稿人除了关注论文的内容和排版外,也会审核图表是否清晰美观…...

AutoCAD 2024 Mac中文附激活补丁 兼容M1.M2电脑

AutoCAD 2024是一款功能强大的CAD设计绘图工具&#xff0c;旨在帮助用户创建和编辑高质量的设计图纸和模型。该软件支持2D和3D设计&#xff0c;具有丰富的功能和工具&#xff0c;可用于绘图、建模、注释、标注、尺寸设置等多种操作。AutoCAD 2024还引入了智能对象捕捉、实时预览…...

Jmeter基础---while控制器举例说明

一、 While 控制器 首先创建一个While Controller (While 循环控制器) ​​ 设置界面如下&#xff1a; Condition (function or variable) &#xff1a;条件说明 条件为 Flase 的时候&#xff0c;才会跳出 While 循环&#xff0c;否则一直执行 While 控制器下的样例 1、不填…...

正点原子嵌入式linux驱动开发——RGB转HDMI

目前大多数的显示器都提供了HDMI接口&#xff0c;HDMI的应用范围也越来越广&#xff0c;但是STM32MP157这颗芯片原生并不支持HDMI显示。可以通过RGB转HDMI芯片将RGB信号转为HDMI信号&#xff0c;这样就可以连接HDMI显示器了。本章就来学习一下如何在正点原子的STM32MP1开发板上…...

前端时间分片渲染

在经典的面试题中&#xff1a;”如果后端返回了十万条数据要你插入到页面中&#xff0c;你会怎么处理&#xff1f;” 除了像 useVirtualList 这样的虚拟列表来处理外&#xff0c;我们还可以通过 时间分片 来处理 通过 setTimeout 直接上一个例子&#xff1a; <!--* Autho…...

亿图导出word和PDF中清晰度保留方法

步骤一 在亿图软件中画一个元件大小搭配合理的图。注意字体大小的安排&#xff0c;尤其是角标的大小要合适&#xff0c;示范如下 选中所有元器件&#xff0c;右键使用组合功能将电路图组合为一个整体 步骤二&#xff1a; 将亿图软件中的图保存为SVG格式。示范如下 在导出到…...

chatGPT结构及商业级相似模型应用调研

GPT前言 说明 ChatGPT这项技术的历史可以追溯到2018年&#xff0c;当时由Facebook实验室的团队开发出该技术&#xff0c;以开发聊天机器人为目的。随后&#xff0c;ChatGPT在2019年由来自谷歌的DeepMind团队在国际会议ICLR上发表了论文&#xff0c;其中提出了ChatGPT的技术框架…...

HarmonyOS鸿蒙原生应用开发设计- 华为分享图标

HarmonyOS设计文档中&#xff0c;为大家提供了独特的华为分享图标&#xff0c;开发者可以根据需要直接引用。 开发者直接使用官方提供的华为分享图标内容&#xff0c;既可以符合HarmonyOS原生应用的开发上架运营规范&#xff0c;又可以防止使用别人的内容产生的侵权意外情况等&…...

Java基础-反射

代理相关 为什么需要代理&#xff1f; 代理可以无侵入式的对方法进行增强&#xff0c;而不需要修改原始方法的代码&#xff0c;这样就可以在不修改原始方法的情况下&#xff0c;对方法进行增强。 代理长什么样子&#xff1f; 代理里面就是对象要被代理的方法 Java通过什么方式…...

计算机毕设 大数据二手房数据爬取与分析可视化 -python 数据分析 可视化

# 1 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通…...

【转载】 Bytedance火山引擎智能拥塞控制算法 VICC

BytedanceTechBlog : 火山引擎实时、低延时拥塞控制算法的优化实践 火山引擎 网站如何利用播放器节省20%点播成本点击下面的链接进入原文:原创 翟强俊、唐辉 字节跳动技术团队 2023-10-18 11:59 发表于北京 一些专利摘要 火山引擎智能拥塞控制算法 VICC(Volcano Intelligent…...

Postman如何测试WebService接口

前言: 由于工作所需,需要使用Postman测试工具,对基于ws规范的WebService接口进行测试.在经过多种尝试后,终于找到了正确的测试方法.下面我便详细记录测试步骤,以便以后再次测试时可以拿来主义. 第一步:确保WebService服务端正常启动(注意服务端各个接口发布的url地址) 第二步…...

微服务-Eureka

文章目录 提供者与消费者Eureka注册中心搭建EurekaServer服务注册服务发现项目结构 提供者与消费者 Eureka注册中心 服务消费者该如何获取服务提供者的地址信息&#xff1f; 服务提供者启动时向eureka注册自己的信息 eureka保存这些信息 消费者根据服务名称向eureka拉取提供者信…...

【独家首发】Python扩展安全成熟度模型(PESMM v1.2):覆盖编译期/加载期/运行期的9维评分体系,仅限前500名开发者免费获取评估工具包

第一章&#xff1a;Python扩展模块安全概述Python 扩展模块&#xff08;如 C/C 编写的 .so/.dll 文件或 Cython 生成的二进制模块&#xff09;在提升性能的同时&#xff0c;也引入了原生层特有的安全风险。与纯 Python 代码不同&#xff0c;扩展模块直接操作内存、调用系统 API…...

WebGLInput:重构Unity WebGL输入体验的革命性方案

WebGLInput&#xff1a;重构Unity WebGL输入体验的革命性方案 【免费下载链接】WebGLInput IME for Unity WebGL 项目地址: https://gitcode.com/gh_mirrors/we/WebGLInput 在Unity WebGL开发中&#xff0c;输入法支持一直是开发者面临的核心挑战之一。WebGLInput项目通…...

1Panel新手必看:5分钟搞定RustDesk远程桌面搭建(含端口配置避坑指南)

1Panel极速部署RustDesk&#xff1a;零基础构建安全远程桌面的完整指南 当我们需要远程管理Linux服务器时&#xff0c;一个轻量级、开源的远程桌面解决方案往往比商业软件更灵活可控。RustDesk作为新兴的远程工具&#xff0c;凭借其跨平台特性和自建服务器的能力&#xff0c;正…...

抖音视频批量下载效率革命:解放双手的douyin-downloader全攻略

抖音视频批量下载效率革命&#xff1a;解放双手的douyin-downloader全攻略 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 作为内容创作者&#xff0c;你是否曾为收集行业素材而重复点击下载按钮&#xff1f…...

为什么你的Mojo-Python FFI在M1芯片上必崩?苹果Silicon专属ABI陷阱与跨架构符号绑定修复指南(含Clang插件源码)

第一章&#xff1a;为什么你的Mojo-Python FFI在M1芯片上必崩&#xff1f;Mojo-Python FFI&#xff08;Foreign Function Interface&#xff09;在 Apple M1 及后续 ARM64 架构芯片上崩溃&#xff0c;根源并非配置疏忽&#xff0c;而是底层 ABI 不兼容与运行时符号解析机制的双…...

PETRV2-BEV模型的高精度3D车道检测效果展示

PETRV2-BEV模型的高精度3D车道检测效果展示 1. 引言 想象一下&#xff0c;一辆自动驾驶汽车在复杂的城市道路中行驶&#xff0c;需要实时识别车道线、判断可行驶区域、预测周围车辆轨迹。这背后离不开一项关键技术——3D车道检测。传统的2D检测方法在复杂道路场景中往往力不从…...

OpCore-Simplify:让黑苹果配置从复杂到简单的智能化革命

OpCore-Simplify&#xff1a;让黑苹果配置从复杂到简单的智能化革命 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 你是否曾为黑苹果&#xff08;Hac…...

夜间自动化利器:OpenClaw+nanobot定时执行爬虫任务

夜间自动化利器&#xff1a;OpenClawnanobot定时执行爬虫任务 1. 为什么选择OpenClaw做夜间自动化 凌晨三点&#xff0c;我的电脑屏幕突然亮了起来。这不是灵异事件&#xff0c;而是OpenClaw正在执行我预设的爬虫任务——收集行业数据、清洗整理、存入数据库&#xff0c;整个…...

SGP30传感器数据不准?可能是你的I2C时序和初始化搞错了(避坑指南)

SGP30传感器数据异常排查指南&#xff1a;从硬件设计到软件调试的完整解决方案 1. 硬件设计中的常见陷阱与优化方案 SGP30作为一款高精度环境传感器&#xff0c;其硬件设计细节直接影响数据可靠性。许多开发者遇到的首要问题往往源于电路设计阶段被忽视的关键参数。 电源稳定性…...

FireRedASR-AED-L在软件测试中的应用:语音交互功能自动化测试

FireRedASR-AED-L在软件测试中的应用&#xff1a;语音交互功能自动化测试 你有没有想过&#xff0c;那些能听懂你说话的手机应用、智能音箱或者车载系统&#xff0c;它们的“听力”到底准不准&#xff1f;开发团队是怎么确保你每次说“播放音乐”或者“导航回家”&#xff0c;…...