js-cloudimage-360-view 4.0.0 → 4.1.1

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
@@ -1,15 +1,15 @@
1
1
  <p align="center">
2
- <a href="https://www.cloudimage.io/#gh-light-mode-only">
3
- <img
4
- alt="cloudimage logo"
5
- src="https://scaleflex.cloudimg.io/v7/cloudimage.io/LOGO+WITH+SCALEFLEX-01.png?vh=f6080d&w=350">
2
+ <a href="https://www.scaleflex.com/en/home">
3
+ <img src="https://scaleflex.cloudimg.io/v7/cloudimage.io/LOGO+WITH+SCALEFLEX-01.png?vh=f6080d&w=350" alt="Cloudimage logo">
6
4
  </a>
7
5
  </p>
8
- <p align="center"><h1 align="center">JS Cloudimage 360 View
9
- </h1></p>
6
+
7
+ <h1 align="center">JS Cloudimage 360 View</h1>
8
+
10
9
  <p align="center">
11
- <em>360 Views, Infinite Possibilities: Unleash the Power of js-cloudimage-360-view!</em>
10
+ <strong>A powerful JavaScript library for creating interactive 360-degree product views</strong>
12
11
  </p>
12
+
13
13
  <p align="center">
14
14
  <a href="https://github.com/scaleflex/js-cloudimage-360-view/releases">
15
15
  <img src="https://img.shields.io/github/v/release/scaleflex/js-cloudimage-360-view" alt="Release">
@@ -18,395 +18,1091 @@
18
18
  <img src="https://img.shields.io/bundlephobia/min/js-cloudimage-360-view" alt="Size">
19
19
  </a>
20
20
  <a href="https://img.shields.io/npm/dt/js-cloudimage-360-view?logoColor=orange">
21
- <img src="https://img.shields.io/npm/dt/js-cloudimage-360-view?logoColor=orange" alt="Download">
22
- </a>
23
- <a href="#contributing">
24
- <img src="https://img.shields.io/badge/contributions-welcome-orange.svg" alt="Contributions welcome">
21
+ <img src="https://img.shields.io/npm/dt/js-cloudimage-360-view?logoColor=orange" alt="Downloads">
25
22
  </a>
26
23
  <a href="https://opensource.org/licenses/MIT">
27
24
  <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License">
28
25
  </a>
29
- <a href="https://www.scaleflex.com/en/home">
30
- <img src="https://img.shields.io/badge/%3C%2F%3E%20with%20%E2%99%A5%20-Scaleflex%20team-6986fa.svg" alt="Scaleflex team">
31
- </a>
32
26
  <a href="https://www.cloudimage.io/en/home">
33
- <img src="https://img.shields.io/badge/Powered%20by-cloudimage-blue" alt="Cloudimage">
27
+ <img src="https://img.shields.io/badge/Powered%20by-Cloudimage-blue" alt="Cloudimage">
34
28
  </a>
35
29
  </p>
36
- <p align="center"><!-- default option, no dependency badges. -->
37
- </p>
30
+
38
31
  <p align="center">
39
- <!-- default option, no dependency badges. -->
32
+ <a href="https://scaleflex.github.io/js-cloudimage-360-view/">View Demo</a> ·
33
+ <a href="https://github.com/scaleflex/js-cloudimage-360-view/issues">Report Bug</a> ·
34
+ <a href="https://github.com/scaleflex/js-cloudimage-360-view/issues">Request Feature</a>
40
35
  </p>
41
- <br>
42
36
 
