neiki-gallery 2.0.0 → 2.1.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 CHANGED
@@ -10,7 +10,7 @@
10
10
  <img src="https://img.shields.io/badge/css-%23663399.svg?style=for-the-badge&logo=css&logoColor=white" alt="CSS">
11
11
  <br>
12
12
  <img src="https://img.shields.io/badge/License-MIT-2563EB?style=for-the-badge&logo=open-source-initiative&logoColor=white&labelColor=000F15&logoWidth=20" alt="License">
13
- <img src="https://img.shields.io/badge/Version-2.0.0-2563EB?style=for-the-badge&logo=semantic-release&logoColor=white&labelColor=000F15&logoWidth=20" alt="Version">
13
+ <img src="https://img.shields.io/badge/Version-2.1.0-2563EB?style=for-the-badge&logo=semantic-release&logoColor=white&labelColor=000F15&logoWidth=20" alt="Version">
14
14
  </p>
15
15
 
16
16
  <p align="center">
@@ -56,17 +56,28 @@
56
56
  - **Dark & light themes** — CSS custom properties + accent color system (`--neiki-accent`)
57
57
  - **Accessibility** — ARIA attributes, focus management, `prefers-reduced-motion`
58
58
  - **Event system** — `open`, `close`, `change`, `filter`, `select`, `slideshowStart`, `slideshowStop`
59
+ - **Blurhash placeholders** — `data-blurhash` attribute decoded into blurred preview (replaces shimmer)
60
+ - **Story mode** — Instagram-like vertical fullscreen viewer with progress bars and tap navigation
61
+ - **Picture-in-Picture** — minimize lightbox to a resizable corner window
62
+ - **Image focus point** — `data-focus="0.3 0.7"` controls `object-position` for smart cropping
63
+ - **EXIF overlay** — camera model, focal length, aperture, shutter speed, ISO from JPEG binary
64
+ - **Color palette extraction** — k-means quantized 5-color palette strip in lightbox
65
+ - **Backdrop tint** — overlay adapts to dominant color of current image
66
+ - **FLIP morph transition** — smooth thumbnail-to-lightbox animation
67
+ - **Virtual scrolling** — `content-visibility` virtualization for large galleries (50+ items)
68
+ - **Drag & drop reorder** — HTML5 drag to reorder grid items
69
+ - **Aspect-ratio skeleton** — `data-width`/`data-height` for placeholder sizing
70
+ - **Web Share API** — native mobile sharing with clipboard fallback
59
71
  - **Cross-browser** — Chrome 60+, Firefox 55+, Safari 12+, Edge 79+
60
72
 
61
73
  ## 🚀 Quick Start
62
74
 
63
75
  ### CDN (Recommended)
64
76
 
65
- Add these two lines to your HTML — that's all you need:
77
+ Add this single line to your HTML — that's all you need (CSS is included automatically):
66
78
 
67
79
  ```html
68
- <link rel="stylesheet" href="http://cdn.neiki.eu/neiki-gallery/neiki-gallery.min.css">
69
- <script src="http://cdn.neiki.eu/neiki-gallery/neiki-gallery.min.js"></script>
80
+ <script src="https://cdn.neiki.eu/neiki-gallery/neiki-gallery.min.js"></script>
70
81
  ```
71
82
 
72
83
  Then create your gallery markup:
@@ -84,16 +95,15 @@ Then create your gallery markup:
84
95
 
85
96
  That's it — galleries with `data-neiki-gallery` auto-initialize on page load.
86
97
 
87
- > **Unminified files** are also available if you need them for debugging:
98
+ > **Unminified files** are also available if you need them for debugging (require separate CSS):
88
99
  > ```
89
- > http://cdn.neiki.eu/neiki-gallery/neiki-gallery.js
90
- > http://cdn.neiki.eu/neiki-gallery/neiki-gallery.css
100
+ > https://cdn.neiki.eu/neiki-gallery/neiki-gallery.js
101
+ > https://cdn.neiki.eu/neiki-gallery/neiki-gallery.css
91
102
  > ```
