npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-img-waterfall

v1.1.0

Published

按需懒加载的React图片瀑布流

Downloads

30

Readme

react-img-waterfall

按需懒加载的React图片瀑布流

GitHub stars npm version

特性

  • 约定传入img标签
  • 无需提前传入图片高度
  • 自适应图片大小
  • 按需加载图片
  • 自定义并发加载数量
  • 缓冲高度
  • 支持异步更新数据源

react-img-waterfall

demo

使用

npm i react-img-waterfall

⚠️重要

约定:传入img标签,并赋予src属性

图片插入第几列,由获取到的图片高度计算得到

      <Waterfall>
        {source.map((url, i) => (
          <img src={url} key={i} />
        ))}
      </Waterfall>

约定:img标签可嵌套在其他节点内,但需唯一

如果子节点中包含多个img标签,只取深度优先第一个获取到的img高度,很可能导致高度计算不准确,插入位置错乱的情况

      <Waterfall>
        {source.map((url, i) => (
          <div className="item">
            <img src={url} key={i} />
            <div>others</div>
          </div>
        ))}
      </Waterfall>

❌ 避免多个img标签

    <Waterfall>
      {source.map((url, i) => (
        <div className="item">
          <img src={url} key={i} />
          <div>
            {/* ❌避免一个item中出现多个img标签 */}
            <img src={url2} key={i} />
          </div>
        </div>
      ))}
    </Waterfall>

异步加载数据

目前只处理向后追加图片数据,向前更新数据不支持

import { Random } from 'mockjs';
import React, { useEffect, useState } from 'react';
import Waterfall from "react-img-waterfall";

const randomImg = () => {
  return Array(20)
    .fill('')
    .map((_, i) =>
      Random.image(`${Math.floor(Math.random() * 200)}x${Math.floor(Math.random() * 50)}`, `#FF6600&text=${i + 1}`)
    );
};

export default function App() {
  const [source, setSource] = useState<string[]>(randomImg());

  const push = () => {
    setSource(s => [...s, Random.image(`200x200`, '#FF0000')]);
  };

  return (
      <Waterfall wrapClass="container" col={3} onComplete={push}>
        {source.map((url, i) => (
          <img src={url} key={i} alt={url} />
        ))}
      </Waterfall>
  );
}

更新数据(重新计算)

适用于翻页、向前追加数据等情况 在数据源更新后,调用ref.current.reload(),组件将从新计算整个source(key未变时会从缓存中读取)

import { Random } from 'mockjs';
import React, { useEffect, useState } from 'react';
import Waterfall from "react-img-waterfall";

const randomImg = () => {
  return Array(20)
    .fill('')
    .map((_, i) =>
      Random.image(`${Math.floor(Math.random() * 200)}x${Math.floor(Math.random() * 50)}`, `#FF6600&text=${i + 1}`)
    );
};

export default function App() {
  const [source, setSource] = useState<string[]>(randomImg());
  const ref = React.useRef<any>();

  const change = () => {
    setSource(randomImg());
    ref.current.reload();
  };

  return (
    <>
      <button onClick={change}>change</button>
      <Waterfall wrapClass="container" col={3} ref={ref}>
        {source.map((url, i) => (
          <img src={url} key={i} alt={url} />
        ))}
      </Waterfall>
    </>
  );
}

props

| prop | 类型 | 默认 | 必要 | 描述 | | --------------- | -------------- | ---- | ----- | -------------------- | | children | - | - | true | - | | col | number | 3 | false | 列数 | | width | number | 200 | false | item宽度 | | marginH | number | 10 | false | 列左右间隙 | | marginV | number | 10 | false | item上下间隙 | | bufferHeight | number | 0 | false | 缓冲高度 | | wrapClass | string | - | false | 容器class | | concurrent | number | 10 | false | 图片加载并发数量 | | extraItemHeight | number | 0 | false | item额外参与计算高度 | | onScroll | Function | - | false | 容器滚动事件 | | onComplete | Function | - | false | 加载完成 |

width

统一宽度,会为每项item设置此宽度,item的高度无需设置

图片加载后会自适应此宽度,默认为objectFit:'contain'

如需修改适应方式,直接在img标签中修改即可

      <Waterfall width={500}>
        {source.map((url, i) => (
          // 每个item的宽度都会设置为500
          <div className="item">
            <img src={url} key={i} />
            <div>others</div>
          </div>
        ))}
      </Waterfall>

concurrent

并发数量,即图片一次性加载数量

例如concurrent={10},则图片一次性加载10张,随着向下滚动,触发后续加载,则再次加载10张

bufferHeight

缓冲高度,组件首次会一次性加载concurrent张,如果未超过容器高度+缓冲高度,则会立刻再次加载concurrent

extraItemHeight

额外高度,item默认为img图片提供的高度

item高度 = 图片高度 + extraItemHeight

不传入extraItemHeight一般不会造成插入顺序的错误,但可能会引起高度计算问题,导致滚动触发加载不准确

      <Waterfall extraItemHeight={20}>
        {source.map((url, i) => (
          <div className="item">
            <img src={url} key={i} />
            <div style={{ height: '20px' }}>others</div>
          </div>
        ))}
      </Waterfall>