zoomora 1.1.0 → 1.2.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.
- package/README.md +75 -15
- package/dist/zoomora.es.js +94 -28
- package/dist/zoomora.es.js.map +1 -1
- package/dist/zoomora.es.min.js +4 -4
- package/dist/zoomora.es.min.js.map +1 -1
- package/dist/zoomora.umd.js +94 -28
- package/dist/zoomora.umd.js.map +1 -1
- package/dist/zoomora.umd.min.js +4 -4
- package/dist/zoomora.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/zoomora.js +160 -47
package/README.md
CHANGED
|
@@ -2,11 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
|
|
5
|
+
<div align="center">
|
|
6
|
+
|
|
5
7
|
A modern, responsive lightbox plugin with zoom, fullscreen, and gallery features. Perfect for showcasing images and videos in a beautiful, user-friendly interface.
|
|
6
8
|
|
|
7
9
|
[](https://fronttheme.github.io/zoomora/)
|
|
8
|
-
](https://www.npmjs.com/package/zoomora)
|
|
11
|
+
[](https://www.npmjs.com/package/zoomora)
|
|
12
|
+
[](https://github.com/fronttheme/zoomora/blob/main/LICENSE)
|
|
13
|
+
[](https://bundlephobia.com/package/zoomora)
|
|
14
|
+
[](https://github.com/fronttheme/zoomora/stargazers)
|
|
15
|
+
|
|
16
|
+
**[Demo](https://fronttheme.github.io/zoomora/)** • **[Documentation](#-quick-start)** • **[Report Bug](https://github.com/fronttheme/zoomora/issues)** • **[Request Feature](https://github.com/fronttheme/zoomora/issues)**
|
|
17
|
+
|
|
18
|
+
</div>
|
|
10
19
|
|
|
11
20
|
## ✨ Features
|
|
12
21
|
|
|
@@ -22,8 +31,9 @@ A modern, responsive lightbox plugin with zoom, fullscreen, and gallery features
|
|
|
22
31
|
- 🌓 **Fullscreen Mode** - Immersive viewing experience
|
|
23
32
|
- 🎨 **Customizable** - Extensive options and callbacks
|
|
24
33
|
- ♿ **Accessible** - Keyboard and screen reader friendly
|
|
25
|
-
- 🚀 **Lightweight** - No dependencies required
|
|
34
|
+
- 🚀 **Lightweight** - No dependencies required (~15KB gzipped)
|
|
26
35
|
- 🔧 **Easy Integration** - Works with vanilla JS, React, Vue, etc.
|
|
36
|
+
- 🎁 **MIT Licensed** - Free for personal and commercial use
|
|
27
37
|
|
|
28
38
|
## 📦 Installation
|
|
29
39
|
|
|
@@ -33,6 +43,12 @@ A modern, responsive lightbox plugin with zoom, fullscreen, and gallery features
|
|
|
33
43
|
npm install zoomora
|
|
34
44
|
```
|
|
35
45
|
|
|
46
|
+
### Yarn
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
yarn add zoomora
|
|
50
|
+
```
|
|
51
|
+
|
|
36
52
|
### CDN
|
|
37
53
|
|
|
38
54
|
```html
|
|
@@ -86,6 +102,7 @@ const lightbox = new Zoomora({
|
|
|
86
102
|
transition: 'fade', // 'fade' or 'slide'
|
|
87
103
|
maxZoomScale: 3,
|
|
88
104
|
animationDuration: 300,
|
|
105
|
+
closeOnBackgroundClick: true, // v1.2.0+
|
|
89
106
|
autoHideDelay: 3000,
|
|
90
107
|
autoHideEnabled: false,
|
|
91
108
|
onOpen: (element, index) => {
|
|
@@ -182,6 +199,7 @@ const lightbox = Zoomora.bind('a[data-lightbox]', {
|
|
|
182
199
|
| `maxZoomScale` | Number | `3` | Maximum zoom scale |
|
|
183
200
|
| `zoomStep` | Number | `0.1` | Zoom step for scroll wheel |
|
|
184
201
|
| `animationDuration` | Number | `300` | Animation duration in milliseconds |
|
|
202
|
+
| `closeOnBackgroundClick` | Boolean | `true` | Close lightbox on background click (v1.2.0+) |
|
|
185
203
|
| `showAutoHideToggle` | Boolean | `true` | Show auto-hide toggle button |
|
|
186
204
|
| `autoHideDelay` | Number | `3000` | Delay before hiding controls (ms) |
|
|
187
205
|
| `autoHideEnabled` | Boolean | `false` | Enable auto-hide by default |
|
|
@@ -250,13 +268,39 @@ Zoomora includes beautiful default styles, but you can customize them:
|
|
|
250
268
|
}
|
|
251
269
|
```
|
|
252
270
|
|
|
271
|
+
## 📊 Stats & Performance
|
|
272
|
+
|
|
273
|
+
- **Bundle Size**: ~15KB minified + gzipped
|
|
274
|
+
- **Zero Dependencies**: Pure vanilla JavaScript
|
|
275
|
+
- **Browser Support**: All modern browsers (Chrome, Firefox, Safari, Edge)
|
|
276
|
+
- **Mobile Optimized**: Touch-friendly with gesture support
|
|
277
|
+
- **Performance**: 60fps smooth animations
|
|
278
|
+
- **Accessibility**: WCAG 2.1 AA compliant
|
|
279
|
+
|
|
253
280
|
## 🌐 Browser Support
|
|
254
281
|
|
|
255
|
-
- Chrome (latest)
|
|
256
|
-
- Firefox (latest)
|
|
257
|
-
- Safari (latest)
|
|
258
|
-
- Edge (latest)
|
|
259
|
-
- Mobile browsers (iOS Safari, Chrome Mobile)
|
|
282
|
+
- ✅ Chrome (latest)
|
|
283
|
+
- ✅ Firefox (latest)
|
|
284
|
+
- ✅ Safari (latest)
|
|
285
|
+
- ✅ Edge (latest)
|
|
286
|
+
- ✅ Mobile browsers (iOS Safari, Chrome Mobile)
|
|
287
|
+
|
|
288
|
+
## 📝 Changelog
|
|
289
|
+
|
|
290
|
+
See [CHANGELOG.md](CHANGELOG.md) for a detailed list of changes.
|
|
291
|
+
|
|
292
|
+
### Recent Updates
|
|
293
|
+
|
|
294
|
+
#### v1.2.0 (Latest)
|
|
295
|
+
- ✨ **New**: Background click to close lightbox
|
|
296
|
+
- ✨ **New**: `closeOnBackgroundClick` configuration option
|
|
297
|
+
- 🐛 **Fixed**: Smart click detection between media and background
|
|
298
|
+
|
|
299
|
+
#### v1.1.0
|
|
300
|
+
- ✨ Progressive zoom levels (1x → 1.5x → 2x → 3x → 100%)
|
|
301
|
+
- 🐛 Fixed drag dezooming issue
|
|
302
|
+
- 🐛 Fixed auto-hide toggle not working
|
|
303
|
+
- 🐛 Fixed vertical image boundary calculations
|
|
260
304
|
|
|
261
305
|
## 🤝 Contributing
|
|
262
306
|
|
|
@@ -268,27 +312,43 @@ Contributions are welcome! Please feel free to submit a Pull Request.
|
|
|
268
312
|
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
|
269
313
|
5. Open a Pull Request
|
|
270
314
|
|
|
271
|
-
##
|
|
315
|
+
## 📄 License
|
|
272
316
|
|
|
273
317
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
274
318
|
|
|
275
319
|
## 👨💻 Author
|
|
276
320
|
|
|
277
|
-
**Faruk Ahmed**
|
|
278
|
-
[FrontTheme](https://fronttheme.com)
|
|
321
|
+
**Faruk Ahmed**
|
|
322
|
+
- Website: [FrontTheme](https://fronttheme.com)
|
|
323
|
+
- Portfolio: [farukdesign.com](https://www.farukdesign.com/)
|
|
324
|
+
- GitHub: [@fronttheme](https://github.com/fronttheme)
|
|
279
325
|
|
|
280
326
|
## 🙏 Acknowledgments
|
|
281
327
|
|
|
282
328
|
- Inspired by modern lightbox libraries
|
|
283
329
|
- Built with love for the web community
|
|
330
|
+
- Thanks to all [contributors](https://github.com/fronttheme/zoomora/graphs/contributors)!
|
|
284
331
|
|
|
285
|
-
##
|
|
332
|
+
## 💬 Community & Support
|
|
286
333
|
|
|
287
|
-
- 🟢 [Live Demo](https://fronttheme.github.io/zoomora/)
|
|
288
334
|
- 🐛 [Report a bug](https://github.com/fronttheme/zoomora/issues)
|
|
289
335
|
- 💡 [Request a feature](https://github.com/fronttheme/zoomora/issues)
|
|
290
|
-
- 📖 [
|
|
336
|
+
- 📖 [Read the docs](https://github.com/fronttheme/zoomora)
|
|
337
|
+
- ⭐ [Star on GitHub](https://github.com/fronttheme/zoomora)
|
|
338
|
+
|
|
339
|
+
## 🔗 Resources
|
|
340
|
+
|
|
341
|
+
- 🟢 [Live Demo](https://fronttheme.github.io/zoomora/)
|
|
342
|
+
- 📦 [NPM Package](https://www.npmjs.com/package/zoomora)
|
|
343
|
+
- 📚 [Documentation](https://github.com/fronttheme/zoomora)
|
|
344
|
+
- 💬 [Discussions](https://github.com/fronttheme/zoomora/discussions)
|
|
291
345
|
|
|
292
346
|
---
|
|
293
347
|
|
|
294
|
-
|
|
348
|
+
<div align="center">
|
|
349
|
+
|
|
350
|
+
Made with ❤️ by [FrontTheme](https://fronttheme.com)
|
|
351
|
+
|
|
352
|
+
**[⬆ back to top](#zoomora-lightbox)**
|
|
353
|
+
|
|
354
|
+
</div>
|
package/dist/zoomora.es.js
CHANGED
|
@@ -24,10 +24,10 @@ var __commonJS = (cb, mod) => function __require() {
|
|
|
24
24
|
var require_zoomora_es = __commonJS({
|
|
25
25
|
"zoomora.es.js"(exports, module) {
|
|
26
26
|
/*!
|
|
27
|
-
* Zoomora Lightbox Plugin v1.
|
|
27
|
+
* Zoomora Lightbox Plugin v1.2.0
|
|
28
28
|
* A modern, responsive lightbox plugin with zoom, fullscreen, and gallery features
|
|
29
29
|
*
|
|
30
|
-
* Copyright (c)
|
|
30
|
+
* Copyright (c) 2026 Faruk Ahmed (FrontTheme)
|
|
31
31
|
* Licensed under MIT License
|
|
32
32
|
*/
|
|
33
33
|
(function(global, factory) {
|
|
@@ -61,6 +61,8 @@ var require_zoomora_es = __commonJS({
|
|
|
61
61
|
// Zoom step for scroll wheel
|
|
62
62
|
animationDuration: 300,
|
|
63
63
|
// Animation duration in ms
|
|
64
|
+
closeOnBackgroundClick: true,
|
|
65
|
+
// Close lightbox when clicking on background
|
|
64
66
|
onOpen: null,
|
|
65
67
|
// Callback when lightbox opens
|
|
66
68
|
onClose: null,
|
|
@@ -315,11 +317,15 @@ var require_zoomora_es = __commonJS({
|
|
|
315
317
|
* Handle fullscreen change events
|
|
316
318
|
*/
|
|
317
319
|
handleFullscreenChange() {
|
|
318
|
-
const isInFullscreen = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement;
|
|
320
|
+
const isInFullscreen = !!(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement);
|
|
319
321
|
if (!isInFullscreen && this.isFullscreen) {
|
|
320
322
|
this.isFullscreen = false;
|
|
321
323
|
this.zoomora.classList.remove("fullscreen");
|
|
322
324
|
this.updateButtons();
|
|
325
|
+
} else if (isInFullscreen && !this.isFullscreen) {
|
|
326
|
+
this.isFullscreen = true;
|
|
327
|
+
this.zoomora.classList.add("fullscreen");
|
|
328
|
+
this.updateButtons();
|
|
323
329
|
}
|
|
324
330
|
}
|
|
325
331
|
/**
|
|
@@ -327,7 +333,7 @@ var require_zoomora_es = __commonJS({
|
|
|
327
333
|
* @param {Event} e - Click event
|
|
328
334
|
*/
|
|
329
335
|
handleZoomoraClick(e) {
|
|
330
|
-
if (e.target === this.zoomora) {
|
|
336
|
+
if (e.target === this.zoomora && this.options.closeOnBackgroundClick) {
|
|
331
337
|
this.close();
|
|
332
338
|
}
|
|
333
339
|
}
|
|
@@ -339,9 +345,37 @@ var require_zoomora_es = __commonJS({
|
|
|
339
345
|
if (Date.now() - this.lastDragTime < 200) {
|
|
340
346
|
return;
|
|
341
347
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
348
|
+
if (this.header && this.header.contains(e.target)) {
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (e.target.closest("button")) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const mediaElement = e.target.closest(".zoomora-media, .zoomora-video, .zoomora-iframe");
|
|
355
|
+
if (mediaElement) {
|
|
356
|
+
if (mediaElement.classList.contains("zoomora-media") && !mediaElement.classList.contains("no-zoom")) {
|
|
357
|
+
this.toggleZoom();
|
|
358
|
+
}
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const videoContainer = e.target.closest(".zoomora-video-container");
|
|
362
|
+
if (videoContainer) {
|
|
363
|
+
if (e.target.closest(".zoomora-play-button")) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
if (this.options.closeOnBackgroundClick) {
|
|
367
|
+
this.close();
|
|
368
|
+
}
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const clickedElement = e.target;
|
|
372
|
+
const isBackgroundElement = clickedElement.classList.contains("zoomora-content") || clickedElement.classList.contains("zoomora-slide-container") || clickedElement.classList.contains("zoomora-slide") || clickedElement.classList.contains("zoomora-slides-container") || clickedElement.id === "zoomoraContent" || clickedElement.id === "zoomoraSlidesContainer";
|
|
373
|
+
if (isBackgroundElement && this.options.closeOnBackgroundClick) {
|
|
374
|
+
this.close();
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
if (this.options.closeOnBackgroundClick) {
|
|
378
|
+
this.close();
|
|
345
379
|
}
|
|
346
380
|
}
|
|
347
381
|
/**
|
|
@@ -807,11 +841,6 @@ var require_zoomora_es = __commonJS({
|
|
|
807
841
|
img.classList.add("no-zoom");
|
|
808
842
|
}
|
|
809
843
|
}
|
|
810
|
-
/**
|
|
811
|
-
* Calculate zoom levels for an image
|
|
812
|
-
* @param {HTMLImageElement} img - Image element
|
|
813
|
-
* @returns {Object} Zoom configuration
|
|
814
|
-
*/
|
|
815
844
|
/**
|
|
816
845
|
* Calculate zoom levels for an image
|
|
817
846
|
* @param {HTMLImageElement} img - Image element
|
|
@@ -952,7 +981,6 @@ var require_zoomora_es = __commonJS({
|
|
|
952
981
|
if (!media || media.tagName !== "IMG") return;
|
|
953
982
|
const zoomConfig = this.calculateZoomLevels(media);
|
|
954
983
|
if (!zoomConfig.canZoom) {
|
|
955
|
-
console.log("Image cannot be zoomed (already at full size or larger)");
|
|
956
984
|
return;
|
|
957
985
|
}
|
|
958
986
|
if (!media.dataset.zoomLevel) {
|
|
@@ -983,7 +1011,6 @@ var require_zoomora_es = __commonJS({
|
|
|
983
1011
|
media.style.transform = `translate(0px, 0px) scale(${targetScale})`;
|
|
984
1012
|
media.style.cursor = "grab";
|
|
985
1013
|
media.classList.add("zoomed");
|
|
986
|
-
console.log(`Zoomed to level ${currentLevel}/${zoomConfig.levels.length - 1} (${(targetScale * 100).toFixed(0)}%)`);
|
|
987
1014
|
}
|
|
988
1015
|
}
|
|
989
1016
|
/**
|
|
@@ -1015,17 +1042,37 @@ var require_zoomora_es = __commonJS({
|
|
|
1015
1042
|
*/
|
|
1016
1043
|
enterFullscreen() {
|
|
1017
1044
|
const element = this.zoomora;
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1045
|
+
try {
|
|
1046
|
+
if (element.requestFullscreen) {
|
|
1047
|
+
element.requestFullscreen().then(() => {
|
|
1048
|
+
this.isFullscreen = true;
|
|
1049
|
+
this.zoomora.classList.add("fullscreen");
|
|
1050
|
+
this.updateButtons();
|
|
1051
|
+
}).catch((err) => {
|
|
1052
|
+
console.warn("Zoomora: Fullscreen request failed:", err.message);
|
|
1053
|
+
this.fallbackFullscreen();
|
|
1054
|
+
});
|
|
1055
|
+
} else if (element.webkitRequestFullscreen) {
|
|
1056
|
+
element.webkitRequestFullscreen();
|
|
1057
|
+
this.isFullscreen = true;
|
|
1058
|
+
this.zoomora.classList.add("fullscreen");
|
|
1059
|
+
this.updateButtons();
|
|
1060
|
+
} else if (element.mozRequestFullScreen) {
|
|
1061
|
+
element.mozRequestFullScreen();
|
|
1021
1062
|
this.isFullscreen = true;
|
|
1022
1063
|
this.zoomora.classList.add("fullscreen");
|
|
1023
1064
|
this.updateButtons();
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1065
|
+
} else if (element.msRequestFullscreen) {
|
|
1066
|
+
element.msRequestFullscreen();
|
|
1067
|
+
this.isFullscreen = true;
|
|
1068
|
+
this.zoomora.classList.add("fullscreen");
|
|
1069
|
+
this.updateButtons();
|
|
1070
|
+
} else {
|
|
1071
|
+
console.warn("Zoomora: Fullscreen API not supported, using CSS fallback");
|
|
1026
1072
|
this.fallbackFullscreen();
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1073
|
+
}
|
|
1074
|
+
} catch (error) {
|
|
1075
|
+
console.error("Zoomora: Error entering fullscreen:", error);
|
|
1029
1076
|
this.fallbackFullscreen();
|
|
1030
1077
|
}
|
|
1031
1078
|
}
|
|
@@ -1033,22 +1080,41 @@ var require_zoomora_es = __commonJS({
|
|
|
1033
1080
|
* Exit fullscreen mode
|
|
1034
1081
|
*/
|
|
1035
1082
|
exitFullscreen() {
|
|
1036
|
-
const isInFullscreen = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement;
|
|
1037
|
-
if (isInFullscreen) {
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1083
|
+
const isInFullscreen = !!(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement);
|
|
1084
|
+
if (!isInFullscreen) {
|
|
1085
|
+
this.fallbackExitFullscreen();
|
|
1086
|
+
return;
|
|
1087
|
+
}
|
|
1088
|
+
try {
|
|
1089
|
+
if (document.exitFullscreen) {
|
|
1090
|
+
document.exitFullscreen().then(() => {
|
|
1041
1091
|
this.isFullscreen = false;
|
|
1042
1092
|
this.zoomora.classList.remove("fullscreen");
|
|
1043
1093
|
this.updateButtons();
|
|
1044
1094
|
}).catch((err) => {
|
|
1045
|
-
console.warn("Zoomora:
|
|
1095
|
+
console.warn("Zoomora: Exit fullscreen failed:", err.message);
|
|
1046
1096
|
this.fallbackExitFullscreen();
|
|
1047
1097
|
});
|
|
1098
|
+
} else if (document.webkitExitFullscreen) {
|
|
1099
|
+
document.webkitExitFullscreen();
|
|
1100
|
+
this.isFullscreen = false;
|
|
1101
|
+
this.zoomora.classList.remove("fullscreen");
|
|
1102
|
+
this.updateButtons();
|
|
1103
|
+
} else if (document.mozCancelFullScreen) {
|
|
1104
|
+
document.mozCancelFullScreen();
|
|
1105
|
+
this.isFullscreen = false;
|
|
1106
|
+
this.zoomora.classList.remove("fullscreen");
|
|
1107
|
+
this.updateButtons();
|
|
1108
|
+
} else if (document.msExitFullscreen) {
|
|
1109
|
+
document.msExitFullscreen();
|
|
1110
|
+
this.isFullscreen = false;
|
|
1111
|
+
this.zoomora.classList.remove("fullscreen");
|
|
1112
|
+
this.updateButtons();
|
|
1048
1113
|
} else {
|
|
1049
1114
|
this.fallbackExitFullscreen();
|
|
1050
1115
|
}
|
|
1051
|
-
}
|
|
1116
|
+
} catch (error) {
|
|
1117
|
+
console.error("Zoomora: Error exiting fullscreen:", error);
|
|
1052
1118
|
this.fallbackExitFullscreen();
|
|
1053
1119
|
}
|
|
1054
1120
|
}
|