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

vision3000-react

v0.1.2

Published

LazyLoading for the New Millenium™

Downloads

3

Readme

(React)Vision3000

Vision3000 👁 LazyLoading for the new Millenium™ as a React component.

For more information about Vision3000 please head over to its README.

Demo

Click here! Try clicking around the navigation, scrolling fast, or using the scrollbar to scrub!

Usage

First add ReactVision3000 as one of your project's dependencies.

yarn add vision3000-react

Great! Then the next steps:

a) We import and initialize a Vision3000 observer b) Use the component for your observables! c) Get creative and profit.

Further details below–

First, in your index.js we initialize an instance of the Vision3000 observer.

  // index.js
  import React from 'react';
  import ReactDOM from 'react-dom';
  import App from './App';
  import { initVision3000 } from 'vision3000-react';

  // initialize! pow!
  initVision3000();

  ReactDOM.render(<App />, document.getElementById('root'));

Simple! Now we can use the component like so anywhere in your :sparkles:App:sparkles:

  // Somewhere in your app
  // Note: In this example we are using a css-in-js library (emotion)
  // More information about styling after "Usage"

  import React from 'react';
  import styled, { css } from 'react-emotion';

  // This is ReactVision right here!
  // Call it however you want, but for this example
  // we're calling it "ObservedImage", see usage below
  import ObservedImage from 'vision3000-react';


  class SomeComponent extends React.Component {
    render() {
      return (
        <main>
          <h1>OMG these images only load when you intend to!</h1>

          { myImageArray.map((image, index) => (
            <MyImageContainer key={`vision3k-${index}`}>
              <ObservedImage
                placeholder={image.placeholder}
                src={image.src}
                classNames={{
                  containerBase: styles.container,
                  containerLoading: styles.containerLoading,
                  containerLoaded: styles.containerLoaded,
                  imageBase: styles.image,
                  imageLoading: styles.imageLoading,
                  imageLoaded: styles.imageLoaded,
                }}
                onIntersect={this.onIntersect}
                onLoadStart={this.onLoadStart}
                onLoad={this.onLoad} />
            </MyImageContainer>
          )) }
        </main>
      )
    }
  }

  const MyImageContainer = styled('div')`
    // Your styling for container etc.
    // Remember, Vision3000 component is only composed of
    // a wrapper element <figure>, and the <img> itself
  `;


  export default SomeComponent;

OK so what's going on up there?

Breakdown

| Prop | Type | What it does | |--|--|--| | src | string (required) | the source image (to be loaded) | | placeholder | string | the placeholder image src | alt | string | your image alt attribute | onIntersect | function | called when an observed element enters the viewport | onLoadStart | function | called when a user "intended" to view an image when the source image is requested | onLoad | function | called when the image has finished loading, decoded and inserted into the DOM |classNames | object | an object containing the following keys corresponding to a className which applies to an image's state great for use with css-in-js libraries or if you're using css modules. See next section. | containerStyle / imageStyle | object | Should you choose to declare inline styles for each state, then you can pass an object with corresponding keys. See next section.

Note: onIntersect, onLoadStart and onLoad callbacks are exposed some variables see Callbacks section.

Styling

ReactVision3000 component renders the following DOM structure:

  <figure [class] [style]>
    <img [class] [style] data-src="" src="" alt="" />
  </figure>

There are two ways you may style the container element and the image: either by passing in a className or passing in inline styles, one for each "state".


Classnames

Should you choose to style the component via className, then you simple pass in an object within the classNames prop.

  <Vision3KComponent
    src="/highres.jpg"
    placeholder="/lowres.jpg"
    classNames={{
      containerBase: 'container',
      containerLoading: 'container--loading',
      containerLoaded: 'container--loaded',
      imageBase: 'container__image',
      imageLoading: 'container__image--loading',
      imageLoaded: 'container__image--loaded',
    }}
    onIntersect={foo}
    onLoadStart={bar}
    onLoad={baz} />

If you're using a css-in-js lib such as emotion or glamour, then you would pass in a variable or the css method itself that returns a generated classname.

  <Vision3KComponent
    src="/highres.jpg"
    placeholder="/lowres.jpg"
    classNames={{
      containerBase: styles.container,
      containerLoading: styles.containerLoading,
      containerLoaded: css`border: 1px solid red`,
      imageBase: styles.image,
      imageLoading: styles.imageLoading,
      imageLoaded: styles.imageLoaded,
    }}
    onIntersect={foo}
    onLoadStart={bar}
    onLoad={baz} />

// your styles object used above
const styles = {
  container: css`
    // your styles here
  `,
  // so on and so forth
}

Inline styles

If this is your flavour then you can also do so:

Note: we use a separate container/image style prop so we don't end up in a mess of nested objects. The style you pass in for each state is (as it is inline style) an object.

  <Vision3KComponent
    src="/highres.jpg"
    placeholder="/lowres.jpg"
    containerStyle={{
      base: {
        backgroundColor: 'blue',
      },
      loading: {},
      loaded: {},
    }}
    imageStyle={{
      base: {},
      loading: {},
      loaded: {},
    }}
    onIntersect={foo}
    onLoadStart={bar}
    onLoad={baz} />

That's pretty much all there is to it! Head on over to the demo to see it in action. Try clicking around the navigation, scrolling fast, or using the scrollbar to scrub!

Callbacks

onIntersect

called when an element enters the viewport. This is just the standard behaviour of intersectionObserver, this will fire regardless of intent. The method provides you back with the following:

| variable | what | |--|--| | inView | an Array of indices referring to which elements are in view. Useful for toggling classes. e.g. className={inView.includes[index] && 'viewing'} | | viewed | an Array of elements indices which have already been loaded. |

  onIntersect = (inView, viewed) => {
    this.setState({ inView });
  }

  // render()
  <Vision3KImage
    onIntersect={this.onIntersect} />

onLoadStart / onLoad

called when the user stops at a section and starts loading Vision3000 elements which are in view and when the element in view has finished loading the source image.

  onLoadStart = (elem, img, viewed) => {
    console.log(elem, img, viewed);
  }

  onLoad = (elem, img, viewed) => {
    console.log(elem, img, viewed);
  }

| variable | what | |--|--| | elem | [DOMNode] a reference to the container element of the <img>| | img | [DOMNode] a reference to the <img element itself | | viewed | an Array of elements indices which have already been loaded. |

P.S.

ReactVision3000 is available as a standalone vanilla module (Vision3000) which is a dependency of this component. You can also read more about it by clicking here.

P.P.S

Do you have any comments/suggestions? Would you like to improve REACTVISION3000? Please feel free to post issues, or open pull requests. I would love that. <3