43
- ## 🔗 Table of Contents
44
-
45
- - [📍 Overview](#-overview)
46
- - [👾 Features](#-features)
47
- - [🚀 Getting Started](#-getting-started)
48
- - [⚙️ Installation](#installation)
49
- - [Option 1: Add via CDN](#option-1-add-via-cdn)
50
- - [Option 2: Install with Package Manager](#option-2-install-with-package-manager)
51
- - [🛠️ Usage](#-usage)
52
- - [⚙️ Configuration Options](#configuration-options)
53
- - [Method 1: Initialization via JavaScript Code](#method-1-initialization-via-javascript-code)
54
- - [Method 2: Initialization via Data Attributes](#method-2-initialization-via-data-attributes)
55
- - [🗺️ Hotspots or Markers Configuration](#-hotspots-or-markers-configuration)
56
- - [🗺️ Cloudimage responsive integration](#-cloudimage-responsive-integration)
57
- - [🔧 Methods](#-methods)
58
- - [getViewById](#getviewbyidid)
59
- - [getViews](#getviews)
60
- - [updateView](#updateviewid-config)
61
- - [onMoveHandler](#onmovehandlermovingdirection-itemsSkippedX-itemsSkippedY)
62
- - [🔰 Contributing](#-contributing)
63
- - [🎗 License](#-license)
37
+ ---
38
+
39
+ ## Table of Contents
40
+
41
+ - [Overview](#overview)
42
+ - [Features](#features)
43
+ - [Quick Start](#quick-start)
44
+ - [Installation](#installation)
45
+ - [Usage](#usage)
46
+ - [React / Next.js](#react--nextjs)
47
+ - [Configuration Options](#configuration-options)
48
+ - [Event Callbacks](#event-callbacks)
49
+ - [Hotspots](#hotspots)
50
+ - [Interaction Hints](#interaction-hints)
51
+ - [Styling & Theming](#styling--theming)
52
+ - [Methods](#methods)
53
+ - [Cloudimage Integration](#cloudimage-integration)
54
+ - [Browser Support](#browser-support)
55
+ - [Migration Guide (v3 → v4)](#migration-guide-v3--v4)
56
+ - [Contributing](#contributing)
57
+ - [License](#license)
64
58
 
65
59
  ---
66
60
 
67
- ## 📍 Overview
61
+ ## Overview
68
62
 
69
- The js-cloudimage-360-view project revolutionizes interactive 360-degree image viewing experiences. With robust build and deployment scripts, it simplifies development processes. Key features include viewer initialization, hotspot functionality, and dynamic configuration utilities. Ideal for e-commerce platforms and virtual tours, it offers immersive and engaging user experiences.
63
+ JS Cloudimage 360 View enables you to create stunning, interactive 360-degree product views for your website. Perfect for e-commerce platforms, virtual tours, and product showcases, it provides an immersive viewing experience that lets users explore products from every angle.
64
+
65
+ ### Why Choose This Library?
66
+
67
+ - **Easy Integration** - Get started in minutes with CDN or npm
68
+ - **Fully Customizable** - CSS variables, callbacks, and extensive configuration options
69
+ - **Mobile-Friendly** - Touch and swipe support out of the box
70
+ - **Performance Optimized** - Lazy loading, responsive images, and efficient rendering
71
+ - **Feature Rich** - Hotspots, zoom, fullscreen, autoplay, and more
70
72
 
71
73
  ---
72
- ## 👾 Features
73
74
 
74
- | | Feature | Summary |
75
- | :--- | :---: | :--- |
76
- | ⚙️ | **Image Viewing** | <ul><li>Enables interactive 360-degree image viewing with smooth transitions</li><li>Supports high-resolution images for detailed visualization</li><li>Touch and drag navigation for user-friendly experiences</li></ul> |
77
- | 🔩 | **Customization** | <ul><li>Offers customizable settings for rotation speed, direction, and initial angle</li><li>Supports multiple display modes and responsive adjustments</li><li>Adaptable to various website designs for seamless integration</li></ul> |
78
- | 📄 | **Documentation** | <ul><li>Comprehensive guides on installation and usage</li><li>Step-by-step instructions for integration and configuration</li><li>Provides examples to help users implement the plugin quickly</li></ul> |
79
- | 🔌 | **Framework Support** | <ul><li>Easily integrates with popular JavaScript frameworks</li><li>Includes clear instructions for setup in React, Vue, Angular, and vanilla JavaScript</li><li>Adjustable settings to adapt to project requirements</li></ul> |
80
- | ⚡️ | **Performance** | <ul><li>Optimized for fast loading and minimal resource consumption</li><li>Utilizes lazy loading and caching to improve load times</li><li>Lightweight script ensures minimal impact on page performance</li></ul> |
81
- | 📦 | **Dependencies** | <ul><li>Minimal dependencies for essential functionality only</li></ul> |
75
+ ## Features
76
+
77
+ | Feature | Description |
78
+ |---------|-------------|
79
+ | **360° Rotation** | Smooth horizontal and vertical rotation with customizable speed |
80
+ | **Touch & Drag** | Intuitive mouse and touch controls with inertia/momentum |
81
+ | **Pinch-to-Zoom** | Natural pinch gesture zooming on mobile devices |
82
+ | **Autoplay** | Automatic rotation with configurable behavior and direction |
83
+ | **Zoom** | Pointer zoom and magnifier glass for detailed views |
84
+ | **Fullscreen** | Immersive fullscreen mode with ESC key support |
85
+ | **Hotspots** | Interactive markers with tooltips for highlighting features |
86
+ | **Keyboard Navigation** | Arrow key support for accessibility |
87
+ | **Lazy Loading** | Optimized loading for better performance |
88
+ | **Responsive** | Works on all screen sizes with Cloudimage CDN integration |
89
+ | **Theming** | CSS variables for easy customization |
90
+ | **Event Callbacks** | Hook into viewer lifecycle and user interactions |
82
91
 
83
92
  ---
84
93
 
85
- ## 🚀 Getting Started
94
+ ## Quick Start
86
95
 
87
- ## ⚙️ Installation
96
+ Add the library via CDN and create your first 360 viewer in seconds:
88
97
 
89
- You can install `js-cloudimage-360-view` using one of the following methods:
98
+ ```html
99
+ <!-- Add the library (CSS is auto-injected) -->
100
+ <script src="https://scaleflex.cloudimg.io/v7/plugins/js-cloudimage-360-view/latest/js-cloudimage-360-view.min.js"></script>
101
+
102
+ <!-- Create a container with data attributes -->
103
+ <div
104
+ class="cloudimage-360"
105
+ data-folder="https://scaleflex.cloudimg.io/v7/demo/360-car/"
106
+ data-filename-x="car-{index}.jpg"
107
+ data-amount-x="36"
108
+ ></div>
109
+
110
+ <!-- Initialize -->
111
+ <script>
112
+ const viewer = new window.CI360();
113
+ viewer.initAll();
114
+ </script>
115
+ ```
116
+
117
+ ---
90
118
 
91
- ### Option 1: Add via CDN
119
+ ## Installation
92
120
 
93
- Include the CDN link to the `js-cloudimage-360-view` library at the end of your `<body>` tag. Additionally, make sure to include the corresponding CSS file for proper styling:
121
+ ### Option 1: CDN (Recommended for Quick Setup)
94
122
 
95
123
  ```html
96
- <link rel="stylesheet" href="https://scaleflex.cloudimg.io/v7/plugins/js-cloudimage-360-view/latest/js-cloudimage-360-view.min.css">
97
- <script src="https://scaleflex.cloudimg.io/v7/plugins/js-cloudimage-360-view/latest/js-cloudimage-360-view.min.js?func=proxy"></script>
124
+ <script src="https://scaleflex.cloudimg.io/v7/plugins/js-cloudimage-360-view/latest/js-cloudimage-360-view.min.js"></script>
98
125
  ```
99
126
 
100
- ### Note:
101
- To ensure the `js-cloudimage-360-view` functionality works correctly, **you must also include the CSS file**. This is crucial for proper styling and display of the plugin.
127
+ > **Note:** CSS is automatically injected by the script - no separate stylesheet needed.
102
128
 
103
- This is the quickest way to get started without additional setup.
104
- #### Option 2: Install with Package Manager
129
+ ### Option 2: Package Manager
105
130
 
106
- You can add `js-cloudimage-360-view` to your project using either npm or Yarn:
131
+ ```bash
132
+ # npm
133
+ npm install js-cloudimage-360-view
107
134
 
108
- For npm:
135
+ # yarn
136
+ yarn add js-cloudimage-360-view
109
137
 
110
- ```sh
111
- npm install js-cloudimage-360-view
138
+ # pnpm
139
+ pnpm add js-cloudimage-360-view
112
140
  ```
113
141
 
114
- For Yarn:
142
+ Then import in your JavaScript:
115
143
 
116
- ```sh
117
- yarn add js-cloudimage-360-view
144
+ ```javascript
145
+ import CI360 from 'js-cloudimage-360-view';
146
+ import 'js-cloudimage-360-view/css';
147
+ ```
148
+
149
+ ---
150
+
151
+ ## Usage
152
+
153
+ ### Method 1: Data Attributes (Declarative)
154
+
155
+ The simplest way to create a 360 viewer using HTML data attributes:
156
+
157
+ ```html
158
+ <div
159
+ id="my-360-viewer"
160
+ class="cloudimage-360"
161
+ data-folder="https://your-domain.com/images/"
162
+ data-filename-x="{index}.jpg"
163
+ data-amount-x="36"
164
+ data-autoplay
165
+ data-fullscreen
166
+ data-magnifier="2"
167
+ ></div>
168
+
169
+ <script>
170
+ const viewer = new CI360();
171
+ viewer.initAll(); // Initializes all elements with class "cloudimage-360"
172
+ </script>
118
173
  ```
119
174
 
120
- Then, import it in your JavaScript file:
175
+ ### Method 2: JavaScript Configuration (Programmatic)
176
+
177
+ For more control, initialize with a JavaScript configuration object:
121
178
 
122
179
  ```javascript
123
- import CloudImage360 from 'js-cloudimage-360-view';
180
+ const viewer = new CI360();
181
+
182
+ const container = document.getElementById('product-viewer');
183
+
184
+ const config = {
185
+ folder: 'https://your-domain.com/images/',
186
+ filenameX: 'product-{index}.jpg',
187
+ amountX: 36,
188
+ autoplay: true,
189
+ speed: 100,
190
+ dragSpeed: 150,
191
+ fullscreen: true,
192
+ magnifier: 2,
193
+ pointerZoom: 2,
194
+ inertia: true,
195
+
196
+ // Event callbacks
197
+ onReady: () => console.log('Viewer ready!'),
198
+ onSpin: (e) => console.log(`Frame: ${e.activeImageX + 1}/${e.amountX}`),
199
+ };
200
+
201
+ viewer.init(container, config);
124
202
  ```
125
203
 
126
- OR
204
+ ### X and Y Axis Rotation
205
+
206
+ Support 360° rotation on both axes for full product exploration:
127
207
 
128
208
  ```javascript
129
- window.CI360
209
+ const config = {
210
+ folder: 'https://your-domain.com/images/',
211
+ filenameX: 'product-x-{index}.jpg',
212
+ filenameY: 'product-y-{index}.jpg',
213
+ amountX: 36,
214
+ amountY: 18,
215
+ autoplayBehavior: 'spin-xy', // Options: 'spin-x', 'spin-y', 'spin-xy', 'spin-yx'
216
+ };
130
217
  ```
131
218
 
219
+ ---
132
220
 
133
- Choose the method that best suits your project setup, and refer to the documentation for configuration options and usage examples.
221
+ ## React / Next.js
134
222
 
135
- ### 🛠️ Usage
223
+ The library provides a React wrapper for seamless integration with React and Next.js applications.
136
224
 
137
- To use `js-cloudimage-360-view`, you need to initialize an instance of the viewer. You can either initialize a specific view or initialize all instances with a common selector.
225
+ ### Installation
138
226
 
139
- #### Initialize a Single View
227
+ ```bash
228
+ npm install js-cloudimage-360-view
229
+ ```
140
230
 
141
- To initialize a single 360-degree view, use the following code:
231
+ ### Basic Usage
232
+
233
+ ```tsx
234
+ import { CI360Viewer } from 'js-cloudimage-360-view/react';
235
+ import 'js-cloudimage-360-view/css';
236
+
237
+ function ProductView() {
238
+ return (
239
+ <CI360Viewer
240
+ folder="https://example.com/images/"
241
+ filenameX="product-{index}.jpg"
242
+ amountX={36}
243
+ autoplay
244
+ fullscreen
245
+ style={{ width: '100%', maxWidth: 600, height: 400 }}
246
+ />
247
+ );
248
+ }
249
+ ```
142
250
 
143
- ```javascript
144
- const cloudimage360 = new CloudImage360();
251
+ ### Imperative Control with Ref
252
+
253
+ Use a ref to control the viewer programmatically:
254
+
255
+ ```tsx
256
+ import { useRef } from 'react';
257
+ import { CI360Viewer, CI360ViewerRef } from 'js-cloudimage-360-view/react';
258
+ import 'js-cloudimage-360-view/css';
259
+
260
+ function ProductView() {
261
+ const viewerRef = useRef<CI360ViewerRef>(null);
262
+
263
+ return (
264
+ <>
265
+ <CI360Viewer
266
+ ref={viewerRef}
267
+ folder="https://example.com/images/"
268
+ filenameX="{index}.jpg"
269
+ amountX={36}
270
+ onSpin={(e) => console.log(`Frame: ${e.activeImageX}`)}
271
+ />
272
+ <button onClick={() => viewerRef.current?.play()}>Play</button>
273
+ <button onClick={() => viewerRef.current?.stop()}>Stop</button>
274
+ <button onClick={() => viewerRef.current?.goToFrame(17)}>Go to Frame 17</button>
275
+ </>
276
+ );
277
+ }
278
+ ```
145
279
 
146
- const suvCarContainer = document.getElementById('gurkha-suv');
280
+ ### Available Ref Methods
147
281
 
148
- const config = {
149
- folder: 'https://scaleflex.cloudimg.io/v7/demo/suv-orange-car-360/',
150
- filenameX: 'orange-{index}.jpg',
151
- amountX: 73,
152
- responsive: 'scaleflex',
153
- };
282
+ | Method | Description |
283
+ |--------|-------------|
284
+ | `play()` | Start autoplay |
285
+ | `stop()` | Stop autoplay |
286
+ | `moveLeft(steps?)` | Move left by specified frames (default: 1) |
287
+ | `moveRight(steps?)` | Move right by specified frames (default: 1) |
288
+ | `moveTop(steps?)` | Move up on Y-axis (default: 1) |
289
+ | `moveBottom(steps?)` | Move down on Y-axis (default: 1) |
290
+ | `zoomIn()` | Toggle zoom in |
291
+ | `zoomOut()` | Zoom out |
292
+ | `goToFrame(frame, hotspotId?)` | Animate to specific frame |
293
+ | `getViewer()` | Get underlying viewer instance |
294
+
295
+ ### With Hotspots
296
+
297
+ ```tsx
298
+ import { CI360Viewer, Hotspot } from 'js-cloudimage-360-view/react';
299
+
300
+ const hotspots: Hotspot[] = [
301
+ {
302
+ id: 'feature-1',
303
+ label: 'Engine',
304
+ orientation: 'x',
305
+ containerSize: [1200, 800],
306
+ positions: { 0: { x: 500, y: 300 } },
307
+ content: '<div>Engine details</div>',
308
+ },
309
+ ];
154
310
 
155
- instance.init(suvCarContainer, config);
311
+ function ProductView() {
312
+ return (
313
+ <CI360Viewer
314
+ folder="https://example.com/images/"
315
+ filenameX="{index}.jpg"
316
+ amountX={36}
317
+ hotspots={hotspots}
318
+ />
319
+ );
320
+ }
156
321
  ```
157
322
 
158
- #### Initialize All Instances
323
+ ### Next.js (SSR)
159
324
 
160
- To initialize all instances with a common selector, use the following code:
325
+ For Next.js applications, use dynamic import to disable server-side rendering:
161
326
 
162
- ```javascript
163
- instance.initAll('.cloudimage-360');
327
+ ```tsx
328
+ import dynamic from 'next/dynamic';
329
+ import 'js-cloudimage-360-view/css';
330
+
331
+ const CI360Viewer = dynamic(
332
+ () => import('js-cloudimage-360-view/react').then(mod => mod.CI360Viewer),
333
+ { ssr: false }
334
+ );
335
+
336
+ export default function ProductPage() {
337
+ return (
338
+ <CI360Viewer
339
+ folder="https://example.com/images/"
340
+ filenameX="{index}.jpg"
341
+ amountX={36}
342
+ />
343
+ );
344
+ }
164
345
  ```
165
346
 
166
- This will apply the 360-degree viewer to all elements matching the specified selector.
347
+ ### useCI360 Hook
348
+
349
+ For advanced use cases, you can use the `useCI360` hook directly:
350
+
351
+ ```tsx
352
+ import { useRef } from 'react';
353
+ import { useCI360 } from 'js-cloudimage-360-view/react';
354
+
355
+ function CustomViewer() {
356
+ const containerRef = useRef<HTMLDivElement>(null);
357
+ const { viewer, isReady } = useCI360(containerRef, {
358
+ folder: 'https://example.com/images/',
359
+ filenameX: '{index}.jpg',
360
+ amountX: 36,
361
+ onReady: () => console.log('Viewer ready!'),
362
+ });
363
+
364
+ return (
365
+ <div>
366
+ <div ref={containerRef} style={{ width: 600, height: 400 }} />
367
+ {isReady && <p>Viewer is ready!</p>}
368
+ </div>
369
+ );
370
+ }
371
+ ```
372
+
373
+ ### TypeScript Support
374
+
375
+ The React wrapper is fully typed. Import types as needed:
376
+
377
+ ```tsx
378
+ import type {
379
+ CI360ViewerProps,
380
+ CI360ViewerRef,
381
+ CI360Config,
382
+ SpinEventData,
383
+ Hotspot,
384
+ } from 'js-cloudimage-360-view/react';
385
+ ```
167
386
 
387
+ ---
168
388
 
169
- ### ⚙️ Configuration Options
389
+ ## Configuration Options
390
+
391
+ All options can be set via JavaScript config or HTML data attributes.
392
+
393
+ ### Image Source Options
394
+
395
+ | Option | Data Attribute | Default | Description |
396
+ |--------|----------------|---------|-------------|
397
+ | `folder` | `data-folder` | `'/'` | Path to the folder containing images |
398
+ | `filenameX` | `data-filename-x` | `'image-{index}.jpg'` | Filename pattern for X-axis images. Use `{index}` as placeholder |
399
+ | `filenameY` | `data-filename-y` | `null` | Filename pattern for Y-axis images |
400
+ | `imageListX` | `data-image-list-x` | `null` | Array of image URLs for X-axis (alternative to folder/filename) |
401
+ | `imageListY` | `data-image-list-y` | `null` | Array of image URLs for Y-axis |
402
+ | `amountX` | `data-amount-x` | `0` | Total number of X-axis images |
403
+ | `amountY` | `data-amount-y` | `0` | Total number of Y-axis images |
404
+ | `indexZeroBase` | `data-index-zero-base` | `0` | Starting index for image filenames |
405
+
406
+ ### Behavior Options
407
+
408
+ | Option | Data Attribute | Default | Description |
409
+ |--------|----------------|---------|-------------|
410
+ | `autoplay` | `data-autoplay` | `false` | Enable automatic rotation |
411
+ | `autoplayBehavior` | `data-autoplay-behavior` | `'spin-x'` | Autoplay pattern: `'spin-x'`, `'spin-y'`, `'spin-xy'`, `'spin-yx'` |
412
+ | `autoplayReverse` | `data-autoplay-reverse` | `false` | Reverse autoplay direction |
413
+ | `playOnce` | `data-play-once` | `false` | Stop after one complete rotation |
414
+ | `speed` | `data-speed` | `80` | Autoplay speed (ms between frames) |
415
+ | `inertia` | `data-inertia` | `false` | Enable momentum after drag release |
416
+
417
+ ### Control Options
418
+
419
+ | Option | Data Attribute | Default | Description |
420
+ |--------|----------------|---------|-------------|
421
+ | `draggable` | `data-draggable` | `true` | Enable mouse drag rotation |
422
+ | `swipeable` | `data-swipeable` | `true` | Enable touch swipe rotation |
423
+ | `dragSpeed` | `data-drag-speed` | `150` | Drag sensitivity |
424
+ | `dragReverse` | `data-drag-reverse` | `false` | Reverse drag direction |
425
+ | `keys` | `data-keys` | `false` | Enable keyboard arrow navigation |
426
+ | `keysReverse` | `data-keys-reverse` | `false` | Reverse keyboard direction |
427
+ | `stopAtEdges` | `data-stop-at-edges` | `false` | Stop rotation at first/last frame |
428
+ | `pinchZoom` | `data-pinch-zoom` | `true` | Enable pinch-to-zoom on touch devices |
429
+
430
+ ### Display Options
431
+
432
+ | Option | Data Attribute | Default | Description |
433
+ |--------|----------------|---------|-------------|
434
+ | `fullscreen` | `data-fullscreen` | `false` | Show fullscreen button |
435
+ | `magnifier` | `data-magnifier` | `null` | Magnifier zoom level (1-5) |
436
+ | `pointerZoom` | `data-pointer-zoom` | `0` | Pointer zoom level on click (1-5) |
437
+ | `bottomCircle` | `data-bottom-circle` | `true` | Show 360° progress indicator |
438
+ | `bottomCircleOffset` | `data-bottom-circle-offset` | `5` | Progress indicator offset (px) |
439
+ | `initialIconShown` | `data-initial-icon` | `true` | Show 360° icon on load |
440
+ | `lazyload` | `data-lazyload` | `true` | Enable lazy loading |
441
+ | `hints` | `data-hints` | `true` | Show interaction hints on load |
442
+ | `theme` | `data-theme` | `null` | Color theme: `'light'` or `'dark'` |
443
+ | `hotspotTimelineOnClick` | `data-hotspot-timeline-on-click` | `true` | Show hotspot popup when clicking timeline dot |
444
+
445
+ ### Cloudimage CDN Options
446
+
447
+ | Option | Data Attribute | Default | Description |
448
+ |--------|----------------|---------|-------------|
449
+ | `ciToken` | `data-responsive` | `null` | Cloudimage token for responsive images |
450
+ | `ciFilters` | `data-filters` | `null` | Cloudimage filters |
451
+ | `ciTransformation` | `data-transformation` | `null` | Cloudimage transformations |
170
452
 
171
- When initializing the `js-cloudimage-360-view`, you can customize various configuration options. Below is a list of available options, their required status, default values, and the corresponding data attributes you can use in HTML.
453
+ ---
172
454
 
173
- #### Method 1: Initialization via JavaScript Code
174
- To initialize a view programmatically, use the following configuration options:
455
+ ## Event Callbacks
175
456
 
457
+ Hook into viewer events for custom functionality. Callbacks are only available via JavaScript configuration.
176
458
 
177
- #### Method 2: Initialization via Data Attributes
178
- You can also initialize the view using HTML data attributes, which correspond to the configuration options listed below.
459
+ | Callback | Event Data | Description |
460
+ |----------|------------|-------------|
461
+ | `onReady` | `{ viewerId }` | Viewer initialized and ready |
462
+ | `onLoad` | `{ viewerId, imagesX, imagesY }` | All images loaded |
463
+ | `onSpin` | `{ viewerId, direction, activeImageX, activeImageY, amountX, amountY }` | Each rotation frame |
464
+ | `onAutoplayStart` | `{ viewerId }` | Autoplay started |
465
+ | `onAutoplayStop` | `{ viewerId }` | Autoplay stopped |
466
+ | `onDragStart` | `{ viewerId }` | User started dragging |
467
+ | `onDragEnd` | `{ viewerId }` | User stopped dragging |
468
+ | `onZoomIn` | `{ viewerId, zoomLevel }` | Pointer zoom activated |
469
+ | `onZoomOut` | `{ viewerId }` | Pointer zoom deactivated |
470
+ | `onFullscreenOpen` | `{ viewerId }` | Fullscreen mode opened |
471
+ | `onFullscreenClose` | `{ viewerId }` | Fullscreen mode closed |
472
+
473
+ ### Example
179
474
 
180
- For example:
181
- ```html
182
- <div id="gurkha-suv"
183
- data-folder="/path/to/images/"
184
- data-api-version="v7"
185
- data-amount-x="73"
186
- data-speed="80"
187
- data-draggable="true">
188
- </div>
189
- ```
190
- | Option | Data Attribute | Required | Default Value | Description |
191
- | ---------------------| --------------------------| -------- | ----------------------------------------------- | ------------------------------------------------- |
192
- | `folder` | `data-folder` | Yes | `'/'` | The path to the folder containing the images. |
193
- | `apiVersion` | `data-api-version` | No | `'v7'` | The API version to use. |
194
- | `filenameX` | `data-filename-x` | Yes | `'image-{index}.jpg'` | The filename pattern for the X-axis images. |
195
- | `filenameY` | `data-filename-y` | No | `null` | The filename pattern for the Y-axis images (optional). |
196
- | `imageListX` | `data-image-list-x` | No | `null` | An array of images for the X-axis (optional). |
197
- | `imageListY` | `data-image-list-y` | No | `null` | An array of images for the Y-axis (optional). |
198
- | `indexZeroBase` | `data-index-zero-base` | No | `0` | Whether the index starts from 0. |
199
- | `amountX` | `data-amount-x` | Yes | `0` | Total number of X-axis images. |
200
- | `amountY` | `data-amount-y` | No | `0` | Total number of Y-axis images (optional). |
201
- | `speed` | `data-speed` | No | `80` | The speed of the rotation in milliseconds. |
202
- | `dragSpeed` | `data-drag-speed` | No | `150` | The speed when dragging the image. |
203
- | `draggable` | `data-draggable` | No | `true` | Enables dragging functionality. |
204
- | `swipeable` | `data-swipeable` | No | `true` | Enables swipe functionality on touch devices. |
205
- | `keys` | `data-keys` | No | `false` | Enables keyboard navigation. |
206
- | `keysReverse` | `data-keys-reverse` | No | `false` | Reverses keyboard navigation controls. |
207
- | `autoplay` | `data-autoplay` | No | `false` | Automatically plays the rotation. |
208
- | `autoplayBehavior` | `data-autoplay-behavior` | No | `AUTOPLAY_BEHAVIOR.SPIN_X` | Defines how autoplay behaves. |
209
- | `playOnce` | `data-play-once` | No | `false` | Plays the animation only once. |
210
- | `autoplayReverse` | `data-autoplay-reverse` | No | `false` | Plays the autoplay in reverse. |
211
- | `pointerZoom` | `data-pointer-zoom` | No | `0` | Defines the zoom level on pointer hover. |
212
- | `fullscreen` | `data-fullscreen` | No | `false` | Enables fullscreen mode. |
213
- | `magnifier` | `data-magnifier` | No | `null` | Defines the magnification level (optional). |
214
- | `bottomCircle` | `data-bottom-circle` | No | `true` | Displays the bottom circle navigation. |
215
- | `bottomCircleOffset` | `data-bottom-circle-offset`| No | `5` | The offset of the bottom circle from the container.|
216
- | `ciToken` | `data-responsive` | No | `null` | Token for Cloudimage API authentication (optional). [🗺️ Cloudimage responsive integration](#-cloudimage-responsive-integration) |
217
- | `ciFilters` | `data-filters` | No | `null` | Filters applied to Cloudimage images (optional). |
218
- | `ciTransformation` | `data-transformation` | No | `null` | Transformations for Cloudimage images (optional). |
219
- | `lazyload` | `data-lazyload` | No | `true` | Enables lazy loading of images. |
220
- | `dragReverse` | `data-drag-reverse` | No | `false` | Reverses drag direction. |
221
- | `stopAtEdges` | `data-stop-at-edges` | No | `false` | Stops the rotation at the edges. |
222
- | `imageInfo` | `data-info` | No | `false` | Displays image information. |
223
- | `initialIconShown` | `data-initial-icon` | No | `true` | Shows the initial icon on load. |
224
-
225
-
226
- The library will automatically read these attributes to configure the instance.
227
-
228
- ### 🗺️ Hotspots or Markers Configuration
229
-
230
- An array defines the configuration for hotspots or markers that can be displayed on the 360 view. Each hotspot can provide additional information or interactivity.
231
- #### Hotspot Configuration Structure
232
- Each hotspot configuration consists of the following properties:
233
-
234
- | Property | Required | Description |
235
- | --------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
236
- | `id` | Yes | A unique identifier for the hotspot. |
237
- | `orientation` | Yes | The orientation of the hotspot (e.g., `'x'` for X-axis). |
238
- | `containerSize` | Yes | An array defining the width and height of the container in pixels (e.g., `[width, height]`). This size represents the dimensions of the container when you first start setting the hotspots. |
239
- | `positions` | Yes | An object where keys are indices (image indexes) representing the position of the hotspot for specific images. |
240
- | `content` | Yes | HTML content to display in the tooltip when the hotspot is hovered or clicked. |
241
- | `onClick` | No | A function that defines the behavior when the hotspot is clicked (optional). |
242
-
243
- #### Positions
244
- The `positions` property is an object where:
245
- - The key is the index of the image in the 360 view (e.g., 6, 7, 8, ...).
246
- - The value is an object with `x` and `y` properties, representing the coordinates of the hotspot on the image.
247
-
248
- If either the `x` or `y` value is `null`, it means that the hotspot will take the coordinates from the previous defined position for that index.
249
-
250
- For example:
251
475
  ```javascript
252
- positions: {
253
- 6: { x: 607, y: 246 },
254
- 7: { x: 619, y: null }, // y is null, so it takes the previous y (246)
255
- 8: { x: 630, y: null }, // y is null, so it takes the previous y (246)
256
- 9: { x: 637, y: null }, // y is null, so it takes the previous y (246)
257
- 10: { x: 642, y: null }, // y is null, so it takes the previous y (246)
258
- },
476
+ const config = {
477
+ folder: 'https://example.com/images/',
478
+ filenameX: '{index}.jpg',
479
+ amountX: 36,
480
+
481
+ onReady: (e) => {
482
+ console.log(`Viewer ${e.viewerId} is ready`);
483
+ },
484
+
485
+ onSpin: (e) => {
486
+ // Update custom progress indicator
487
+ const progress = ((e.activeImageX + 1) / e.amountX * 100).toFixed(0);
488
+ document.getElementById('progress').textContent = `${progress}%`;
489
+ },
490
+
491
+ onFullscreenOpen: () => {
492
+ // Pause background video when entering fullscreen
493
+ document.getElementById('bg-video')?.pause();
494
+ },
495
+ };
259
496
  ```
260
497
 
261
- #### Example Hotspot Configuration
262
- Here's an example configuration for multiple hotspots:
498
+ ---
499
+
500
+ ## Hotspots
501
+
502
+ Add interactive markers to highlight product features.
503
+
504
+ ### Configuration
505
+
263
506
  ```javascript
264
- const GURKHA_SUV_HOTSPOTS_CONFIG = [
507
+ const hotspots = [
265
508
  {
266
- id: 'hotspot-1',
509
+ id: 'feature-1',
267
510
  orientation: 'x',
268
- containerSize: [1170, 663],
511
+ containerSize: [1200, 800], // Reference container size for positioning
269
512
  positions: {
270
- 0: { x: 527, y: 319 },
271
- 1: { x: 527, y: 319 },
272
- 2: { x: 527, y: null }, // Takes the previous position
273
- 3: { x: 498, y: null }, // Takes the previous y (319)
274
- 4: { x: 470, y: null }, // Takes the previous y (319)
275
- // Additional positions...
513
+ 0: { x: 500, y: 300 },
514
+ 1: { x: 520, y: 300 },
515
+ 2: { x: 540, y: null }, // null inherits from previous frame
516
+ 3: { x: 560, y: null },
517
+ // ... positions for frames where hotspot is visible
518
+ },
519
+ content: '<div class="tooltip"><strong>Premium Feature</strong><p>Description here</p></div>',
520
+ onClick: () => {
521
+ console.log('Hotspot clicked!');
276
522
  },
277
- content: '<div class="tooltip">Info about Hotspot 1</div>',
278
523
  },
279
- // Additional hotspots...
280
524
  ];
525
+
526
+ const config = {
527
+ folder: 'https://example.com/images/',
528
+ filenameX: '{index}.jpg',
529
+ amountX: 36,
530
+ hotspots: hotspots,
531
+ };
281
532
  ```
282
- In the example above, the keys (0, 1, 2, 3, 4, ...) represent image indexes. If the `y` value is `null`, it inherits the `y` coordinate from the previous defined position. This allows for easier configuration and reduces redundancy.
283
-
284
- ### 🎨 Styling
285
- The following class names are used for styling various elements within the 360-degree viewer and hotspot functionality. Each class serves a specific purpose in controlling the appearance and behavior of the component.
286
- | Class Name | Description |
287
- | -------------------------------------- | -------------------------------------------------------------------------------------------------------- |
288
- | `cloudimage-360-transition-overlay` | Applies styling for the overlay that appears during transitions. |
289
- | `cloudimage-360-button` | Styles the main button for interacting with the 360 view. |
290
- | `cloudimage-360-magnifier-button` | Styles the button that activates the magnifier feature within the 360 view. |
291
- | `cloudimage-loading-spinner` | Styles the loading spinner displayed while the images are being loaded. |
292
- | `cloudimage-initial-icon` | Styles the initial icon displayed before the 360 view is fully loaded. |
293
- | `cloudimage-360-icons-container` | Styles the container for all icons associated with the 360 view (e.g., buttons, overlays). |
294
- | `cloudimage-360-hotspot-container` | Styles the container that holds the hotspots or markers in the 360 view. |
295
- | `cloudimage-360-fullscreen-modal` | Styles the modal that appears when the 360 view is in fullscreen mode. |
296
- | `cloudimage-360-fullscreen-button` | Styles the button that toggles the fullscreen mode of the 360 view. |
297
- | `cloudimage-360-close-icon` | Styles the close icon used to exit the fullscreen view. |
298
- | `cloudimage-360-view-360-circle` | Styles the circular view area of the 360 images. |
299
- | `cloudimage-360-popper` | Styles the popper element for displaying tooltips or additional information on hover or click. |
300
- | `cloudimage-360-hotspot` | Styles individual hotspots within the 360 view, allowing for customizable appearance and behavior. |
301
-
302
- Customize these class names in your CSS files to match your application's design requirements.
303
533
 
534
+ ### Hotspot Properties
304
535
 
305
- ## Methods
536
+ | Property | Required | Description |
537
+ |----------|----------|-------------|
538
+ | `id` | Yes | Unique identifier |
539
+ | `orientation` | Yes | `'x'` or `'y'` axis |
540
+ | `containerSize` | Yes | `[width, height]` reference dimensions |
541
+ | `positions` | Yes | Object mapping frame index to `{ x, y }` coordinates |
542
+ | `content` | Yes | HTML content for the tooltip |
543
+ | `label` | No | Short label for the hotspot (used in timeline tooltips) |
544
+ | `onClick` | No | Click handler function |
545
+
546
+ ### Hotspot Timeline
547
+
548
+ When hotspots are configured, a timeline navigation bar automatically appears below the viewer. This timeline shows:
549
+
550
+ - **Position indicator** - Shows current rotation position
551
+ - **Hotspot dots** - One dot per hotspot at its center frame position
552
+ - **Hover tooltips** - If a hotspot has a `label`, hovering over its dot shows a tooltip
553
+
554
+ Clicking a dot animates the viewer to that hotspot's position and optionally shows its popup.
555
+
556
+ #### Timeline Tooltips
557
+
558
+ Tooltips display the hotspot's `label` property when hovering over a timeline dot:
559
+
560
+ ```javascript
561
+ const hotspots = [
562
+ {
563
+ id: 'engine',
564
+ label: 'Engine Bay', // This text appears in the tooltip
565
+ orientation: 'x',
566
+ containerSize: [1200, 800],
567
+ positions: { 0: { x: 500, y: 300 }, /* ... */ },
568
+ content: '<div>Full hotspot content here</div>',
569
+ },
570
+ ];
571
+ ```
572
+
573
+ **Tooltip behavior:**
574
+ - Appears after a **400ms hover delay** to prevent accidental triggers
575
+ - Positioned above the dot with an arrow pointer
576
+ - Hidden on mouse leave or click (navigation)
577
+
578
+ #### Timeline Configuration
579
+
580
+ | Option | Default | Description |
581
+ |--------|---------|-------------|
582
+ | `hotspotTimelineOnClick` | `true` | Show hotspot popup when clicking a timeline dot |
583
+
584
+ ```javascript
585
+ const config = {
586
+ hotspots: [...],
587
+ hotspotTimelineOnClick: true, // Show popup on click (default)
588
+ // or
589
+ hotspotTimelineOnClick: false, // Only navigate, don't show popup
590
+ };
591
+ ```
592
+
593
+ #### Timeline CSS Variables
594
+
595
+ Customize the timeline appearance with CSS variables:
596
+
597
+ ```css
598
+ :root {
599
+ /* Timeline track */
600
+ --ci360-timeline-height: 6px;
601
+ --ci360-timeline-track-bg: rgba(0, 0, 0, 0.12);
602
+
603
+ /* Hotspot dots */
604
+ --ci360-timeline-dot-size: 18px;
605
+ --ci360-timeline-dot-color: var(--ci360-hotspot-color);
606
+ --ci360-timeline-dot-border: 2px solid #fff;
607
+
608
+ /* Position indicator */
609
+ --ci360-timeline-indicator-size: 12px;
610
+ --ci360-timeline-indicator-color: #333333;
611
+
612
+ /* Tooltip styling (matches theme) */
613
+ --ci360-timeline-tooltip-bg: rgba(255, 255, 255, 0.95);
614
+ --ci360-timeline-tooltip-color: #333333;
615
+ }
616
+
617
+ /* Dark theme uses dark tooltip */
618
+ .ci360-theme-dark {
619
+ --ci360-timeline-tooltip-bg: rgba(40, 40, 45, 0.95);
620
+ --ci360-timeline-tooltip-color: #e0e0e0;
621
+ }
622
+ ```
623
+
624
+ **Custom tooltip styling example:**
306
625
 
307
- ### `getViewById(id)`
308
- Returns the view object associated with the specified ID.
626
+ ```css
627
+ /* Increase tooltip font size */
628
+ .cloudimage-360-hotspot-timeline-tooltip {
629
+ font-size: 14px;
630
+ padding: 8px 16px;
631
+ }
632
+
633
+ /* Brand-colored tooltip */
634
+ .my-viewer {
635
+ --ci360-timeline-tooltip-bg: #2563eb;
636
+ --ci360-timeline-tooltip-color: #ffffff;
637
+ }
638
+ ```
639
+
640
+ ---
641
+
642
+ ## Interaction Hints
643
+
644
+ The viewer displays helpful hints at the bottom showing users how to interact with the 360° view. Hints are automatically generated based on enabled features and hide after the first interaction.
645
+
646
+ ### Configuration
309
647
 
310
648
  ```javascript
311
- getViewById(id)
649
+ const config = {
650
+ // Auto-detect hints based on enabled features (default)
651
+ hints: true,
652
+
653
+ // Disable hints
654
+ hints: false,
655
+
656
+ // Custom hints array
657
+ hints: ['drag', 'click', 'keys'],
658
+ };
312
659
  ```
313
660
 
314
- ### `getViews()`
315
- Returns an array of all the view objects currently available.
661
+ ### Available Hint Types
662
+
663
+ | Type | Desktop | Mobile | Description |
664
+ |------|---------|--------|-------------|
665
+ | `drag` | ✓ | - | "Drag to rotate" |
666
+ | `swipe` | - | ✓ | "Swipe to rotate" |
667
+ | `click` | ✓ | - | "Click to zoom" (when pointerZoom enabled) |
668
+ | `pinch` | - | ✓ | "Pinch to zoom" (when pinchZoom enabled) |
669
+ | `keys` | ✓ | - | "Use arrow keys" (when keys enabled) |
670
+
671
+ ---
672
+
673
+ ## Styling & Theming
674
+
675
+ ### Built-in Themes
676
+
677
+ Apply a theme by setting the `theme` option or using the `ci360-theme-dark` class:
316
678
 
317
679
  ```javascript
318
- getViews()
680
+ // Via config
681
+ const config = {
682
+ theme: 'dark', // or 'light'
683
+ // ...other options
684
+ };
685
+
686
+ // Or via HTML
687
+ <div class="cloudimage-360 ci360-theme-dark" ...></div>
688
+ ```
689
+
690
+ ### CSS Variables (Recommended)
691
+
692
+ The easiest way to customize the viewer appearance:
693
+
694
+ ```css
695
+ :root {
696
+ /* Buttons */
697
+ --ci360-button-bg: #f0f0f0;
698
+ --ci360-button-bg-hover: #e0e0e0;
699
+ --ci360-button-size: 40px;
700
+ --ci360-button-border-radius: 6px;
701
+ --ci360-button-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
702
+
703
+ /* Icons */
704
+ --ci360-icon-color: #37414b;
705
+ --ci360-icon-color-hover: #1a1f24;
706
+ --ci360-icon-size: 20px;
707
+
708
+ /* 360° Indicator */
709
+ --ci360-initial-icon-bg: rgba(255, 255, 255, 0.9);
710
+ --ci360-initial-icon-color: #505050;
711
+ --ci360-initial-icon-size: 80px;
712
+ --ci360-initial-icon-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
713
+
714
+ /* Loading Spinner */
715
+ --ci360-spinner-color: #fff;
716
+ --ci360-spinner-accent: #a3a3a3;
717
+ --ci360-spinner-size: 30px;
718
+
719
+ /* Fullscreen */
720
+ --ci360-fullscreen-bg: #fff;
721
+
722
+ /* Magnifier */
723
+ --ci360-magnifier-size: 250px;
724
+ --ci360-magnifier-border: 2px solid rgba(0, 0, 0, 0.3);
725
+ --ci360-magnifier-shadow: 0 8px 16px rgba(0, 0, 0, 0.4);
726
+
727
+ /* Hotspots */
728
+ --ci360-hotspot-color: #00aaff;
729
+ --ci360-hotspot-border: 1px solid #fff;
730
+ --ci360-hotspot-size: 18px;
731
+
732
+ /* Tooltips */
733
+ --ci360-popper-bg: rgba(255, 255, 255, 0.95);
734
+ --ci360-popper-color: #333;
735
+ --ci360-popper-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
736
+ --ci360-popper-border-radius: 6px;
737
+
738
+ /* Hints Overlay */
739
+ --ci360-hints-bg: rgba(0, 0, 0, 0.75);
740
+ --ci360-hints-color: #ffffff;
741
+ --ci360-hints-font-size: 14px;
742
+ --ci360-hints-border-radius: 12px;
743
+
744
+ /* Bottom Circle Indicator */
745
+ --ci360-circle-color-start: rgba(0, 0, 0, 0.05);
746
+ --ci360-circle-color-mid: rgba(0, 0, 0, 0.3);
747
+ --ci360-circle-color-end: rgba(0, 0, 0, 0.05);
748
+ --ci360-circle-dot-color: rgba(0, 0, 0, 0.4);
749
+
750
+ /* Other */
751
+ --ci360-focus-color: #0066cc;
752
+ --ci360-overlay-bg: rgba(255, 255, 255, 1);
753
+ }
319
754
  ```
320
755
 
321
- ### `updateView(id, config)`
322
- Updates the configuration of an existing view identified by its ID. If the configuration has changed significantly, the view will be destroyed and reinitialized; otherwise, it will simply be updated.
756
+ ### Custom Dark Theme Example
757
+
758
+ If you prefer to customize beyond the built-in dark theme:
759
+
760
+ ```css
761
+ .my-dark-viewer {
762
+ --ci360-button-bg: rgba(30, 30, 35, 0.9);
763
+ --ci360-button-bg-hover: rgba(45, 45, 50, 0.95);
764
+ --ci360-icon-color: #e0e0e0;
765
+ --ci360-icon-color-hover: #ffffff;
766
+ --ci360-fullscreen-bg: #1a1a1f;
767
+ --ci360-initial-icon-bg: rgba(30, 30, 35, 0.9);
768
+ --ci360-initial-icon-color: #e0e0e0;
769
+ --ci360-popper-bg: rgba(40, 40, 45, 0.95);
770
+ --ci360-popper-color: #e0e0e0;
771
+ --ci360-hints-bg: rgba(255, 255, 255, 0.12);
772
+ --ci360-circle-color-mid: rgba(255, 255, 255, 0.25);
773
+ --ci360-circle-dot-color: rgba(255, 255, 255, 0.4);
774
+ --ci360-overlay-bg: rgba(26, 26, 31, 1);
775
+ }
776
+ ```
777
+
778
+ ### Scope to Specific Viewer
779
+
780
+ ```css
781
+ #my-special-viewer {
782
+ --ci360-button-bg: #4a90d9;
783
+ --ci360-icon-color: #ffffff;
784
+ --ci360-hotspot-color: #ff6b6b;
785
+ }
786
+ ```
787
+
788
+ ### CSS Classes Reference
789
+
790
+ | Class | Description |
791
+ |-------|-------------|
792
+ | `.cloudimage-360` | Main container |
793
+ | `.cloudimage-360-inner-box` | Inner container |
794
+ | `.cloudimage-360-button` | Control buttons |
795
+ | `.cloudimage-360-icons-container` | Button container |
796
+ | `.cloudimage-initial-icon` | 360° indicator icon |
797
+ | `.cloudimage-360-view-360-circle` | Bottom progress indicator |
798
+ | `.cloudimage-loading-spinner` | Loading spinner |
799
+ | `.cloudimage-360-fullscreen-modal` | Fullscreen container |
800
+ | `.cloudimage-360-img-magnifier-glass` | Magnifier element |
801
+ | `.cloudimage-360-hotspot` | Hotspot marker |
802
+ | `.cloudimage-360-popper` | Hotspot tooltip |
803
+ | `.cloudimage-360-hints-overlay` | Hints overlay container |
804
+ | `.cloudimage-360-hints-container` | Hints content box |
805
+ | `.cloudimage-360-hotspot-timeline` | Hotspot timeline container |
806
+ | `.cloudimage-360-hotspot-timeline-track` | Timeline track |
807
+ | `.cloudimage-360-hotspot-timeline-dot` | Timeline hotspot dot |
808
+ | `.cloudimage-360-hotspot-timeline-indicator` | Timeline position indicator |
809
+ | `.cloudimage-360-hotspot-timeline-tooltip` | Timeline dot tooltip (appears on hover) |
810
+ | `.ci360-theme-dark` | Dark theme class |
811
+
812
+ ---
813
+
814
+ ## Methods
815
+
816
+ ### Instance Methods
323
817
 
324
818
  ```javascript
325
- updateView(id, config)
819
+ const viewer = new CI360();
820
+
821
+ // Initialize all viewers with class "cloudimage-360"
822
+ viewer.initAll();
823
+
824
+ // Initialize a specific container
825
+ viewer.init(containerElement, config);
826
+
827
+ // Get a viewer by its container ID
828
+ const view = viewer.getViewById('my-viewer');
829
+
830
+ // Get all viewer instances
831
+ const allViews = viewer.getViews();
832
+
833
+ // Update a viewer's configuration
834
+ viewer.updateView('my-viewer', { speed: 50, autoplay: true });
326
835
  ```
327
836
 
328
837
  ### View Methods
329
838
 
330
- #### `onMoveHandler(movingDirection, itemsSkippedX = 1, itemsSkippedY = 1)`
331
- Handles the movement of items in the view. It takes a direction and the number of items to skip horizontally and vertically.
839
+ ```javascript
840
+ const view = viewer.getViewById('my-viewer');
841
+
842
+ // Programmatically rotate the view
843
+ view.onMoveHandler('right', 1, 0); // Move right by 1 frame
844
+ view.onMoveHandler('left', 5, 0); // Move left by 5 frames
845
+ view.onMoveHandler('up', 0, 1); // Move up by 1 frame (Y-axis)
846
+ view.onMoveHandler('down', 0, 1); // Move down by 1 frame (Y-axis)
847
+
848
+ // Destroy the viewer
849
+ view.destroy();
850
+ ```
851
+
852
+ ---
853
+
854
+ ## Cloudimage Integration
855
+
856
+ Enhance performance with [Cloudimage](https://cloudimage.io) CDN for responsive, optimized images.
857
+
858
+ ### Setup
859
+
860
+ 1. Register at [cloudimage.io](https://cloudimage.io) to get your token
861
+ 2. Add the token to your viewer configuration:
332
862
 
333
863
  ```javascript
334
- onMoveHandler(movingDirection, itemsSkippedX = 1, itemsSkippedY = 1)
864
+ const config = {
865
+ folder: 'https://your-domain.com/images/',
866
+ filenameX: '{index}.jpg',
867
+ amountX: 36,
868
+ ciToken: 'your-cloudimage-token', // or use data-responsive attribute
869
+ };
335
870
  ```
336
871
 
337
- **Parameters:**
338
- - `movingDirection`: A string indicating the direction of movement (`'right'`, `'left'`, `'top'`, or `'bottom'`).
339
- - `itemsSkippedX`: The number of items to skip in the horizontal direction (default is 1).
340
- - `itemsSkippedY`: The number of items to skip in the vertical direction (default is 1).
872
+ ### Benefits
873
+
874
+ - **25GB free CDN traffic** per month
875
+ - **Automatic optimization** - WebP, AVIF conversion
876
+ - **Responsive images** - Serve the right size for each device
877
+ - **Global CDN** - Fast delivery worldwide
878
+ - **Image transformations** - Resize, crop, filters on-the-fly
341
879
 
342
880
  ---
343
881
 
344
- ## Cloudimage Responsive Integration
882
+ ## Browser Support
345
883
 
346
- ### Overview
884
+ | Browser | Version |
885
+ |---------|---------|
886
+ | Chrome | 69+ |
887
+ | Firefox | 105+ |
888
+ | Safari | 16.4+ |
889
+ | Edge | 79+ |
890
+ | iOS Safari | 16.4+ |
891
+ | Android Chrome | 69+ |
347
892
 
348
- Integrating Cloudimage for responsive images enhances the loading speed and performance of your website. This service delivers optimized images over a Content Delivery Network (CDN), ensuring that your images are served quickly and efficiently, regardless of the user's location.
893
+ > **Note:** This library uses OffscreenCanvas for optimal performance, which requires the browser versions listed above.
349
894
 
350
- ### How It Works
895
+ ---
351
896
 
352
- To see how Cloudimage transforms image delivery for responsive design, check out the [full article on Medium](https://medium.com/cloudimage/responsive-images-in-2019-now-easier-than-ever-b76e5a43c074). The article details the importance of responsive images in modern web development and how Cloudimage simplifies the process.
897
+ ## Migration Guide (v3 v4)
353
898
 
354
- ### Requirements
899
+ Version 4 introduces significant improvements in performance, customization, and developer experience. This guide helps you upgrade from v3.
355
900
 
356
- Before you start using the Cloudimage Responsive plugin, make sure you have the following:
901
+ ### Breaking Changes
357
902
 
358
- - **Cloudimage Token**: You'll need a unique Cloudimage token to deliver your images over their CDN.
903
+ #### 1. CSS Handling
359
904
 
360
- **Getting Your Token**:
361
- - Register at the [Cloudimage website](https://cloudimage.io).
362
- - After registration, you'll receive a token that allows you to access their services.
905
+ For CDN users, CSS is now auto-injected (same as v3):
363
906
 
364
- The token grants you **25GB of image cache** and **25GB of worldwide CDN traffic per month** for free. This is perfect for startups and small projects looking to enhance their website's performance without incurring costs.
907
+ ```html
908
+ <!-- v4: Just include the script -->
909
+ <script src=".../js-cloudimage-360-view.min.js"></script>
910
+ ```
365
911
 
912
+ For npm/bundler users, import CSS separately:
366
913
 
367
- ## 🔰 Contributing
914
+ ```javascript
915
+ import CI360 from 'js-cloudimage-360-view';
916
+ import 'js-cloudimage-360-view/css';
917
+ ```
368
918
 
369
- - **💬 [Join the Discussions](https://github.com/Scaleflex/js-cloudimage-360-view/discussions)**: Share your insights, provide feedback, or ask questions.
370
- - **🐛 [Report Issues](https://github.com/Scaleflex/js-cloudimage-360-view/issues)**: Submit bugs found or log feature requests for the `js-cloudimage-360-view` project.
371
- - **💡 [Submit Pull Requests](https://github.com/Scaleflex/js-cloudimage-360-view/blob/main/CONTRIBUTING.md)**: Review open PRs, and submit your own PRs.
919
+ #### 2. Initialization API Changed
372
920
 
373
- <details closed>
374
- <summary>Contributing Guidelines</summary>
921
+ ```javascript
922
+ // v3
923
+ window.CI360.init();
924
+ window.CI360.add('my-viewer');
925
+ window.CI360.update('my-viewer', true);
926
+ window.CI360.destroy();
927
+
928
+ // v4
929
+ const viewer = new CI360();
930
+ viewer.initAll(); // Initialize all
931
+ viewer.init(container, config); // Initialize specific container
932
+ viewer.updateView('my-viewer', newConfig); // Update with new config
933
+ viewer.getViewById('my-viewer').destroy(); // Destroy specific viewer
934
+ ```
375
935
 
376
- 1. **Fork the Repository**: Start by forking the project repository to your github account.
377
- 2. **Clone Locally**: Clone the forked repository to your local machine using a git client.
378
- ```sh
379
- git clone https://github.com/Scaleflex/js-cloudimage-360-view
380
- ```
381
- 3. **Create a New Branch**: Always work on a new branch, giving it a descriptive name.
382
- ```sh
383
- git checkout -b new-feature-x
384
- ```
385
- 4. **Make Your Changes**: Develop and test your changes locally.
386
- 5. **Commit Your Changes**: Commit with a clear message describing your updates.
387
- ```sh
388
- git commit -m 'Implemented new feature x.'
389
- ```
390
- 6. **Push to github**: Push the changes to your forked repository.
391
- ```sh
392
- git push origin new-feature-x
393
- ```
394
- 7. **Submit a Pull Request**: Create a PR against the original project repository. Clearly describe the changes and their motivations.
395
- 8. **Review**: Once your PR is reviewed and approved, it will be merged into the main branch. Congratulations on your contribution!
396
- </details>
936
+ #### 3. Browser Requirements Changed
397
937
 
398
- <details closed>
399
- <summary>Contributor Graph</summary>
938
+ v4 uses OffscreenCanvas for performance, requiring newer browsers:
939
+
940
+ | Browser | v3 | v4 |
941
+ |---------|-----|-----|
942
+ | Safari | 12+ | **16.4+** |
943
+ | iOS Safari | 12+ | **16.4+** |
944
+ | Firefox | 55+ | **105+** |
945
+ | Chrome | 60+ | 69+ |
946
+
947
+ ### Deprecated Configuration Options
948
+
949
+ The following options have been removed in v4:
950
+
951
+ | v3 Option | v4 Alternative |
952
+ |-----------|----------------|
953
+ | `data-box-shadow` | Use CSS: `.cloudimage-360 { box-shadow: ... }` |
954
+ | `data-ratio` | Container automatically maintains aspect ratio |
955
+ | `data-lazy-selector` | Use `data-lazyload` (boolean) |
956
+ | `data-hide-360-logo` | Use `data-initial-icon` (boolean, inverted) |
957
+ | `data-logo-src` | Custom logos not supported; use CSS to hide |
958
+ | `data-image-info` | Removed |
959
+ | `data-request-responsive-images` | Removed |
960
+ | `data-disable-drag` | Use `data-draggable` (inverted: `draggable="false"`) |
961
+ | `data-spin-reverse` | Use `data-drag-reverse` and `data-autoplay-reverse` |
962
+
963
+ ### Hotspot Configuration Changes
964
+
965
+ Hotspot properties have been simplified:
966
+
967
+ ```javascript
968
+ // v3 - Multiple specific properties
969
+ const hotspot = {
970
+ id: 'feature-1',
971
+ title: 'Feature Title',
972
+ description: 'Description text',
973
+ url: 'https://example.com',
974
+ newTab: true,
975
+ moreDetailsUrl: 'https://example.com/details',
976
+ moreDetailsTitle: 'Learn More',
977
+ popupSelector: '#custom-popup',
978
+ arrow: true,
979
+ placement: 'top',
980
+ offset: [0, 10],
981
+ positions: { 0: { x: 100, y: 200 } },
982
+ };
983
+
984
+ // v4 - Flexible HTML content
985
+ const hotspot = {
986
+ id: 'feature-1',
987
+ orientation: 'x',
988
+ containerSize: [1200, 800],
989
+ positions: { 0: { x: 100, y: 200 } },
990
+ content: `
991
+ <div class="my-tooltip">
992
+ <h3>Feature Title</h3>
993
+ <p>Description text</p>
994
+ <a href="https://example.com" target="_blank">Learn More</a>
995
+ </div>
996
+ `,
997
+ onClick: () => console.log('Clicked!'),
998
+ };
999
+ ```
1000
+
1001
+ | v3 Property | v4 Alternative |
1002
+ |-------------|----------------|
1003
+ | `title`, `description` | Use `content` with HTML |
1004
+ | `url`, `newTab` | Include `<a>` tag in `content` |
1005
+ | `moreDetailsUrl`, `moreDetailsTitle` | Include in `content` HTML |
1006
+ | `popupSelector` | Use `content` with your HTML |
1007
+ | `arrow`, `placement`, `offset` | Popper.js handles positioning automatically |
1008
+ | `open` | Removed; hotspots open on click/hover |
1009
+
1010
+ ### New Features in v4
1011
+
1012
+ Take advantage of these new capabilities:
1013
+
1014
+ #### CSS Variables for Theming
1015
+
1016
+ ```css
1017
+ :root {
1018
+ --ci360-button-bg: #f0f0f0;
1019
+ --ci360-icon-color: #333;
1020
+ --ci360-hotspot-color: #00aaff;
1021
+ }
1022
+ ```
1023
+
1024
+ #### Built-in Themes
1025
+
1026
+ ```html
1027
+ <div class="cloudimage-360 ci360-theme-dark" ...></div>
1028
+ ```
1029
+
1030
+ #### Event Callbacks
1031
+
1032
+ ```javascript
1033
+ const config = {
1034
+ onReady: (e) => console.log('Ready'),
1035
+ onSpin: (e) => console.log(`Frame: ${e.activeImageX}`),
1036
+ onFullscreenOpen: () => console.log('Fullscreen'),
1037
+ };
1038
+ ```
1039
+
1040
+ #### Interaction Hints
1041
+
1042
+ ```javascript
1043
+ const config = {
1044
+ hints: true, // Auto-detect hints
1045
+ // or
1046
+ hints: ['drag', 'click', 'keys'], // Custom hints
1047
+ };
1048
+ ```
1049
+
1050
+ #### Pinch-to-Zoom (Mobile)
1051
+
1052
+ ```javascript
1053
+ const config = {
1054
+ pinchZoom: true, // Enabled by default
1055
+ };
1056
+ ```
1057
+
1058
+ ### Quick Migration Checklist
1059
+
1060
+ - [ ] Add CSS file import alongside JS
1061
+ - [ ] Update initialization code to use `new CI360()`
1062
+ - [ ] Replace `data-disable-drag` with `data-draggable="false"`
1063
+ - [ ] Replace `data-spin-reverse` with `data-drag-reverse`
1064
+ - [ ] Replace `data-hide-360-logo` with `data-initial-icon="false"`
1065
+ - [ ] Update hotspot configs to use `content` instead of individual properties
1066
+ - [ ] Test on Safari 16.4+ (older versions not supported)
1067
+ - [ ] Consider adding CSS variables for customization
1068
+ - [ ] Consider adding event callbacks for analytics/tracking
1069
+
1070
+ ---
1071
+
1072
+ ## Contributing
1073
+
1074
+ We welcome contributions! Here's how you can help:
1075
+
1076
+ - **[Report bugs](https://github.com/Scaleflex/js-cloudimage-360-view/issues)** - Found a bug? Let us know!
1077
+ - **[Request features](https://github.com/Scaleflex/js-cloudimage-360-view/issues)** - Have an idea? Share it!
1078
+ - **[Submit PRs](https://github.com/Scaleflex/js-cloudimage-360-view/pulls)** - Code contributions are welcome!
1079
+ - **[Join discussions](https://github.com/Scaleflex/js-cloudimage-360-view/discussions)** - Ask questions, share insights
1080
+
1081
+ ### Development Setup
1082
+
1083
+ ```bash
1084
+ git clone https://github.com/Scaleflex/js-cloudimage-360-view.git
1085
+ cd js-cloudimage-360-view
1086
+ npm install
1087
+ npm run dev
1088
+ ```
1089
+
1090
+ <details>
1091
+ <summary><strong>Contributors</strong></summary>
400
1092
  <br>
401
- <p align="left">
402
- <a href="https://github.com{/Scaleflex/js-cloudimage-360-view/}graphs/contributors">
403
- <img src="https://contrib.rocks/image?repo=Scaleflex/js-cloudimage-360-view">
404
- </a>
405
- </p>
1093
+ <a href="https://github.com/Scaleflex/js-cloudimage-360-view/graphs/contributors">
1094
+ <img src="https://contrib.rocks/image?repo=Scaleflex/js-cloudimage-360-view" alt="Contributors">
1095
+ </a>
406
1096
  </details>
407
1097
 
408
1098
  ---
409
1099
 
410
- ## 🎗 License
1100
+ ## License
411
1101
 
412
- JS Cloudimage 360 View is provided under the [MIT License](https://opensource.org/licenses/MIT)
1102
+ This project is licensed under the [MIT License](https://opensource.org/licenses/MIT).
1103
+
1104
+ ---
1105
+
1106
+ <p align="center">
1107
+ Made with care by the <a href="https://www.scaleflex.com">Scaleflex</a> team
1108
+ </p>