92
103
 
93
104
  > **Pin a specific version** to avoid unexpected changes:
94
105
  > ```
95
- > http://cdn.neiki.eu/neiki-gallery/2.0.0/neiki-gallery.min.js
96
- > http://cdn.neiki.eu/neiki-gallery/2.0.0/neiki-gallery.min.css
106
+ > https://cdn.neiki.eu/neiki-gallery/2.1.0/neiki-gallery.min.js
97
107
  > ```
98
108
 
99
109
  ### Self-Hosting (Local)
@@ -104,20 +114,26 @@ Download or clone the repository from GitHub:
104
114
  git clone https://github.com/neikiri/neiki-gallery.git
105
115
  ```
106
116
 
107
- Copy the files from the `dist/` folder into your project and link them directly:
117
+ For production, you only need one file CSS is already included:
108
118
 
109
119
  ```html
110
- <link rel="stylesheet" href="path/to/neiki-gallery.min.css">
111
120
  <script src="path/to/neiki-gallery.min.js"></script>
112
121
  ```
113
122
 
114
- The `dist/` folder contains both minified and unminified versions:
123
+ For development / debugging, use the unminified versions (requires separate CSS):
124
+
125
+ ```html
126
+ <link rel="stylesheet" href="path/to/neiki-gallery.css">
127
+ <script src="path/to/neiki-gallery.js"></script>
128
+ ```
129
+
130
+ The `dist/` folder contains:
115
131
 
116
132
  | File | Description |
117
133
  |------|-------------|
118
- | `neiki-gallery.min.js` | Minified JS (production) |
119
- | `neiki-gallery.min.css` | Minified CSS (production) |
120
- | `neiki-gallery.js` | Full JS (development / debugging) |
134
+ | `neiki-gallery.min.js` | Minified JS + CSS included (production) |
135
+ | `neiki-gallery.min.css` | Minified CSS standalone (optional) |
136
+ | `neiki-gallery.js` | Full JS without CSS (development / debugging) |
121
137
  | `neiki-gallery.css` | Full CSS (development / debugging) |
122
138
 
123
139
  ### Manual Initialization
@@ -139,6 +155,18 @@ const gallery = new NeikiGallery('#my-gallery', {
139
155
  share: true, // share/download popup
140
156
  filter: false, // tag filtering
141
157
  batchSelect: false, // Shift+click multi-select
158
+ // v2.1.0
159
+ focusPoint: true, // respect data-focus for object-position
160
+ blurhash: true, // decode data-blurhash placeholders
161
+ exif: false, // show EXIF overlay in lightbox
162
+ storyMode: false, // vertical fullscreen story viewer
163
+ pip: false, // picture-in-picture lightbox
164
+ virtualScroll: false, // virtualize grid for large galleries
165
+ dragReorder: false, // drag-and-drop reorder
166
+ backdropTint: false, // tint overlay with dominant color
167
+ morphTransition: false, // FLIP morph from grid to lightbox
168
+ colorPalette: false, // extract dominant colors
169
+ aspectSkeleton: true, // data-width/data-height skeleton
142
170
  });
143
171
  ```
144
172
 
@@ -157,6 +185,7 @@ gallery.toggleSlideshow(); // Toggle autoplay
157
185
  gallery.filter('landscape'); // Filter by tag (null = show all)
158
186
  gallery.getSelected(); // Get batch-selected items
159
187
  gallery.clearSelection(); // Clear batch selection
188
+ gallery.getOrder(); // Get current item order (after drag reorder)
160
189
  gallery.destroy(); // Remove gallery, clean up all listeners & DOM
