@alekstar79/comparison-slider
v1.0.1
Published
A powerful, modern, and highly customizable TypeScript library that seamlessly combines an image comparison slider with a feature-rich image gallery.
Maintainers
Readme
✨ Comparison Slider TS
Comparison Slider TS is a powerful, modern, and highly customizable TypeScript library that seamlessly combines the functionality of an image comparison slider with a feature-rich image gallery. Built with TypeScript and a flexible plugin architecture, it's designed for performance, extensibility, and a superior user experience.
This is not just another before-and-after slider. It's a comprehensive toolkit for interactive image presentation, allowing you to compare, filter, magnify, and navigate through image sets with smooth, hardware-accelerated effects.
📖 Table of Contents
- ✨ Comparison Slider TS
🌟 Core Concepts
- Hybrid Engine: The library can function as a classic two-image comparison tool or as a multi-image gallery, or both at the same time. This is controlled by the
comparisonanddata-imgsetoptions. - Plugin-Driven Architecture: Core features like the magnifier, image set navigation, and panning are implemented as independent plugins. This keeps the core light and allows you to bundle only the functionality you need.
- Canvas Rendering: Instead of manipulating DOM elements, the library renders images onto an HTML5 Canvas. This enables high-performance pixel-level effects, transitions, and filtering that are impossible with standard
<img>tags. - Declarative and Imperative Configuration: Configure everything declaratively via
data-attributes in your HTML for simplicity, or use a detailed JavaScript object for maximum control and type safety.
🚀 Getting Started
Installation
Install the package from the npm registry:
npm install @alekstar79/comparison-slider
# or
yarn add @alekstar79/comparison-sliderImporting Styles
The library requires a core stylesheet and optional stylesheets for each plugin you use.
// Import core styles
import '@alekstar79/comparison-slider-ts/styles/core.css'
// Import styles for the plugins you are using
import '@alekstar79/comparison-slider-ts/styles/ImageSetPlugin.css'
import '@alekstar79/comparison-slider-ts/styles/MagnifierPlugin.css'
// ... and so on for other pluginsHTML Setup
The slider is initialized from a standard <img> element. The library will replace it with the full slider component.
<!-- Basic Usage -->
<img id="my-slider" src="images/before.jpg" alt="Before and After" />
<!-- Comparison Slider -->
<img
src="./images/l1.jpg"
class="slider-large"
data-comparison-slide
data-action-buttons="{ top: '50%', transform: 'translateY(-50%)', left: '10px' }"
data-features-buttons="{ top: '50%', transform: 'translateY(-50%)', right: '10px' }"
data-action-buttons-direction="vertical"
data-features-buttons-direction="vertical"
data-direction="vertical"
data-init-x="300"
data-init-y="150"
data-filters="all"
alt="Before and After"
>
<!-- Image Gallery Slider -->
<img
class="slider-large"
data-imgset="./images/img1.jpg,./images/img2.jpg,./images/img3.jpg,./images/img4.jpg"
data-comparison-slide
data-direction="vertical"
data-filters="all"
data-init-x="200"
data-init-y="300"
alt="My Awesome Gallery"
src=""
>Initialization
Import the ComparisonSlider class, create a new instance with your image element and a configuration object, and then call .mount().
import { ComparisonSlider, defaultConfig } from '@alekstar79/comparison-slider'
const imageElement = document.getElementById('my-slider')
// You can start with the defaultConfig and override properties
const myConfig = JSON.parse(JSON.stringify(defaultConfig))
myConfig.hoverToSlide = true
myConfig.magnifier.defaultZoom = 3
// Create and mount the slider
const slider = new ComparisonSlider(imageElement, myConfig)
slider.mount()⚙️ Configuration
You have two ways to configure the slider, which can be used together.
Via Object
This is the most powerful method, giving you access to all options with full type-safety if you're using TypeScript.
const slider = new ComparisonSlider(imageElement, {
...defaultConfig,
direction: 'vertical',
imageSet: {
...defaultConfig.imageSet,
autoplay: true,
}
})Via data- Attributes
For quick setup, most configuration options can be set directly in HTML. The library automatically parses these attributes.
Simple values:
data-direction="vertical"Nested values: Use kebab-case for nested properties.
data-image-set-autoplay="true"Complex objects: For properties that are objects (like UI block positions), pass a JavaScript-like object string.
<img id="my-slider" src="images/before.jpg" data-action-buttons="{ top: '50%', left: '1rem', transform: 'translateY(-50%)' }" data-nav-buttons-direction="vertical" alt="" />
Detailed Configuration Options
Below is a comprehensive list of all available options found in the defaultConfig.
| Property | Type | Default | data- Attribute | Description |
|:----------------------------|:------------|:---------------|:-----------------------------------|:-----------------------------------------------------------------------------------------------|
| comparison | boolean | true | data-comparison | Enables the core before/after comparison functionality. |
| hoverToSlide | boolean | false | data-hover-to-slide | If true, the handle follows the mouse without clicking. |
| direction | string | 'horizontal' | data-direction | Orientation of the slider: 'horizontal' or 'vertical'. |
| labels.before | string | 'Before' | data-labels-before | Text for the "before" label. |
| labels.after | string | 'After' | data-labels-after | Text for the "after" label. |
| labels.position | string | 'top-left' | data-labels-position | Position of the labels. |
| imageSet.autoplay | boolean | false | data-image-set-autoplay | Enables automatic transitioning between images in a set. |
| imageSet.interval | number | 5000 | data-image-set-interval | Time in milliseconds between transitions in autoplay mode. |
| imageSet.pauseOnHover | boolean | false | data-image-set-pause-on-hover | Pauses autoplay when the mouse is over the slider. |
| imageSet.cyclic | boolean | false | data-image-set-cyclic | Allows navigation to loop from the last image to the first. |
| imageSet.transitionEffect | string | 'slide' | data-image-set-transition-effect | The animation effect to use. See Transition Effects. |
| imageSet.duration | number | 1000 | data-image-set-duration | Duration of the transition effect in milliseconds. |
| magnifier.enabled | boolean | true | data-magnifier-enabled | Enables the magnifier plugin. |
| magnifier.size | number | 180 | data-magnifier-size | Diameter of the magnifier circle in pixels. |
| magnifier.defaultZoom | number | 2 | data-magnifier-default-zoom | The initial zoom level. |
| magnifier.zoomLevels | number[] | [2, 3, 4] | data-magnifier-zoom-levels | Array of available zoom levels in the panel. |
| uiBlocks | UIBlock[] | (array) | data-[block-id] | Defines the layout of UI elements. See SliderHtmlBuilder.ts. |
🔌 Plugins API
The plugin architecture is the heart of the library's extensibility. Each plugin is a class that hooks into the slider's lifecycle to add new functionality. They are initialized automatically by the main ComparisonSlider class.
ImageSetPlugin: Manages image galleries defined bydata-imgset. It handles navigation (next/prev), autoplay, and orchestrates the transition effects between images.MagnifierPlugin: Adds an interactive magnifying glass. It creates a separate canvas that follows the cursor, rendering a zoomed-in portion of the main canvas, including any applied filters and UI elements.FilterPlugin: Manages the filter selection UI. It dynamically adds/removes an "Original" filter button when switching between comparison and single-view modes and ensures the correct filter is applied.ImagePanPlugin: Automatically detects if the source image has a different aspect ratio than the container. If so, it enables panning by clicking and dragging on the image, allowing users to explore the entire image.SavePlugin: Adds a "Save" button. When clicked, it creates a new temporary canvas, redraws the current image with any active filters applied, and triggers a browser download of the resulting image.FullscreenPlugin: Provides a button to toggle the slider's container into and out of the browser's fullscreen mode.LabelPlugin: Manages the visibility and positioning of the "Before" and "After" labels, ensuring they are correctly clipped as the handle moves.
🎨 Transition Effects
When using the ImageSetPlugin, you can choose from several visually impressive transition effects.
| Effect | Description |
|:---------------|:-------------------------------------------------------------------------------------|
| slide | The new image slides in smoothly over the old one. |
| dissolve | A cross-fade effect where the old image dissolves into the new one. |
| blinds | The new image is revealed through a series of animated vertical or horizontal slats. |
| wipe | A classic directional wipe transition. |
| wave | A modern, GLSL-powered wave distortion effect that ripples across the image. |
👨💻 API Reference
While most functionality can be controlled via the configuration object, the ComparisonSlider instance provides several public methods for imperative control.
new ComparisonSlider(image, config)
Creates a new slider instance.
image: TheHTMLImageElementto enhance.config: A configuration object to override the defaults.
.mount()
Initializes all plugins, builds the required DOM structure, and replaces the original <img> element. This method is asynchronous and returns a Promise that resolves when the initial image is fully loaded and the slider is ready.
.updateImage(newImage, reset)
Updates the slider with a new source image.
newImage: AnHTMLImageElementor a URLstringfor the new image.reset: Aboolean(trueby default). Iftrue, resets the handle to its initial position.
.toggleComparisonView()
Programmatically toggles the comparison view on or off.
.use(plugin)
Registers a custom plugin with the slider instance. This allows for extending the slider with your own functionality.
🤝 Contributing
Contributions are highly welcome! If you find a bug, have a feature request, or want to improve the documentation, please open an issue or submit a pull request.
Development Setup
- Clone the repository.
- Install dependencies:
npm install - Start the development server:
npm run dev - Run tests:
npm test
📜 License
This project is licensed under the MIT License. See the LICENSE file for details.
