npm package: @lylech/react-image-magnifier
Description: An image magnifier complete with thumbnail ribbon. Lightweight yet customizable.
Author: Lyle F. Chamarette
Latest version: 1.1.10

# @lylech/react-image-magnifier

A responsive image-magnifying Javascript component for mouse and touch, with integrated thumbnail ribbon, offering carousel like functionality. Suitable for photographs, e-commerce products, etc. Authored in raw Javascript with zero dependencies, this widget is easily integrated in Angular, React (examples and documentation provided), Vue and other JS frameworks.

Click/tap on a thumbnail to select an image into the magnification pane. Move the mouse/drag a finger over the magnification pane to zoom-in on and pan to the corresponding area of the selected image.

Appearance of the widget components may be stylized via your own CSS.

[![npm version](https://img.shields.io/npm/v/@lylech/react-image-magnifier?style=flat)](https://www.npmjs.com/package/@lylech/react-image-magnifier "View this project on npm")
[![npm downloads](https://img.shields.io/npm/dm/@lylech/react-image-magnifier.svg?style=flat-square)](https://www.npmjs.com/package/@lylech/react-image-magnifier)
[![MIT license](https://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)

## Interactive Demo Site

See the following for React examples and links to source code on Gitlab.
https://magnifier.glamarette.com

[<img src="https://gitlab.com/lylech/react-image-magnifier/-/raw/main/doc/showcase01.gif" alt="Magnifier component showcase example"/>](https://magnifier.glamarette.com)


## Installation

```sh
npm install --save @lylech/react-image-magnifier
```

## Basic Usage
You will have to, of course, provide your own images _```img1..img-n```_. This works great for images present on your system at build-time. For run-time, web based images are also supported as entries in ```arrayOfImagePaths```.

```JSX
//MyMagnifier.js
import React, { useRef, useEffect } from 'react';
import {RIMagnifier} from '@lylech/react-image-magnifier';
import img1 from "../img/img-01.jpeg";
import img2 from "../img/img-02.jpeg";
...
import img-n from "../img/img-n.jpeg";
...

export default function MyMagnifier() {
  const refMagnifier = useRef(null);

  const onThumbnailClick=(idxImage)=>{
    console.log("@ onThumbnailClick: Clicked on image# %o.", idxImage);
  };

  useEffect( ()=>{
    new RIMagnifier({
      container: refMagnifier.current,
      arrayOfImagePaths: [img1, img2, ... img-n],
      fnClickHandler: onThumbnailClick,
    });
  });
  return (
    <div className='react-image-magnifier' ref={refMagnifier} />
  )
}
```

## Parameters/Props
| Prop | Required | Default  | Description |
| :------------ |:---:|:---------------:| :-----|
| `container` | YES | | A reference to the HTML element in which this widget is to be dispayed.|
| `arrayOfImagePaths` | YES | | An array of source images. Local and Web based images are supported. |
| `arrayOfImageZoomFactors` | NO | 2 | The amount of zoom for each corresponding source image. |
| `fnClickHandler` | NO | | The function to be invoked on a click/tap of a _Thumbnail Tile_. The index of the selected image is passed as the only argument. |
| `initialSelection` | NO | 0 | The index of the image to be displayed initially. |

## Methods/Functions
| Method | Description |
| :------------ | :--------------- |
| `nextImage()` | Call this function to select the next thumbnail.
| `previousImage()` | Call this function to select the previous thumbnail.

## Controlling the Appearance
Certain aspects of the appearance may controlled by setting the class of the container element to one of the pre-defined styles, listed below. Further customizations may be applied via standard CSS.

| Class Name | Description |
| :------------ | :--------------- |
| `react-image-magnifier` | Default style and size. _Thumbnail Ribbon_ on the bottom edge.|

The position of the _Thumbnail Ribbon_ may be controlled by adding the appropriate class to the container(ref) element.

By default, the _Thumbnail Ribbon_ is positioned on the bottom edge. To alter this, apply one of the following pre-defined classes to the container element.

| Class Name | Description |
| :------------ | :--------------- |
| `ribbon-top` | _Thumbnail Ribbon_ on the top edge. |
| `ribbon-left` | _Thumbnail Ribbon_ on the left edge. |
| `ribbon-right` | _Thumbnail Ribbon_ on the right edge. |
| `ribbon-hide` | Does not display the _Thumbnail Ribbon_. |

# Details for the Technically Inclined
The design philosophy that drove the development of this widget:
- to offer an easy method for presenting a series of product images
- to offer an easy-to-use widget, with minimal fluff,
  - authored in vanilla Javascript, it is suitable for use in class or function components
  - with zero dependencies, it will not fall victim to a dependency update
  - easily integrates into any JS frameworks
- to favour rock-solid functionality for mouse and touch enabled devices,
- to favour CSS over JS when possible,
  - the browser is best suited to optimize DOM interactions
- to offer a full set of *__cosmetic customization options__*, or **_cosmetications_**.

In other words, that which it purports to do i.e. image magnification, it should do well, and for the rest i.e. _look pretty_, to allow users to _cosmeticate_ to their heart's content.

## Summary of `react-image-magnifier` Components:

Lean, unpretentious and authored in plain old Javascript, this widget supports a plethora of *cosmetications* that makes developing custom layouts a breeze, using standard CSS.

### Main View
The _Main View_ is composed of two parts - the _Magnification Pane_ and the _Thumbnail Ribbon_.

### Magnification Pane
Move the mouse into this area to zoom-in on the selected image. Move the mouse within this area to pan the zoomed image accordingly. Move the mouse outside this area to restore the image.

For touch devices, single tap in this area to zoom-in on the selected image. Drag within this area to pan the zoomed image. Tap outside this area to restore the image.

Zoom values may be specified on a per-image basis when invoking the constructor.

### Thumbnail Ribbon
Thumbnails of images available for selection are displayed in this area. Click or tap on a thumbnail to select it into the _Magnification Pane_.

Thumbnail images are generated automatically from the given images and sized to fit either the height or width of each thumbnail container so as to maintain the aspect ratio.

## Customizing the Appearance with CSS
This section identifies the CSS classes that control the appearance of the widget components. The default behaviour may be overridden by defining more specific CSS rules e.g. in your own CSS file, precede each rule with the (class name or ID of the) container.

Here is an illustration of the component CSS class structure:
<img src="https://gitlab.com/lylech/react-image-magnifier/-/raw/main/doc/MagnifierClasses.jpeg" alt="Magnifier component CSS class structure" width="800px"/>

### Main View
- **CSS Class:** <pre>div.lfc-rim-main</pre>
   -  By default, the _Main View_ occupies the entire width and height of its container.

### Magnification Pane
- **CSS Class**: <pre>div.lfc-rim-product</pre>
  - By default the _Magnification Pane_ occupies the entire width of the container and the top four-fifths height of the container.
  - ```.selected``` class is toggled when a new thumbnail is selected and is used to trigger an effect, animation or transition.

- **CSS Class**: <pre>div.lfc-rim-product-img</pre>
  - An ```<image/>``` element of the selected image. It may be _regular size_ or large when it is magnified. Note that _regular size_ is defined as that size required to fit either the height or width of the image within the container while maintaining the aspect ration.

### Thumbnail Ribbon
- **CSS Class**: <pre>.lfc-rim-thumbnails</pre>
  - By default the _Thumbnail Ribbon_ occupies entire width and the  bottom fifth of the container.
  - Scrolling thumbnails within the ribbon - as what we might expect from a gallery or carousel - is not presently supported.

### Thumbnail Tile
- **CSS Class**: <pre>.lfc-rim-thumbnail-outer --i:<i>n</i></pre>
  - This is a second-level container that wraps each thumbnail. It may prove useful when 'straightening' i.e. undoing rotations on the thumbnail image, after application of translation and rotation transformations which may otherwise leave the thumbnail rotated.
  - This element is also tagged with CSS variable ```--i``` with value _```n```_, so that the element may be individually referenced by CSS.
- **CSS Class**: <pre>lfc-rim-thumbnail</pre>
  - By default a _Thumbnail Tile_ is displayed for each provided image. In other words, the width of each tile varies according to the number of tiles required to occupy the full width of the container.
- **CSS Class**: <pre>lfc-rim-thumbnail.active</pre>
  - ```.active``` indicates the currently selected image.