欢迎大家来到IT世界,在知识的湖畔探索吧!
最近项目里有瀑布流的需求,本来打算使用现有轮子的,后来发现在兼容大小屏时样式会出现错乱,因此决定手动实现一个。以下一个简单的demo。(完整代码可已查看next-demo: next-demo – Gitee.com)
欢迎大家来到IT世界,在知识的湖畔探索吧!
如上图所示,瀑布流实现的核心逻辑主要是根据容器宽度,排列数,自动计算图片宽度,然后计算各个图片的绝对定位位置。
技术要点
- 获取容器宽度,确定大小屏时图片的排列数(小屏2列,中屏3列,大屏4,超大屏5.。。)
- 根据容器宽度和列数计算出每项的宽度
- 根据每项宽度,使用New image计算出每个图片的宽高
- 将容器相对定位,每项绝对定位
- 计算每项绝对定位(left和top)
- 计算绝对定位时需要将每项的额外距离计算在内(padding,margin,border)
- 根据定位信息进行页面布局
代码实现
- 获取每项宽度
const getColumnWidth = (node: HTMLElement, gap = 20) => { let COLUMN_COUNT = 2; if (node.clientWidth > 968 && node.clientWidth <= 1200) { COLUMN_COUNT = 3; } else if (node.clientWidth > 1200 && node.clientWidth <= 1400) { COLUMN_COUNT = 4; } else if (node.clientWidth > 1400 && node.clientWidth <= 1600) { COLUMN_COUNT = 5; } else if (node.clientWidth > 1600) { COLUMN_COUNT = 6; } return { column: COLUMN_COUNT, columnWidth: Math.floor((node.clientWidth - gap * (COLUMN_COUNT - 1)) / COLUMN_COUNT), } }
欢迎大家来到IT世界,在知识的湖畔探索吧!
- 根据列宽计算出渲染尺寸宽高
欢迎大家来到IT世界,在知识的湖畔探索吧!const loadImage = async (url: string, width: number) => { const img = new Image(); img.src = url; await new Promise(res => img.onload = res); return { w: width, h: Math.floor((img.naturalHeight / img.naturalWidth) * width), src: img.src, }; };
- 计算每项的绝对定位
const calculatePositions = (data:any[]) => { const newPositions: Iposition[] = []; const tempHeights = [...columnHeights.current]; data.forEach((img,index:number) => { // 计算元素高度 const elementHeight = img.h + (ITEM_PADDING * 2) + (BORDER_WIDTH * 2) + 20; // 找到最小高度列 const minHeight = Math.min(...tempHeights); const columnIndex = tempHeights.indexOf(minHeight); // 计算位置 newPositions.push({ left: columnIndex * (columns.columnWidth + GAP), top: minHeight }); // 更新列高度(图片高度 + 间距) tempHeights[columnIndex] += elementHeight + GAP; }); columnHeights.current = tempHeights; setPositions([...newPositions]); }
- 完整的代码可查看 next-demo: next-demo – Gitee.com
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/127594.html