svelte-medium-image-zoom Svelte Themes

Svelte Medium Image Zoom

The original medium.com-inspired image zooming library for Svelte.

svelte-medium-image-zoom

The original medium.com-inspired image zooming library for Svelte.
View the storybook examples to see various usages.

Features:

Requirements to know about:

  • <dialog> element (caniuse dialog)
  • ResizeObserver (caniuse ResizeObserver)
  • Package build target is ESNext. If you need to support older environments, run this package through your build system.

Quickstart

npm install --save svelte-medium-image-zoom
<script lang="ts">
  import Zoom from 'svelte-medium-image-zoom';
  import 'svelte-medium-image-zoom/dist/styles.css';
</script>

<Zoom>
  <img
    alt="That Wanaka Tree, New Zealand by Laura Smetsers"
    src="/media/andres-iga.jpg"
    width="500"
  />
</Zoom>

API

Note: component type props are rendered as snippets, check this for more.
example use

export interface ZoomProps {
  // Accessible label text for when you want to unzoom.
  // Default: 'Minimize image'
  a11y_name_button_unzoom?: string;

  // Accessible label text for when you want to zoom.
  // Default: 'Expand image'
  a11y_name_button_zoom?: string;

  // Your image (required).
  children: Snippet<[]>;

  // Custom CSS class to add to the unzoom and zoom buttons.
  class_button?: string;

  // Custom CSS class to add to the zoomed <dialog>.
  class_dialog?: string;

  // Transition duration for modal image and overlay elements.
  // Default: 300ms
  duration?: string | number;

  // Provide your own unzoom button icon.
  // Default: ICompress
  icon_unzoom?: Snippet<[]>;

  // Provide your own zoom button icon.
  // Default: IEnlarge
  icon_zoom?: Snippet<[]>;

  // Tell the component whether or not it should be zoomed.
  // Default: false
  is_zoomed?: boolean;

  // Listen for hints from the component about when you
  // should zoom (`true` value) or unzoom (`false` value).
  on_zoom_change?: (value: boolean) => void;

  // Specify what type of element should be used for
  // internal component usage. This is useful if the
  // image is inside a <p> or <button>, for example.
  // Default: 'div'
  wrap_element?: 'div' | 'span';

  // Provide your own custom modal content component.
  zoom_content?: Snippet<[{
    img: Snippet<[]>;
    button_unzoom: Snippet<[]>;
    modal_state: IModalState;
    handle_unzoom: () => void;
  }]>;

  // Offset in pixels the zoomed image should
  // be from the window's boundaries.
  // Default: 0
  zoom_margin?: number;
}

Basic Usage

Import the component and the CSS, wrap your image with the component, and the component will handle it's own state.

<script lang="ts">
  import Zoom from 'svelte-medium-image-zoom';
  import 'svelte-medium-image-zoom/dist/styles.css';
</script>

<!-- <img /> -->
<Zoom>
  <img
    alt="That Wanaka Tree, New Zealand by Laura Smetsers"
    src="/path/to/thatwanakatree.jpg"
    width="500"
  />
</Zoom>

<!-- <div> -->
<Zoom>
  <div
    aria-label="That Wanaka Tree, New Zealand by Laura Smetsers"
    role="img"
    class="div-img"
    style="
      background-color: #fff;
      background-image: url(/media/laura-smetsers.jpg);
      background-position: 50%;
      background-repeat: no-repeat;
      background-size: cover;
      width: 500px;
      height: 300px;
    "
  ></div>
</Zoom>

Controlled usage

Import the component and the CSS, wrap your image with the component, and then dictate the is_zoomed with on_zoom_change handler state to the component.

<script lang="ts">
  import Zoom from 'svelte-medium-image-zoom';
  import 'svelte-medium-image-zoom/dist/styles.css';

  let is_zoomed = $state(false);
</script>

<Zoom
  {is_zoomed}
  on_zoom_change={(z) => (is_zoomed = z)}
  wrap_element="span"
  zoom_margin={25}
>
  <img
    alt="That Wanaka Tree, New Zealand by Laura Smetsers"
    src="/path/to/thatwanakatree.jpg"
    width="500"
    decoding="async"
    loading="lazy"
  />
</Zoom>

The on_zoom_change 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.

Styles

You can import the default styles from svelte-medium-image-zoom/dist/styles.css and override the values from your code, or you can copy the styles.css file and alter it to your liking. The latter is the best option, given rems should be used instead of px to account for different default browser font sizes, and it's hard for a library to guess at what these values should be.

An example of customizing the transition duration, timing function, overlay background color, and unzoom button styles with :focus-visible can be found in this story: custom-modal-styles.

Custom zoom modal content

If you want to customize the zoomed modal experience with a caption, form, or other set of components, you can do so by providing a custom component to the zoom_content prop.

View the live example of custom zoom modal content.

Below is some example code that demonstrates how to use this feature.

<script lang="ts">
  import Zoom from 'svelte-medium-image-zoom';
  import 'svelte-medium-image-zoom/dist/styles.css';
</script>

<Zoom>
  {#snippet zoom_content({ img, button_unzoom, modal_state })}
    {@render button_unzoom()}
    <figure>
      {@render img()}
      <figcaption
        class="zoom-caption zoom-caption--bottom"
        class:zoom-caption--loaded={modal_state === 'LOADED'}
      >
        That Wanaka Tree, also known as the Wanaka Willow, is a willow tree located at the
        southern end of Lake Wānaka in the Otago region of New Zealand.
        <cite className="zoom-caption-cite">
          Wikipedia, <a
            className="zoom-caption-link"
            href="https://en.wikipedia.org/wiki/That_Wanaka_Tree"
          >
            That Wanaka Tree
          </a>
        </cite>
      </figcaption>
    </figure>
  {/snippet}
  <img
    alt="That Wanaka Tree, New Zealand by Laura Smetsers"
    src="/path/to/thatwanakatree.jpg"
    width="500"
    decoding="async"
    loading="lazy"
  />
</Zoom>

Credits

This project is inspired from rpearce's react-medium-image-zoom library.

Top categories

Loading Svelte Themes