js-cloudimage-before-after 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +305 -0
  3. package/dist/a11y/aria.d.ts +4 -0
  4. package/dist/a11y/keyboard.d.ts +22 -0
  5. package/dist/animation/entrance.d.ts +18 -0
  6. package/dist/core/ci-before-after.d.ts +64 -0
  7. package/dist/core/config.d.ts +3 -0
  8. package/dist/core/types.d.ts +127 -0
  9. package/dist/fullscreen/fullscreen.d.ts +16 -0
  10. package/dist/index.d.ts +10 -0
  11. package/dist/js-cloudimage-before-after.cjs.js +2 -0
  12. package/dist/js-cloudimage-before-after.cjs.js.map +1 -0
  13. package/dist/js-cloudimage-before-after.esm.js +1210 -0
  14. package/dist/js-cloudimage-before-after.esm.js.map +1 -0
  15. package/dist/js-cloudimage-before-after.min.js +2 -0
  16. package/dist/js-cloudimage-before-after.min.js.map +1 -0
  17. package/dist/labels/labels.d.ts +6 -0
  18. package/dist/react/ci-before-after-viewer.d.ts +3 -0
  19. package/dist/react/index.cjs +2 -0
  20. package/dist/react/index.cjs.map +1 -0
  21. package/dist/react/index.d.ts +3 -0
  22. package/dist/react/index.js +179 -0
  23. package/dist/react/index.js.map +1 -0
  24. package/dist/react/types.d.ts +11 -0
  25. package/dist/react/use-ci-before-after.d.ts +5 -0
  26. package/dist/slider/gestures.d.ts +31 -0
  27. package/dist/slider/handle.d.ts +2 -0
  28. package/dist/slider/slider.d.ts +11 -0
  29. package/dist/utils/cloudimage.d.ts +2 -0
  30. package/dist/utils/dom.d.ts +8 -0
  31. package/dist/utils/events.d.ts +12 -0
  32. package/dist/zoom/controls.d.ts +12 -0
  33. package/dist/zoom/gestures.d.ts +21 -0
  34. package/dist/zoom/scroll-hint.d.ts +7 -0
  35. package/dist/zoom/zoom-pan.d.ts +40 -0
  36. package/package.json +69 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Scaleflex
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,305 @@
1
+ <p align="center">
2
+ <img src="https://scaleflex.cloudimg.io/v7/plugins/js-cloudimage-360-view/logo_scaleflex_on_white_bg.jpg?vh=91b12d&w=700" alt="Scaleflex" width="350">
3
+ </p>
4
+
5
+ <h1 align="center">js-cloudimage-before-after</h1>
6
+
7
+ <p align="center">
8
+ Interactive before/after image comparison slider with zoom, labels, and accessibility. Zero dependencies.
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/js-cloudimage-before-after"><img src="https://img.shields.io/npm/v/js-cloudimage-before-after.svg?style=flat-square" alt="npm version"></a>
13
+ <a href="https://www.npmjs.com/package/js-cloudimage-before-after"><img src="https://img.shields.io/npm/dm/js-cloudimage-before-after.svg?style=flat-square" alt="npm downloads"></a>
14
+ <a href="https://github.com/scaleflex/js-cloudimage-before-after/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/js-cloudimage-before-after.svg?style=flat-square" alt="license"></a>
15
+ <a href="https://bundlephobia.com/package/js-cloudimage-before-after"><img src="https://img.shields.io/bundlephobia/minzip/js-cloudimage-before-after?style=flat-square" alt="bundle size"></a>
16
+ </p>
17
+
18
+ <p align="center">
19
+ <a href="https://scaleflex.github.io/js-cloudimage-before-after/">Live Demo</a> |
20
+ <a href="https://codesandbox.io/p/devbox/github/scaleflex/js-cloudimage-before-after/tree/main/examples/vanilla">Vanilla Sandbox</a> |
21
+ <a href="https://codesandbox.io/p/devbox/github/scaleflex/js-cloudimage-before-after/tree/main/examples/react">React Sandbox</a>
22
+ </p>
23
+
24
+ ---
25
+
26
+ ## Why js-cloudimage-before-after?
27
+
28
+ Existing before/after sliders are often rigid, inaccessible, or missing features like zoom and vertical orientation. This library was built to fill the gap:
29
+
30
+ - **Lightweight** — under 15 KB gzipped with zero runtime dependencies
31
+ - **Accessible by default** — WCAG 2.1 AA compliant out of the box
32
+ - **Framework-agnostic** — works with vanilla JS, React, or any framework
33
+ - **Built-in zoom & pan** — no need for a separate zoom library
34
+ - **Multiple interaction modes** — drag, hover, or click
35
+ - **Optional Cloudimage CDN** — serve optimally-sized images automatically
36
+
37
+ ---
38
+
39
+ ## Features
40
+
41
+ - **Three interaction modes** — Drag, hover, or click to reveal before/after
42
+ - **Horizontal & vertical** — Slider works in both orientations
43
+ - **Zoom & Pan** — CSS transform-based with mouse wheel, pinch-to-zoom, double-click, drag-to-pan
44
+ - **Handle styles** — Arrows, circle, or minimal line
45
+ - **Labels** — Customizable before/after labels with configurable position
46
+ - **Entrance animation** — Smooth slider animation on first view with configurable duration, delay, and easing
47
+ - **Fullscreen mode** — Built-in fullscreen toggle
48
+ - **WCAG 2.1 AA** — Full keyboard navigation, ARIA attributes, focus management, reduced motion
49
+ - **CSS variable theming** — Light and dark themes, fully customizable
50
+ - **Two init methods** — JavaScript API and HTML data-attributes
51
+ - **React wrapper** — Separate entry point with component, hook, and ref API
52
+ - **TypeScript** — Full type definitions
53
+ - **Cloudimage CDN** — Optional responsive image loading
54
+ - **Lazy loading** — IntersectionObserver-based image lazy loading
55
+
56
+ ## Installation
57
+
58
+ ```bash
59
+ npm install js-cloudimage-before-after
60
+ ```
61
+
62
+ ### CDN
63
+
64
+ ```html
65
+ <script src="https://scaleflex.cloudimg.io/v7/plugins/js-cloudimage-before-after/1.0.0/js-cloudimage-before-after.min.js?vh=ad6399&func=proxy"></script>
66
+ ```
67
+
68
+ ## Quick Start
69
+
70
+ ### JavaScript API
71
+
72
+ ```js
73
+ import CIBeforeAfter from 'js-cloudimage-before-after';
74
+
75
+ const viewer = new CIBeforeAfter('#slider', {
76
+ beforeSrc: 'https://example.com/kitchen-before.jpg',
77
+ afterSrc: 'https://example.com/kitchen-after.jpg',
78
+ beforeAlt: 'Kitchen before renovation',
79
+ afterAlt: 'Kitchen after renovation',
80
+ zoom: true,
81
+ labels: { before: 'Before', after: 'After' },
82
+ theme: 'light',
83
+ handleStyle: 'arrows',
84
+ animate: { duration: 800 },
85
+ onSlide(position) {
86
+ console.log('Position:', position);
87
+ },
88
+ });
89
+ ```
90
+
91
+ ### HTML Data-Attributes
92
+
93
+ ```html
94
+ <div
95
+ data-ci-before-after-before-src="https://example.com/before.jpg"
96
+ data-ci-before-after-after-src="https://example.com/after.jpg"
97
+ data-ci-before-after-before-alt="Before renovation"
98
+ data-ci-before-after-after-alt="After renovation"
99
+ data-ci-before-after-zoom="true"
100
+ data-ci-before-after-theme="light"
101
+ data-ci-before-after-handle-style="arrows"
102
+ data-ci-before-after-label-before="Before"
103
+ data-ci-before-after-label-after="After"
104
+ ></div>
105
+
106
+ <script>CIBeforeAfter.autoInit();</script>
107
+ ```
108
+
109
+ ## API Reference
110
+
111
+ ### Constructor
112
+
113
+ ```ts
114
+ new CIBeforeAfter(element: HTMLElement | string, config: CIBeforeAfterConfig)
115
+ ```
116
+
117
+ ### Config
118
+
119
+ | Option | Type | Default | Description |
120
+ |--------|------|---------|-------------|
121
+ | `beforeSrc` | `string` | — | Before image URL (required) |
122
+ | `afterSrc` | `string` | — | After image URL (required) |
123
+ | `beforeAlt` | `string` | `'Before'` | Before image alt text |
124
+ | `afterAlt` | `string` | `'After'` | After image alt text |
125
+ | `mode` | `'drag' \| 'hover' \| 'click'` | `'drag'` | Interaction mode |
126
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Slider direction |
127
+ | `initialPosition` | `number` | `50` | Starting position (0–100) |
128
+ | `handleStyle` | `'arrows' \| 'circle' \| 'line'` | `'arrows'` | Handle visual style |
129
+ | `labels` | `boolean \| { before?: string; after?: string }` | `true` | Show labels or custom text |
130
+ | `labelPosition` | `'top' \| 'bottom'` | `'top'` | Label placement |
131
+ | `theme` | `'light' \| 'dark'` | `'light'` | Color theme |
132
+ | `zoom` | `boolean` | `false` | Enable zoom & pan |
133
+ | `zoomMax` | `number` | `4` | Maximum zoom level |
134
+ | `zoomMin` | `number` | `1` | Minimum zoom level |
135
+ | `zoomControls` | `boolean` | `true` | Show zoom control buttons |
136
+ | `zoomControlsPosition` | `string` | `'bottom-right'` | Zoom controls position (`top-left`, `top-center`, `top-right`, `bottom-left`, `bottom-center`, `bottom-right`) |
137
+ | `scrollHint` | `boolean` | `true` | Show scroll hint when zoomed |
138
+ | `animate` | `boolean \| AnimateConfig` | `false` | Entrance animation |
139
+ | `animateOnce` | `boolean` | `true` | Animate only on first view |
140
+ | `fullscreenButton` | `boolean` | `true` | Show fullscreen button |
141
+ | `lazyLoad` | `boolean` | `true` | Lazy load images |
142
+ | `keyboardStep` | `number` | `1` | Arrow key step (%) |
143
+ | `keyboardLargeStep` | `number` | `10` | Shift+Arrow step (%) |
144
+ | `onSlide` | `(position: number) => void` | — | Position change callback |
145
+ | `onZoom` | `(level: number) => void` | — | Zoom change callback |
146
+ | `onFullscreenChange` | `(isFullscreen: boolean) => void` | — | Fullscreen callback |
147
+ | `onReady` | `() => void` | — | Ready callback |
148
+ | `cloudimage` | `CloudimageConfig` | — | Cloudimage CDN config |
149
+
150
+ ### AnimateConfig
151
+
152
+ | Option | Type | Default | Description |
153
+ |--------|------|---------|-------------|
154
+ | `duration` | `number` | `800` | Duration in ms |
155
+ | `delay` | `number` | `0` | Delay before start in ms |
156
+ | `easing` | `string` | `'ease-out'` | CSS easing function |
157
+
158
+ ### Instance Methods
159
+
160
+ ```ts
161
+ instance.setPosition(percent: number): void // Set slider position (0–100)
162
+ instance.getPosition(): number // Get current position
163
+ instance.setZoom(level: number): void // Set zoom level
164
+ instance.getZoom(): number // Get current zoom level
165
+ instance.resetZoom(): void // Reset zoom to 1×
166
+ instance.enterFullscreen(): void // Enter fullscreen
167
+ instance.exitFullscreen(): void // Exit fullscreen
168
+ instance.isFullscreen(): boolean // Check fullscreen state
169
+ instance.update(config: Partial<Config>): void // Update config
170
+ instance.destroy(): void // Destroy instance
171
+ instance.getElements(): Elements // Get DOM elements
172
+ ```
173
+
174
+ ### Static Methods
175
+
176
+ ```ts
177
+ CIBeforeAfter.autoInit(root?: HTMLElement): CIBeforeAfterInstance[]
178
+ ```
179
+
180
+ ## React Usage
181
+
182
+ ```tsx
183
+ import { CIBeforeAfterViewer, useCIBeforeAfter } from 'js-cloudimage-before-after/react';
184
+
185
+ // Component
186
+ function ImageComparison() {
187
+ return (
188
+ <CIBeforeAfterViewer
189
+ beforeSrc="/kitchen-before.jpg"
190
+ afterSrc="/kitchen-after.jpg"
191
+ beforeAlt="Kitchen before renovation"
192
+ afterAlt="Kitchen after renovation"
193
+ zoom
194
+ labels={{ before: 'Before', after: 'After' }}
195
+ handleStyle="arrows"
196
+ animate={{ duration: 800 }}
197
+ onSlide={(pos) => console.log('Position:', pos)}
198
+ />
199
+ );
200
+ }
201
+
202
+ // Hook
203
+ function ImageComparison() {
204
+ const { containerRef, instance } = useCIBeforeAfter({
205
+ beforeSrc: '/kitchen-before.jpg',
206
+ afterSrc: '/kitchen-after.jpg',
207
+ zoom: true,
208
+ });
209
+
210
+ return (
211
+ <>
212
+ <div ref={containerRef} />
213
+ <button onClick={() => instance.current?.setZoom(2)}>Zoom 2×</button>
214
+ </>
215
+ );
216
+ }
217
+
218
+ // Ref API
219
+ function ImageComparison() {
220
+ const ref = useRef<CIBeforeAfterViewerRef>(null);
221
+ return (
222
+ <>
223
+ <CIBeforeAfterViewer
224
+ ref={ref}
225
+ beforeSrc="/kitchen-before.jpg"
226
+ afterSrc="/kitchen-after.jpg"
227
+ zoom
228
+ />
229
+ <button onClick={() => ref.current?.setPosition(75)}>Show 75%</button>
230
+ </>
231
+ );
232
+ }
233
+ ```
234
+
235
+ ## Theming
236
+
237
+ All visuals are customizable via CSS variables:
238
+
239
+ ```css
240
+ .my-viewer {
241
+ --ci-before-after-border-radius: 12px;
242
+ --ci-before-after-handle-color: #0058a3;
243
+ --ci-before-after-handle-size: 44px;
244
+ --ci-before-after-handle-border: 2px solid white;
245
+ --ci-before-after-label-bg: rgba(0, 0, 0, 0.6);
246
+ --ci-before-after-label-color: #fff;
247
+ --ci-before-after-label-radius: 4px;
248
+ }
249
+ ```
250
+
251
+ Set `theme: 'dark'` for the built-in dark theme.
252
+
253
+ ## Accessibility
254
+
255
+ - Slider handle is a focusable element with `role="slider"` and `aria-valuenow`
256
+ - `Arrow keys` move the slider position
257
+ - `Shift + Arrow` moves in larger steps
258
+ - `Home` / `End` jump to 0% / 100%
259
+ - `+` / `-` / `0` control zoom
260
+ - `Escape` exits fullscreen
261
+ - `prefers-reduced-motion` disables animations
262
+ - Before/after images have configurable alt text
263
+
264
+ ## Cloudimage Integration
265
+
266
+ ```js
267
+ new CIBeforeAfter('#el', {
268
+ beforeSrc: 'https://example.com/before.jpg',
269
+ afterSrc: 'https://example.com/after.jpg',
270
+ cloudimage: {
271
+ token: 'demo',
272
+ limitFactor: 100,
273
+ params: 'q=80',
274
+ },
275
+ });
276
+ ```
277
+
278
+ ## Browser Support
279
+
280
+ | Browser | Version |
281
+ |---------|---------|
282
+ | Chrome | 80+ |
283
+ | Firefox | 80+ |
284
+ | Safari | 14+ |
285
+ | Edge | 80+ |
286
+
287
+ ## License
288
+
289
+ [MIT](./LICENSE)
290
+
291
+ ---
292
+
293
+ ## Support
294
+
295
+ If this library helped your project, consider buying me a coffee!
296
+
297
+ <a href="https://buymeacoffee.com/dzmitry.stramavus">
298
+ <img src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black" alt="Buy Me A Coffee">
299
+ </a>
300
+
301
+ ---
302
+
303
+ <p align="center">
304
+ Made with care by the <a href="https://www.scaleflex.com">Scaleflex</a> team
305
+ </p>
@@ -0,0 +1,4 @@
1
+ import type { Orientation } from '../core/types';
2
+ export declare function updateAriaValue(handle: HTMLElement, position: number): void;
3
+ export declare function updateAriaOrientation(handle: HTMLElement, orientation: Orientation): void;
4
+ export declare function setContainerAria(container: HTMLElement): void;
@@ -0,0 +1,22 @@
1
+ import type { Orientation } from '../core/types';
2
+ export interface KeyboardCallbacks {
3
+ onPositionChange: (position: number) => void;
4
+ getPosition: () => number;
5
+ onZoomIn?: () => void;
6
+ onZoomOut?: () => void;
7
+ onZoomReset?: () => void;
8
+ }
9
+ export declare class KeyboardHandler {
10
+ private handle;
11
+ private orientation;
12
+ private step;
13
+ private largeStep;
14
+ private zoomEnabled;
15
+ private callbacks;
16
+ private events;
17
+ constructor(handle: HTMLElement, orientation: Orientation, step: number, largeStep: number, zoomEnabled: boolean, callbacks: KeyboardCallbacks);
18
+ private bind;
19
+ private handleKeyDown;
20
+ updateConfig(orientation: Orientation, step: number, largeStep: number, zoomEnabled: boolean): void;
21
+ destroy(): void;
22
+ }
@@ -0,0 +1,18 @@
1
+ export declare class EntranceAnimation {
2
+ private container;
3
+ private duration;
4
+ private delay;
5
+ private easing;
6
+ private animateOnce;
7
+ private onAnimate;
8
+ private observer;
9
+ private hasPlayed;
10
+ private isAnimating;
11
+ private delayTimer;
12
+ private durationTimer;
13
+ constructor(container: HTMLElement, duration: number, delay: number, easing: string, animateOnce: boolean, onAnimate: (skipTransition: boolean) => void);
14
+ private observe;
15
+ private play;
16
+ getHasPlayed(): boolean;
17
+ destroy(): void;
18
+ }
@@ -0,0 +1,64 @@
1
+ import type { CIBeforeAfterConfig, CIBeforeAfterInstance } from './types';
2
+ export declare class CIBeforeAfterCore implements CIBeforeAfterInstance {
3
+ private config;
4
+ private userConfig;
5
+ private state;
6
+ private elements;
7
+ private events;
8
+ private imageEvents;
9
+ private sliderGestures;
10
+ private zoomPan;
11
+ private zoomGestures;
12
+ private scrollHint;
13
+ private fullscreenManager;
14
+ private entranceAnimation;
15
+ private keyboardHandler;
16
+ private resizeObserver;
17
+ private zoomControlsEl;
18
+ private zoomControlsEvents;
19
+ private lazyLoadObserver;
20
+ private resizeDebounceTimer;
21
+ private animTransitionTimer;
22
+ private suppressCallbacks;
23
+ constructor(target: HTMLElement | string, userConfig: CIBeforeAfterConfig);
24
+ getElements(): {
25
+ container: HTMLElement;
26
+ viewport: HTMLElement;
27
+ beforeImage: HTMLImageElement;
28
+ afterImage: HTMLImageElement;
29
+ handle: HTMLElement;
30
+ };
31
+ setPosition(percent: number): void;
32
+ getPosition(): number;
33
+ setZoom(level: number): void;
34
+ getZoom(): number;
35
+ resetZoom(): void;
36
+ enterFullscreen(): void;
37
+ exitFullscreen(): void;
38
+ isFullscreen(): boolean;
39
+ update(newConfig: Partial<CIBeforeAfterConfig>): void;
40
+ destroy(): void;
41
+ private buildDOM;
42
+ private initModules;
43
+ private initZoom;
44
+ private applyZoomPositionClasses;
45
+ private initEntranceAnimation;
46
+ private loadImages;
47
+ /**
48
+ * Register load/error handlers for images. Cleans up previous handlers first.
49
+ * When only one image changed, the unchanged image is treated as already loaded.
50
+ */
51
+ private registerImageLoadHandlers;
52
+ private onImagesReady;
53
+ private getClipZoomInfo;
54
+ private syncClip;
55
+ private updatePosition;
56
+ private onDragStart;
57
+ private onDragEnd;
58
+ private resolveImageSrc;
59
+ private rebuildHandle;
60
+ private rebuildLabels;
61
+ private rebuildZoom;
62
+ private rebuildFullscreen;
63
+ private initResizeObserver;
64
+ }
@@ -0,0 +1,3 @@
1
+ import type { CIBeforeAfterConfig, ResolvedConfig } from './types';
2
+ export declare function resolveConfig(config: CIBeforeAfterConfig): ResolvedConfig;
3
+ export declare function parseDataAttributes(el: HTMLElement): CIBeforeAfterConfig;
@@ -0,0 +1,127 @@
1
+ export type InteractionMode = 'drag' | 'hover' | 'click';
2
+ export type Orientation = 'horizontal' | 'vertical';
3
+ export type HandleStyle = 'arrows' | 'circle' | 'line';
4
+ export type Theme = 'light' | 'dark';
5
+ export type LabelPosition = 'top' | 'bottom';
6
+ export type ZoomControlsPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
7
+ export interface AnimateConfig {
8
+ duration?: number;
9
+ delay?: number;
10
+ easing?: string;
11
+ }
12
+ export interface CloudimageConfig {
13
+ token: string;
14
+ apiVersion?: string;
15
+ domain?: string;
16
+ limitFactor?: number;
17
+ params?: string;
18
+ devicePixelRatioList?: number[];
19
+ }
20
+ export interface CIBeforeAfterConfig {
21
+ beforeSrc: string;
22
+ afterSrc: string;
23
+ beforeAlt?: string;
24
+ afterAlt?: string;
25
+ mode?: InteractionMode;
26
+ orientation?: Orientation;
27
+ initialPosition?: number;
28
+ zoom?: boolean;
29
+ zoomMax?: number;
30
+ zoomMin?: number;
31
+ theme?: Theme;
32
+ handleStyle?: HandleStyle;
33
+ labels?: boolean | {
34
+ before?: string;
35
+ after?: string;
36
+ };
37
+ labelPosition?: LabelPosition;
38
+ animate?: boolean | AnimateConfig;
39
+ animateOnce?: boolean;
40
+ fullscreenButton?: boolean;
41
+ lazyLoad?: boolean;
42
+ zoomControls?: boolean;
43
+ zoomControlsPosition?: ZoomControlsPosition;
44
+ scrollHint?: boolean;
45
+ keyboardStep?: number;
46
+ keyboardLargeStep?: number;
47
+ onSlide?: (position: number) => void;
48
+ onZoom?: (level: number) => void;
49
+ onFullscreenChange?: (isFullscreen: boolean) => void;
50
+ onReady?: () => void;
51
+ cloudimage?: CloudimageConfig;
52
+ }
53
+ export interface ResolvedConfig {
54
+ beforeSrc: string;
55
+ afterSrc: string;
56
+ beforeAlt: string;
57
+ afterAlt: string;
58
+ mode: InteractionMode;
59
+ orientation: Orientation;
60
+ initialPosition: number;
61
+ zoom: boolean;
62
+ zoomMax: number;
63
+ zoomMin: number;
64
+ theme: Theme;
65
+ handleStyle: HandleStyle;
66
+ labelsEnabled: boolean;
67
+ labelBefore: string;
68
+ labelAfter: string;
69
+ labelPosition: LabelPosition;
70
+ animateEnabled: boolean;
71
+ animateDuration: number;
72
+ animateDelay: number;
73
+ animateEasing: string;
74
+ animateOnce: boolean;
75
+ fullscreenButton: boolean;
76
+ lazyLoad: boolean;
77
+ zoomControls: boolean;
78
+ zoomControlsPosition: ZoomControlsPosition;
79
+ scrollHint: boolean;
80
+ keyboardStep: number;
81
+ keyboardLargeStep: number;
82
+ onSlide?: (position: number) => void;
83
+ onZoom?: (level: number) => void;
84
+ onFullscreenChange?: (isFullscreen: boolean) => void;
85
+ onReady?: () => void;
86
+ cloudimage?: CloudimageConfig;
87
+ }
88
+ export interface SliderState {
89
+ position: number;
90
+ isDragging: boolean;
91
+ zoomLevel: number;
92
+ panX: number;
93
+ panY: number;
94
+ isReady: boolean;
95
+ isFullscreen: boolean;
96
+ }
97
+ export interface CIBeforeAfterElements {
98
+ container: HTMLElement;
99
+ viewport: HTMLElement;
100
+ wrapper: HTMLElement;
101
+ beforeImage: HTMLImageElement;
102
+ afterImage: HTMLImageElement;
103
+ clip: HTMLElement;
104
+ handle: HTMLElement;
105
+ handleGrip: HTMLElement;
106
+ labelBefore: HTMLElement | null;
107
+ labelAfter: HTMLElement | null;
108
+ }
109
+ export interface CIBeforeAfterInstance {
110
+ getElements(): {
111
+ container: HTMLElement;
112
+ viewport: HTMLElement;
113
+ beforeImage: HTMLImageElement;
114
+ afterImage: HTMLImageElement;
115
+ handle: HTMLElement;
116
+ };
117
+ setPosition(percent: number): void;
118
+ getPosition(): number;
119
+ setZoom(level: number): void;
120
+ getZoom(): number;
121
+ resetZoom(): void;
122
+ enterFullscreen(): void;
123
+ exitFullscreen(): void;
124
+ isFullscreen(): boolean;
125
+ update(config: Partial<CIBeforeAfterConfig>): void;
126
+ destroy(): void;
127
+ }
@@ -0,0 +1,16 @@
1
+ export declare class FullscreenManager {
2
+ private container;
3
+ private onFullscreenChange?;
4
+ private button;
5
+ private events;
6
+ private isActive;
7
+ constructor(container: HTMLElement, onFullscreenChange?: ((isFullscreen: boolean) => void) | undefined);
8
+ private createButton;
9
+ private bindEvents;
10
+ private handleChange;
11
+ enter(): Promise<void>;
12
+ exit(): Promise<void>;
13
+ toggle(): Promise<void>;
14
+ getIsFullscreen(): boolean;
15
+ destroy(): void;
16
+ }
@@ -0,0 +1,10 @@
1
+ import { CIBeforeAfterCore } from './core/ci-before-after';
2
+ import type { CIBeforeAfterConfig, CIBeforeAfterInstance } from './core/types';
3
+ export type { CIBeforeAfterConfig, CIBeforeAfterInstance, InteractionMode, Orientation, HandleStyle, Theme, LabelPosition, ZoomControlsPosition, AnimateConfig, CloudimageConfig, SliderState, } from './core/types';
4
+ export { CIBeforeAfterCore };
5
+ declare class CIBeforeAfter extends CIBeforeAfterCore {
6
+ static autoInit(root?: HTMLElement): CIBeforeAfterInstance[];
7
+ constructor(target: HTMLElement | string, config: CIBeforeAfterConfig);
8
+ }
9
+ export default CIBeforeAfter;
10
+ export { CIBeforeAfter };