161
190
  ```
162
191
 
@@ -174,6 +203,24 @@ const slider = NeikiGallery.compare('#compare-container', {
174
203
 
175
204
  slider.setPosition(30); // Move handle to 30%
176
205
  slider.destroy(); // Clean up
206
+
207
+ // Color palette extraction (v2.1.0)
208
+ NeikiGallery.extractPalette('photo.jpg', 5, (colors) => {
209
+ console.log(colors); // [{r, g, b, hex}, ...]
210
+ });
211
+
212
+ // Dominant color (v2.1.0)
213
+ NeikiGallery.extractDominantColor('photo.jpg', (color) => {
214
+ console.log(color); // {r, g, b, hex}
215
+ });
216
+
217
+ // EXIF parsing (v2.1.0)
218
+ NeikiGallery.parseExif('photo.jpg', (tags) => {
219
+ console.log(tags); // {make, model, iso, fNumber, exposure, focalLength}
220
+ });
221
+
222
+ // Blurhash decoding (v2.1.0)
223
+ const pixels = NeikiGallery.decodeBlurhash('LEHV6nWB2y...', 32, 32);
177
224
  ```
178
225
 
179
226
  ### Events
@@ -202,6 +249,13 @@ gallery.on('select', (indices) => {
202
249
  gallery.on('slideshowStart', () => {
203
250
  console.log('Slideshow started');
204
251
  });
252
+
253
+ gallery.on('reorder', (order) => {
254
+ console.log('New order:', order);
255
+ });
256
+
257
+ gallery.on('pipEnter', () => console.log('PiP on'));
258
+ gallery.on('storyEnter', () => console.log('Story opened'));
205
259
  ```
206
260
 
207
261
  ### Options
@@ -227,6 +281,17 @@ gallery.on('slideshowStart', () => {
227
281
  | `share` | `boolean` | `true` | Show share button in lightbox |
228
282
  | `filter` | `boolean` | `false` | Enable tag filtering bar |
229
283
  | `batchSelect` | `boolean` | `false` | Enable Shift+click multi-select |
284
+ | `focusPoint` | `boolean` | `true` | Respect `data-focus` for `object-position` |
285
+ | `blurhash` | `boolean` | `true` | Decode `data-blurhash` placeholders |
286
+ | `exif` | `boolean` | `false` | Show EXIF data overlay in lightbox |
287
+ | `storyMode` | `boolean` | `false` | Enable story mode button in toolbar |
288
+ | `pip` | `boolean` | `false` | Enable PiP button in toolbar |
289
+ | `virtualScroll` | `boolean` | `false` | Virtualize grid for 50+ items |
290
+ | `dragReorder` | `boolean` | `false` | Enable drag & drop reorder |
291
+ | `backdropTint` | `boolean` | `false` | Tint overlay with dominant color |
292
+ | `morphTransition` | `boolean` | `false` | FLIP morph from grid to lightbox |
293
+ | `colorPalette` | `boolean` | `false` | Show extracted color palette |
294
+ | `aspectSkeleton` | `boolean` | `true` | Use `data-width`/`data-height` for skeleton |
230
295
 
231
296
  ### Data Attributes
232
297
 
@@ -244,9 +309,18 @@ All options can also be set via `data-` attributes on the container:
244
309
  data-share="true"
245
310
  data-filter="true"
246
311
  data-batch-select="false"
247
- data-contextual-zoom="true">
248
- <a href="full.jpg" data-tags="landscape,nature" data-size="large">
249
- <img src="thumb.jpg" alt="Photo">
312
+ data-contextual-zoom="true"
313
+ data-story-mode="false"
314
+ data-pip="false"
315
+ data-exif="false"
316
+ data-backdrop-tint="false"
317
+ data-morph-transition="false"
318
+ data-color-palette="false"
319
+ data-drag-reorder="false"
320
+ data-virtual-scroll="false"
321
+ data-aspect-skeleton="true">
322
+ <a href="full.jpg" data-tags="landscape,nature" data-size="large" data-width="1200" data-height="800">
323
+ <img src="thumb.jpg" alt="Photo" data-focus="0.5 0.3" data-blurhash="LEHV6nWB2y...">
250
324
  </a>
251
325
  </div>
252
326
  ```