react-medium-image-zoom
    TypeScript icon, indicating that this package has built-in type declarations

    4.3.5 • Public • Published

    react-medium-image-zoom

    All Contributors npm version npm downloads bundlephobia size Coverage Status

    This library is a React.js implementation of Medium.com's image zoom that allows for images to work together for a “zooming” effect and works regardless of parent elements that have overflow: hidden or parents with transform properties.

    As an added bonus, it will let you zoom anything (see the Storybook Examples for more).

    Blog post announcing v4

    Links

    Installation

    npm i react-medium-image-zoom

    or

    yarn add react-medium-image-zoom

    or

    <!-- this build only needs React to be already present -->
    <script src="https://unpkg.com/react-medium-image-zoom"></script>

    Basic Usage

    Uncontrolled component (default)

    Import the component and the CSS, wrap whatever you want to be "zoomable" with this component, and the component will handle it's own state:

    import React from 'react'
    import Zoom from 'react-medium-image-zoom'
    import 'react-medium-image-zoom/dist/styles.css'
    
    const MyComponent = () => (
      <Zoom>
        <img
          alt="that wanaka tree"
          src="/path/to/thatwanakatree.jpg"
          width="500"
        />
      </Zoom>
    )
    
    export default MyComponent

    You can zoom anything, so <picture>, <figure>, and even <div> elements are all valid:

    // <picture>
    <Zoom>
      <picture>
        <source media="(max-width: 800px)" srcSet="/path/to/teAraiPoint.jpg" />
        <img
          alt="that wanaka tree"
          src="/path/to/thatwanakatree.jpg"
          width="500"
        />
      </picture>
    </Zoom>
    
    // <figure>
    <figure>
      <Zoom>
        <img
          alt="that wanaka tree"
          src="/path/to/thatwanakatree.jpg"
          width="500"
        />
      </Zoom>
      <figcaption>That Wanaka Tree</figcaption>
    </figure>
    
    // <div> that looks like a circle
    <Zoom>
      <div
        aria-label="A blue circle"
        style={{
          width: 300,
          height: 300,
          borderRadius: '50%',
          backgroundColor: '#0099ff'
        }}
      />
    </Zoom>

    Controlled component (Controlled)

    Import the Controlled component and the CSS, wrap whatever you want to be "zoomable" with this component and then dictate the zoomed/unzoomed state to the component. Here, we will automatically zoom the component once the image has loaded:

    import React, { useCallback, useState } from 'react'
    import { Controlled as ControlledZoom } from 'react-medium-image-zoom'
    import 'react-medium-image-zoom/dist/styles.css'
    
    const MyComponent = () => {
      const [isZoomed, setIsZoomed] = useState(false)
    
      const handleImgLoad = useCallback(() => {
        setIsZoomed(true)
      }, [])
    
      const handleZoomChange = useCallback(shouldZoom => {
        setIsZoomed(shouldZoom)
      }, [])
    
      return (
        <ControlledZoom isZoomed={isZoomed} onZoomChange={handleZoomChange}>
          <img
            alt="that wanaka tree"
            onLoad={handleImgLoad}
            src="/path/to/thatwanakatree.jpg"
            width="500"
          />
        </ControlledZoom>
      )
    )
    
    export default MyComponent

    The onZoomChange prop accepts a callback that will receive true or false based on events that occur (like click or scroll events) to assist you in determining when to zoom and unzoom the component.

    There is also an example in the Storybook Examples of how to use a Controlled component to create a full-screen slideshow gallery.

    API

    Both uncontrolled & controlled components

    You can pass these options to either the default or controlled components.

    Prop Type Required Default Details
    closeText String no 'Unzoom Image' Accessible label text for when you want to unzoom
    openText String no 'Zoom Image' Accessible label text for when you want to zoom
    overlayBgColorEnd String no 'rgba(255, 255, 255, 0.95)' Modal overlay background color at end of zoom
    overlayBgColorStart String no 'rgba(255, 255, 255, 0)' Modal overlay background color at start of zoom
    portalEl Element no document.body DOM Element to which we will append the zoom modal
    scrollableEl Window no window DOM Element to which we will listen for scroll events to determine if we should unzoom
    transitionDuration Number no 300 Transition duration in milliseconds for the component to use on zoom and unzoom. Set this to 0 to disable the animation
    wrapElement String no 'div' Wrapper element
    wrapStyle Object no null Optional style object to pass to the wrapper element. Useful when you want the <Zoom> container to be width: '100%', for example
    zoomMargin Number no 0 Offset in pixels the zoomed image should be from the window' boundaries
    zoomZindex Number no 2147483647 z-index value for the zoom overlay

    Only the controlled component

    You can pass these options to only the controlled component.

    Prop Type Required Default Details
    isZoomed bool yes false Tell the component whether or not it should be zoomed
    onZoomChange Function no Function.prototype Listen for hints from the component about when you should zoom (true value) or unzoom (false value)

    Migrating From v3 to v4

    In v3, you might have code like this:

    <ImageZoom
      image={{
        src: '/path/to/bridge.jpg',
        alt: 'Golden Gate Bridge',
        className: 'img',
        style: { width: '50em' }
      }}
      zoomImage={{
        src: '/path/to/bridge-big.jpg',
        alt: 'Golden Gate Bridge'
      }}
      zoomMargin={80}
    />

    In v3, you would pass properties for your normal image that would be zoomed, and you would pass an optional zoomImage that would be a higher quality image that would replace the original image when zoomed.

    The problem with v3 was that it tried to assume too many things about what it is you were trying to zoom, and this resulted in overly complex and near-unmaintainable code that had a number of bugs.

    In v4, you can zoom the bridge example above like this:

    <Zoom zoomMargin={40}>
      <img
        src="/path/to/bridge.jpg"
        alt="Golden Gate Bridge"
        className="img"
        style={{ width: '50em'}}
      />
    </Zoom>

    We've removed the zoomImage functionality (there is an issue for us to consider re-adding something like it), but as it was not a primary use case for many consumers, we opted to ship v4 without it.

    Please see the Controlled component (Controlled) section for further documentation regarding controlled components that used the isZoomed, onZoom, and onUnzoom properties.

    Contributors

    Thanks goes to these wonderful people (emoji key):


    Cameron Bothner

    💻 📖 🐛 💡 🤔 👀 ⚠️

    Jeremy Bini

    💻 🐛

    ismay

    🐛 🤔

    Rajit Singh

    🐛

    Roberto Saccon

    🐛

    wtfdaemon

    🐛

    Robert Pearce

    💻 💬 ⚠️ 🐛 💡 🎨 👀 🤔 📖

    Josh Sloat

    🐛 💻 💡 👀 🤔 📖 🎨 💬

    Aswin

    💬

    Alex Shelkovskiy

    🐛

    Adrian Bindiu

    🐛

    Kendall Buchanan

    🐛

    Kaycee

    💻

    Anuj

    🐛 💬

    Ludwig Frank

    🐛 💻

    LX

    🐛 🤔

    Rosen Tomov

    🐛

    Tom Moor

    💻 🐛

    Johan Preynat

    💻 🐛

    Rahul Gaba

    💻 🐛

    Spencer Davis

    💻 🤔 👀 🎨

    dnlnvl

    💻

    Sean King

    🤔

    Ben Hood

    🤔 🐛 💡 👀

    Navilan

    🤔

    13806

    🐛

    Akshay Kadam (A2K)

    🐛 🤔

    Jake Stewart

    🐛 🤔

    hhh

    🐛

    @davalapar

    🐛

    Sun Knudsen

    💻 🐛 🤔 💡 💬 👀 ⚠️ 📖

    Douglas Galdino

    💻 📖 🐛 🤔 💡 👀 ⚠️

    Mohammed Faragallah

    🐛 🤔 💡

    Youngrok Kim

    💻 🐛

    Nandhagopal Ezhilmaran

    🐛

    Mattia Astorino

    🐛

    Dan Wood

    📖

    Zachery C Gentry

    🐛

    xmflsct

    🐛

    This project follows the all-contributors specification. Contributions of any kind welcome!

    Install

    npm i react-medium-image-zoom

    DownloadsWeekly Downloads

    32,297

    Version

    4.3.5

    License

    BSD-3

    Unpacked Size

    155 kB

    Total Files

    33

    Last publish

    Collaborators

    • rpearce