js-cloudimage-360-view 4.0.0 → 4.1.0-beta.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
@@ -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,1098 @@
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 CSS and JS -->
100
+ <link rel="stylesheet" href="https://scaleflex.cloudimg.io/v7/plugins/js-cloudimage-360-view/latest/js-cloudimage-360-view.min.css">
101
+ <script src="https://scaleflex.cloudimg.io/v7/plugins/js-cloudimage-360-view/latest/js-cloudimage-360-view.min.js"></script>
102
+
103
+ <!-- Create a container with data attributes -->
104
+ <div
105
+ class="cloudimage-360"
106
+ data-folder="https://scaleflex.cloudimg.io/v7/demo/360-car/"
107
+ data-filename-x="car-{index}.jpg"
108
+ data-amount-x="36"
109
+ ></div>
110
+
111
+ <!-- Initialize -->
112
+ <script>
113
+ const viewer = new window.CI360();
114
+ viewer.initAll();
115
+ </script>
116
+ ```
117
+
118
+ ---
90
119
 
91
- ### Option 1: Add via CDN
120
+ ## Installation
92
121
 
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:
122
+ ### Option 1: CDN (Recommended for Quick Setup)
94
123
 
95
124
  ```html
96
125
  <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>
126
+ <script src="https://scaleflex.cloudimg.io/v7/plugins/js-cloudimage-360-view/latest/js-cloudimage-360-view.min.js"></script>
98
127
  ```
99
128
 
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.
129
+ > **Important:** Both CSS and JS files are required for proper functionality.
102
130
 
103
- This is the quickest way to get started without additional setup.
104
- #### Option 2: Install with Package Manager
131
+ ### Option 2: Package Manager
105
132
 
106
- You can add `js-cloudimage-360-view` to your project using either npm or Yarn:
133
+ ```bash
134
+ # npm
135
+ npm install js-cloudimage-360-view
107
136
 
108
- For npm:
137
+ # yarn
138
+ yarn add js-cloudimage-360-view
109
139
 
110
- ```sh
111
- npm install js-cloudimage-360-view
140
+ # pnpm
141
+ pnpm add js-cloudimage-360-view
112
142
  ```
113
143
 
114
- For Yarn:
144
+ Then import in your JavaScript:
115
145
 
116
- ```sh
117
- yarn add js-cloudimage-360-view
146
+ ```javascript
147
+ import CI360 from 'js-cloudimage-360-view';
148
+ import 'js-cloudimage-360-view/css';
149
+ ```
150
+
151
+ ---
152
+
153
+ ## Usage
154
+
155
+ ### Method 1: Data Attributes (Declarative)
156
+
157
+ The simplest way to create a 360 viewer using HTML data attributes:
158
+
159
+ ```html
160
+ <div
161
+ id="my-360-viewer"
162
+ class="cloudimage-360"
163
+ data-folder="https://your-domain.com/images/"
164
+ data-filename-x="{index}.jpg"
165
+ data-amount-x="36"
166
+ data-autoplay
167
+ data-fullscreen
168
+ data-magnifier="2"
169
+ ></div>
170
+
171
+ <script>
172
+ const viewer = new CI360();
173
+ viewer.initAll(); // Initializes all elements with class "cloudimage-360"
174
+ </script>
118
175
  ```
119
176
 
120
- Then, import it in your JavaScript file:
177
+ ### Method 2: JavaScript Configuration (Programmatic)
178
+
179
+ For more control, initialize with a JavaScript configuration object:
121
180
 
122
181
  ```javascript
123
- import CloudImage360 from 'js-cloudimage-360-view';
182
+ const viewer = new CI360();
183
+
184
+ const container = document.getElementById('product-viewer');
185
+
186
+ const config = {
187
+ folder: 'https://your-domain.com/images/',
188
+ filenameX: 'product-{index}.jpg',
189
+ amountX: 36,
190
+ autoplay: true,
191
+ speed: 100,
192
+ dragSpeed: 150,
193
+ fullscreen: true,
194
+ magnifier: 2,
195
+ pointerZoom: 2,
196
+ inertia: true,
197
+
198
+ // Event callbacks
199
+ onReady: () => console.log('Viewer ready!'),
200
+ onSpin: (e) => console.log(`Frame: ${e.activeImageX + 1}/${e.amountX}`),
201
+ };
202
+
203
+ viewer.init(container, config);
124
204
  ```
125
205
 
126
- OR
206
+ ### X and Y Axis Rotation
207
+
208
+ Support 360° rotation on both axes for full product exploration:
127
209
 
128
210
  ```javascript
129
- window.CI360
211
+ const config = {
212
+ folder: 'https://your-domain.com/images/',
213
+ filenameX: 'product-x-{index}.jpg',
214
+ filenameY: 'product-y-{index}.jpg',
215
+ amountX: 36,
216
+ amountY: 18,
217
+ autoplayBehavior: 'spin-xy', // Options: 'spin-x', 'spin-y', 'spin-xy', 'spin-yx'
218
+ };
130
219
  ```
131
220
 
221
+ ---
132
222
 
133
- Choose the method that best suits your project setup, and refer to the documentation for configuration options and usage examples.
223
+ ## React / Next.js
134
224
 
135
- ### 🛠️ Usage
225
+ The library provides a React wrapper for seamless integration with React and Next.js applications.
136
226
 
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.
227
+ ### Installation
138
228
 
139
- #### Initialize a Single View
229
+ ```bash
230
+ npm install js-cloudimage-360-view
231
+ ```
140
232
 
141
- To initialize a single 360-degree view, use the following code:
233
+ ### Basic Usage
234
+
235
+ ```tsx
236
+ import { CI360Viewer } from 'js-cloudimage-360-view/react';
237
+ import 'js-cloudimage-360-view/css';
238
+
239
+ function ProductView() {
240
+ return (
241
+ <CI360Viewer
242
+ folder="https://example.com/images/"
243
+ filenameX="product-{index}.jpg"
244
+ amountX={36}
245
+ autoplay
246
+ fullscreen
247
+ style={{ width: '100%', maxWidth: 600, height: 400 }}
248
+ />
249
+ );
250
+ }
251
+ ```
142
252
 
143
- ```javascript
144
- const cloudimage360 = new CloudImage360();
253
+ ### Imperative Control with Ref
254
+
255
+ Use a ref to control the viewer programmatically:
256
+
257
+ ```tsx
258
+ import { useRef } from 'react';
259
+ import { CI360Viewer, CI360ViewerRef } from 'js-cloudimage-360-view/react';
260
+ import 'js-cloudimage-360-view/css';
261
+
262
+ function ProductView() {
263
+ const viewerRef = useRef<CI360ViewerRef>(null);
264
+
265
+ return (
266
+ <>
267
+ <CI360Viewer
268
+ ref={viewerRef}
269
+ folder="https://example.com/images/"
270
+ filenameX="{index}.jpg"
271
+ amountX={36}
272
+ onSpin={(e) => console.log(`Frame: ${e.activeImageX}`)}
273
+ />
274
+ <button onClick={() => viewerRef.current?.play()}>Play</button>
275
+ <button onClick={() => viewerRef.current?.stop()}>Stop</button>
276
+ <button onClick={() => viewerRef.current?.goToFrame(17)}>Go to Frame 17</button>
277
+ </>
278
+ );
279
+ }
280
+ ```
145
281
 
146
- const suvCarContainer = document.getElementById('gurkha-suv');
282
+ ### Available Ref Methods
147
283
 
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
- };
284
+ | Method | Description |
285
+ |--------|-------------|
286
+ | `play()` | Start autoplay |
287
+ | `stop()` | Stop autoplay |
288
+ | `moveLeft(steps?)` | Move left by specified frames (default: 1) |
289
+ | `moveRight(steps?)` | Move right by specified frames (default: 1) |
290
+ | `moveTop(steps?)` | Move up on Y-axis (default: 1) |
291
+ | `moveBottom(steps?)` | Move down on Y-axis (default: 1) |
292
+ | `zoomIn()` | Toggle zoom in |
293
+ | `zoomOut()` | Zoom out |
294
+ | `goToFrame(frame, hotspotId?)` | Animate to specific frame |
295
+ | `getViewer()` | Get underlying viewer instance |
296
+
297
+ ### With Hotspots
298
+
299
+ ```tsx
300
+ import { CI360Viewer, Hotspot } from 'js-cloudimage-360-view/react';
154
301
 
155
- instance.init(suvCarContainer, config);
302
+ const hotspots: Hotspot[] = [
303
+ {
304
+ id: 'feature-1',
305
+ label: 'Engine',
306
+ orientation: 'x',
307
+ containerSize: [1200, 800],
308
+ positions: { 0: { x: 500, y: 300 } },
309
+ content: '<div>Engine details</div>',
310
+ },
311
+ ];
312
+
313
+ function ProductView() {
314
+ return (
315
+ <CI360Viewer
316
+ folder="https://example.com/images/"
317
+ filenameX="{index}.jpg"
318
+ amountX={36}
319
+ hotspots={hotspots}
320
+ />
321
+ );
322
+ }
156
323
  ```
157
324
 
158
- #### Initialize All Instances
325
+ ### Next.js (SSR)
159
326
 
160
- To initialize all instances with a common selector, use the following code:
327
+ For Next.js applications, use dynamic import to disable server-side rendering:
161
328
 
162
- ```javascript
163
- instance.initAll('.cloudimage-360');
329
+ ```tsx
330
+ import dynamic from 'next/dynamic';
331
+ import 'js-cloudimage-360-view/css';
332
+
333
+ const CI360Viewer = dynamic(
334
+ () => import('js-cloudimage-360-view/react').then(mod => mod.CI360Viewer),
335
+ { ssr: false }
336
+ );
337
+
338
+ export default function ProductPage() {
339
+ return (
340
+ <CI360Viewer
341
+ folder="https://example.com/images/"
342
+ filenameX="{index}.jpg"
343
+ amountX={36}
344
+ />
345
+ );
346
+ }
347
+ ```
348
+
349
+ ### useCI360 Hook
350
+
351
+ For advanced use cases, you can use the `useCI360` hook directly:
352
+
353
+ ```tsx
354
+ import { useRef } from 'react';
355
+ import { useCI360 } from 'js-cloudimage-360-view/react';
356
+
357
+ function CustomViewer() {
358
+ const containerRef = useRef<HTMLDivElement>(null);
359
+ const { viewer, isReady } = useCI360(containerRef, {
360
+ folder: 'https://example.com/images/',
361
+ filenameX: '{index}.jpg',
362
+ amountX: 36,
363
+ onReady: () => console.log('Viewer ready!'),
364
+ });
365
+
366
+ return (
367
+ <div>
368
+ <div ref={containerRef} style={{ width: 600, height: 400 }} />
369
+ {isReady && <p>Viewer is ready!</p>}
370
+ </div>
371
+ );
372
+ }
164
373
  ```
165
374
 
166
- This will apply the 360-degree viewer to all elements matching the specified selector.
375
+ ### TypeScript Support
376
+
377
+ The React wrapper is fully typed. Import types as needed:
167
378
 
379
+ ```tsx
380
+ import type {
381
+ CI360ViewerProps,
382
+ CI360ViewerRef,
383
+ CI360Config,
384
+ SpinEventData,
385
+ Hotspot,
386
+ } from 'js-cloudimage-360-view/react';
387
+ ```
168
388
 
169
- ### ⚙️ Configuration Options
389
+ ---
170
390
 
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.
391
+ ## Configuration Options
392
+
393
+ All options can be set via JavaScript config or HTML data attributes.
394
+
395
+ ### Image Source Options
396
+
397
+ | Option | Data Attribute | Default | Description |
398
+ |--------|----------------|---------|-------------|
399
+ | `folder` | `data-folder` | `'/'` | Path to the folder containing images |
400
+ | `filenameX` | `data-filename-x` | `'image-{index}.jpg'` | Filename pattern for X-axis images. Use `{index}` as placeholder |
401
+ | `filenameY` | `data-filename-y` | `null` | Filename pattern for Y-axis images |
402
+ | `imageListX` | `data-image-list-x` | `null` | Array of image URLs for X-axis (alternative to folder/filename) |
403
+ | `imageListY` | `data-image-list-y` | `null` | Array of image URLs for Y-axis |
404
+ | `amountX` | `data-amount-x` | `0` | Total number of X-axis images |
405
+ | `amountY` | `data-amount-y` | `0` | Total number of Y-axis images |
406
+ | `indexZeroBase` | `data-index-zero-base` | `0` | Starting index for image filenames |
407
+
408
+ ### Behavior Options
409
+
410
+ | Option | Data Attribute | Default | Description |
411
+ |--------|----------------|---------|-------------|
412
+ | `autoplay` | `data-autoplay` | `false` | Enable automatic rotation |
413
+ | `autoplayBehavior` | `data-autoplay-behavior` | `'spin-x'` | Autoplay pattern: `'spin-x'`, `'spin-y'`, `'spin-xy'`, `'spin-yx'` |
414
+ | `autoplayReverse` | `data-autoplay-reverse` | `false` | Reverse autoplay direction |
415
+ | `playOnce` | `data-play-once` | `false` | Stop after one complete rotation |
416
+ | `speed` | `data-speed` | `80` | Autoplay speed (ms between frames) |
417
+ | `inertia` | `data-inertia` | `false` | Enable momentum after drag release |
418
+
419
+ ### Control Options
420
+
421
+ | Option | Data Attribute | Default | Description |
422
+ |--------|----------------|---------|-------------|
423
+ | `draggable` | `data-draggable` | `true` | Enable mouse drag rotation |
424
+ | `swipeable` | `data-swipeable` | `true` | Enable touch swipe rotation |
425
+ | `dragSpeed` | `data-drag-speed` | `150` | Drag sensitivity |
426
+ | `dragReverse` | `data-drag-reverse` | `false` | Reverse drag direction |
427
+ | `keys` | `data-keys` | `false` | Enable keyboard arrow navigation |
428
+ | `keysReverse` | `data-keys-reverse` | `false` | Reverse keyboard direction |
429
+ | `stopAtEdges` | `data-stop-at-edges` | `false` | Stop rotation at first/last frame |
430
+ | `pinchZoom` | `data-pinch-zoom` | `true` | Enable pinch-to-zoom on touch devices |
431
+
432
+ ### Display Options
433
+
434
+ | Option | Data Attribute | Default | Description |
435
+ |--------|----------------|---------|-------------|
436
+ | `fullscreen` | `data-fullscreen` | `false` | Show fullscreen button |
437
+ | `magnifier` | `data-magnifier` | `null` | Magnifier zoom level (1-5) |
438
+ | `pointerZoom` | `data-pointer-zoom` | `0` | Pointer zoom level on click (1-5) |
439
+ | `bottomCircle` | `data-bottom-circle` | `true` | Show 360° progress indicator |
440
+ | `bottomCircleOffset` | `data-bottom-circle-offset` | `5` | Progress indicator offset (px) |
441
+ | `initialIconShown` | `data-initial-icon` | `true` | Show 360° icon on load |
442
+ | `lazyload` | `data-lazyload` | `true` | Enable lazy loading |
443
+ | `hints` | `data-hints` | `true` | Show interaction hints on load |
444
+ | `theme` | `data-theme` | `null` | Color theme: `'light'` or `'dark'` |
445
+ | `hotspotTimelineOnClick` | `data-hotspot-timeline-on-click` | `true` | Show hotspot popup when clicking timeline dot |
446
+
447
+ ### Cloudimage CDN Options
448
+
449
+ | Option | Data Attribute | Default | Description |
450
+ |--------|----------------|---------|-------------|
451
+ | `ciToken` | `data-responsive` | `null` | Cloudimage token for responsive images |
452
+ | `ciFilters` | `data-filters` | `null` | Cloudimage filters |
453
+ | `ciTransformation` | `data-transformation` | `null` | Cloudimage transformations |
172
454
 
173
- #### Method 1: Initialization via JavaScript Code
174
- To initialize a view programmatically, use the following configuration options:
455
+ ---
175
456
 
457
+ ## Event Callbacks
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
+ Hook into viewer events for custom functionality. Callbacks are only available via JavaScript configuration.
460
+
461
+ | Callback | Event Data | Description |
462
+ |----------|------------|-------------|
463
+ | `onReady` | `{ viewerId }` | Viewer initialized and ready |
464
+ | `onLoad` | `{ viewerId, imagesX, imagesY }` | All images loaded |
465
+ | `onSpin` | `{ viewerId, direction, activeImageX, activeImageY, amountX, amountY }` | Each rotation frame |
466
+ | `onAutoplayStart` | `{ viewerId }` | Autoplay started |
467
+ | `onAutoplayStop` | `{ viewerId }` | Autoplay stopped |
468
+ | `onDragStart` | `{ viewerId }` | User started dragging |
469
+ | `onDragEnd` | `{ viewerId }` | User stopped dragging |
470
+ | `onZoomIn` | `{ viewerId, zoomLevel }` | Pointer zoom activated |
471
+ | `onZoomOut` | `{ viewerId }` | Pointer zoom deactivated |
472
+ | `onFullscreenOpen` | `{ viewerId }` | Fullscreen mode opened |
473
+ | `onFullscreenClose` | `{ viewerId }` | Fullscreen mode closed |
474
+
475
+ ### Example
179
476
 
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
477
  ```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
- },
478
+ const config = {
479
+ folder: 'https://example.com/images/',
480
+ filenameX: '{index}.jpg',
481
+ amountX: 36,
482
+
483
+ onReady: (e) => {
484
+ console.log(`Viewer ${e.viewerId} is ready`);
485
+ },
486
+
487
+ onSpin: (e) => {
488
+ // Update custom progress indicator
489
+ const progress = ((e.activeImageX + 1) / e.amountX * 100).toFixed(0);
490
+ document.getElementById('progress').textContent = `${progress}%`;
491
+ },
492
+
493
+ onFullscreenOpen: () => {
494
+ // Pause background video when entering fullscreen
495
+ document.getElementById('bg-video')?.pause();
496
+ },
497
+ };
259
498
  ```
260
499
 
261
- #### Example Hotspot Configuration
262
- Here's an example configuration for multiple hotspots:
500
+ ---
501
+
502
+ ## Hotspots
503
+
504
+ Add interactive markers to highlight product features.
505
+
506
+ ### Configuration
507
+
263
508
  ```javascript
264
- const GURKHA_SUV_HOTSPOTS_CONFIG = [
509
+ const hotspots = [
265
510
  {
266
- id: 'hotspot-1',
511
+ id: 'feature-1',
267
512
  orientation: 'x',
268
- containerSize: [1170, 663],
513
+ containerSize: [1200, 800], // Reference container size for positioning
269
514
  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...
515
+ 0: { x: 500, y: 300 },
516
+ 1: { x: 520, y: 300 },
517
+ 2: { x: 540, y: null }, // null inherits from previous frame
518
+ 3: { x: 560, y: null },
519
+ // ... positions for frames where hotspot is visible
520
+ },
521
+ content: '<div class="tooltip"><strong>Premium Feature</strong><p>Description here</p></div>',
522
+ onClick: () => {
523
+ console.log('Hotspot clicked!');
276
524
  },
277
- content: '<div class="tooltip">Info about Hotspot 1</div>',
278
525
  },
279
- // Additional hotspots...
280
526
  ];
527
+
528
+ const config = {
529
+ folder: 'https://example.com/images/',
530
+ filenameX: '{index}.jpg',
531
+ amountX: 36,
532
+ hotspots: hotspots,
533
+ };
281
534
  ```
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
535
 
536
+ ### Hotspot Properties
304
537
 
305
- ## Methods
538
+ | Property | Required | Description |
539
+ |----------|----------|-------------|
540
+ | `id` | Yes | Unique identifier |
541
+ | `orientation` | Yes | `'x'` or `'y'` axis |
542
+ | `containerSize` | Yes | `[width, height]` reference dimensions |
543
+ | `positions` | Yes | Object mapping frame index to `{ x, y }` coordinates |
544
+ | `content` | Yes | HTML content for the tooltip |
545
+ | `label` | No | Short label for the hotspot (used in timeline tooltips) |
546
+ | `onClick` | No | Click handler function |
547
+
548
+ ### Hotspot Timeline
549
+
550
+ When hotspots are configured, a timeline navigation bar automatically appears below the viewer. This timeline shows:
551
+
552
+ - **Position indicator** - Shows current rotation position
553
+ - **Hotspot dots** - One dot per hotspot at its center frame position
554
+ - **Hover tooltips** - If a hotspot has a `label`, hovering over its dot shows a tooltip
555
+
556
+ Clicking a dot animates the viewer to that hotspot's position and optionally shows its popup.
557
+
558
+ #### Timeline Tooltips
559
+
560
+ Tooltips display the hotspot's `label` property when hovering over a timeline dot:
561
+
562
+ ```javascript
563
+ const hotspots = [
564
+ {
565
+ id: 'engine',
566
+ label: 'Engine Bay', // This text appears in the tooltip
567
+ orientation: 'x',
568
+ containerSize: [1200, 800],
569
+ positions: { 0: { x: 500, y: 300 }, /* ... */ },
570
+ content: '<div>Full hotspot content here</div>',
571
+ },
572
+ ];
573
+ ```
574
+
575
+ **Tooltip behavior:**
576
+ - Appears after a **400ms hover delay** to prevent accidental triggers
577
+ - Positioned above the dot with an arrow pointer
578
+ - Hidden on mouse leave or click (navigation)
579
+
580
+ #### Timeline Configuration
581
+
582
+ | Option | Default | Description |
583
+ |--------|---------|-------------|
584
+ | `hotspotTimelineOnClick` | `true` | Show hotspot popup when clicking a timeline dot |
585
+
586
+ ```javascript
587
+ const config = {
588
+ hotspots: [...],
589
+ hotspotTimelineOnClick: true, // Show popup on click (default)
590
+ // or
591
+ hotspotTimelineOnClick: false, // Only navigate, don't show popup
592
+ };
593
+ ```
594
+
595
+ #### Timeline CSS Variables
596
+
597
+ Customize the timeline appearance with CSS variables:
598
+
599
+ ```css
600
+ :root {
601
+ /* Timeline track */
602
+ --ci360-timeline-height: 6px;
603
+ --ci360-timeline-track-bg: rgba(0, 0, 0, 0.12);
604
+
605
+ /* Hotspot dots */
606
+ --ci360-timeline-dot-size: 18px;
607
+ --ci360-timeline-dot-color: var(--ci360-hotspot-color);
608
+ --ci360-timeline-dot-border: 2px solid #fff;
609
+
610
+ /* Position indicator */
611
+ --ci360-timeline-indicator-size: 12px;
612
+ --ci360-timeline-indicator-color: #333333;
613
+
614
+ /* Tooltip styling (matches theme) */
615
+ --ci360-timeline-tooltip-bg: rgba(255, 255, 255, 0.95);
616
+ --ci360-timeline-tooltip-color: #333333;
617
+ }
618
+
619
+ /* Dark theme uses dark tooltip */
620
+ .ci360-theme-dark {
621
+ --ci360-timeline-tooltip-bg: rgba(40, 40, 45, 0.95);
622
+ --ci360-timeline-tooltip-color: #e0e0e0;
623
+ }
624
+ ```
625
+
626
+ **Custom tooltip styling example:**
306
627
 
307
- ### `getViewById(id)`
308
- Returns the view object associated with the specified ID.
628
+ ```css
629
+ /* Increase tooltip font size */
630
+ .cloudimage-360-hotspot-timeline-tooltip {
631
+ font-size: 14px;
632
+ padding: 8px 16px;
633
+ }
634
+
635
+ /* Brand-colored tooltip */
636
+ .my-viewer {
637
+ --ci360-timeline-tooltip-bg: #2563eb;
638
+ --ci360-timeline-tooltip-color: #ffffff;
639
+ }
640
+ ```
641
+
642
+ ---
643
+
644
+ ## Interaction Hints
645
+
646
+ 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.
647
+
648
+ ### Configuration
309
649
 
310
650
  ```javascript
311
- getViewById(id)
651
+ const config = {
652
+ // Auto-detect hints based on enabled features (default)
653
+ hints: true,
654
+
655
+ // Disable hints
656
+ hints: false,
657
+
658
+ // Custom hints array
659
+ hints: ['drag', 'click', 'keys'],
660
+ };
312
661
  ```
313
662
 
314
- ### `getViews()`
315
- Returns an array of all the view objects currently available.
663
+ ### Available Hint Types
664
+
665
+ | Type | Desktop | Mobile | Description |
666
+ |------|---------|--------|-------------|
667
+ | `drag` | ✓ | - | "Drag to rotate" |
668
+ | `swipe` | - | ✓ | "Swipe to rotate" |
669
+ | `click` | ✓ | - | "Click to zoom" (when pointerZoom enabled) |
670
+ | `pinch` | - | ✓ | "Pinch to zoom" (when pinchZoom enabled) |
671
+ | `keys` | ✓ | - | "Use arrow keys" (when keys enabled) |
672
+
673
+ ---
674
+
675
+ ## Styling & Theming
676
+
677
+ ### Built-in Themes
678
+
679
+ Apply a theme by setting the `theme` option or using the `ci360-theme-dark` class:
316
680
 
317
681
  ```javascript
318
- getViews()
682
+ // Via config
683
+ const config = {
684
+ theme: 'dark', // or 'light'
685
+ // ...other options
686
+ };
687
+
688
+ // Or via HTML
689
+ <div class="cloudimage-360 ci360-theme-dark" ...></div>
690
+ ```
691
+
692
+ ### CSS Variables (Recommended)
693
+
694
+ The easiest way to customize the viewer appearance:
695
+
696
+ ```css
697
+ :root {
698
+ /* Buttons */
699
+ --ci360-button-bg: #f0f0f0;
700
+ --ci360-button-bg-hover: #e0e0e0;
701
+ --ci360-button-size: 40px;
702
+ --ci360-button-border-radius: 6px;
703
+ --ci360-button-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
704
+
705
+ /* Icons */
706
+ --ci360-icon-color: #37414b;
707
+ --ci360-icon-color-hover: #1a1f24;
708
+ --ci360-icon-size: 20px;
709
+
710
+ /* 360° Indicator */
711
+ --ci360-initial-icon-bg: rgba(255, 255, 255, 0.9);
712
+ --ci360-initial-icon-color: #505050;
713
+ --ci360-initial-icon-size: 80px;
714
+ --ci360-initial-icon-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
715
+
716
+ /* Loading Spinner */
717
+ --ci360-spinner-color: #fff;
718
+ --ci360-spinner-accent: #a3a3a3;
719
+ --ci360-spinner-size: 30px;
720
+
721
+ /* Fullscreen */
722
+ --ci360-fullscreen-bg: #fff;
723
+
724
+ /* Magnifier */
725
+ --ci360-magnifier-size: 250px;
726
+ --ci360-magnifier-border: 2px solid rgba(0, 0, 0, 0.3);
727
+ --ci360-magnifier-shadow: 0 8px 16px rgba(0, 0, 0, 0.4);
728
+
729
+ /* Hotspots */
730
+ --ci360-hotspot-color: #00aaff;
731
+ --ci360-hotspot-border: 1px solid #fff;
732
+ --ci360-hotspot-size: 18px;
733
+
734
+ /* Tooltips */
735
+ --ci360-popper-bg: rgba(255, 255, 255, 0.95);
736
+ --ci360-popper-color: #333;
737
+ --ci360-popper-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
738
+ --ci360-popper-border-radius: 6px;
739
+
740
+ /* Hints Overlay */
741
+ --ci360-hints-bg: rgba(0, 0, 0, 0.75);
742
+ --ci360-hints-color: #ffffff;
743
+ --ci360-hints-font-size: 14px;
744
+ --ci360-hints-border-radius: 12px;
745
+
746
+ /* Bottom Circle Indicator */
747
+ --ci360-circle-color-start: rgba(0, 0, 0, 0.05);
748
+ --ci360-circle-color-mid: rgba(0, 0, 0, 0.3);
749
+ --ci360-circle-color-end: rgba(0, 0, 0, 0.05);
750
+ --ci360-circle-dot-color: rgba(0, 0, 0, 0.4);
751
+
752
+ /* Other */
753
+ --ci360-focus-color: #0066cc;
754
+ --ci360-overlay-bg: rgba(255, 255, 255, 1);
755
+ }
319
756
  ```
320
757
 
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.
758
+ ### Custom Dark Theme Example
759
+
760
+ If you prefer to customize beyond the built-in dark theme:
761
+
762
+ ```css
763
+ .my-dark-viewer {
764
+ --ci360-button-bg: rgba(30, 30, 35, 0.9);
765
+ --ci360-button-bg-hover: rgba(45, 45, 50, 0.95);
766
+ --ci360-icon-color: #e0e0e0;
767
+ --ci360-icon-color-hover: #ffffff;
768
+ --ci360-fullscreen-bg: #1a1a1f;
769
+ --ci360-initial-icon-bg: rgba(30, 30, 35, 0.9);
770
+ --ci360-initial-icon-color: #e0e0e0;
771
+ --ci360-popper-bg: rgba(40, 40, 45, 0.95);
772
+ --ci360-popper-color: #e0e0e0;
773
+ --ci360-hints-bg: rgba(255, 255, 255, 0.12);
774
+ --ci360-circle-color-mid: rgba(255, 255, 255, 0.25);
775
+ --ci360-circle-dot-color: rgba(255, 255, 255, 0.4);
776
+ --ci360-overlay-bg: rgba(26, 26, 31, 1);
777
+ }
778
+ ```
779
+
780
+ ### Scope to Specific Viewer
781
+
782
+ ```css
783
+ #my-special-viewer {
784
+ --ci360-button-bg: #4a90d9;
785
+ --ci360-icon-color: #ffffff;
786
+ --ci360-hotspot-color: #ff6b6b;
787
+ }
788
+ ```
789
+
790
+ ### CSS Classes Reference
791
+
792
+ | Class | Description |
793
+ |-------|-------------|
794
+ | `.cloudimage-360` | Main container |
795
+ | `.cloudimage-360-inner-box` | Inner container |
796
+ | `.cloudimage-360-button` | Control buttons |
797
+ | `.cloudimage-360-icons-container` | Button container |
798
+ | `.cloudimage-initial-icon` | 360° indicator icon |
799
+ | `.cloudimage-360-view-360-circle` | Bottom progress indicator |
800
+ | `.cloudimage-loading-spinner` | Loading spinner |
801
+ | `.cloudimage-360-fullscreen-modal` | Fullscreen container |
802
+ | `.cloudimage-360-img-magnifier-glass` | Magnifier element |
803
+ | `.cloudimage-360-hotspot` | Hotspot marker |
804
+ | `.cloudimage-360-popper` | Hotspot tooltip |
805
+ | `.cloudimage-360-hints-overlay` | Hints overlay container |
806
+ | `.cloudimage-360-hints-container` | Hints content box |
807
+ | `.cloudimage-360-hotspot-timeline` | Hotspot timeline container |
808
+ | `.cloudimage-360-hotspot-timeline-track` | Timeline track |
809
+ | `.cloudimage-360-hotspot-timeline-dot` | Timeline hotspot dot |
810
+ | `.cloudimage-360-hotspot-timeline-indicator` | Timeline position indicator |
811
+ | `.cloudimage-360-hotspot-timeline-tooltip` | Timeline dot tooltip (appears on hover) |
812
+ | `.ci360-theme-dark` | Dark theme class |
813
+
814
+ ---
815
+
816
+ ## Methods
817
+
818
+ ### Instance Methods
323
819
 
324
820
  ```javascript
325
- updateView(id, config)
821
+ const viewer = new CI360();
822
+
823
+ // Initialize all viewers with class "cloudimage-360"
824
+ viewer.initAll();
825
+
826
+ // Initialize a specific container
827
+ viewer.init(containerElement, config);
828
+
829
+ // Get a viewer by its container ID
830
+ const view = viewer.getViewById('my-viewer');
831
+
832
+ // Get all viewer instances
833
+ const allViews = viewer.getViews();
834
+
835
+ // Update a viewer's configuration
836
+ viewer.updateView('my-viewer', { speed: 50, autoplay: true });
326
837
  ```
327
838
 
328
839
  ### View Methods
329
840
 
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.
841
+ ```javascript
842
+ const view = viewer.getViewById('my-viewer');
843
+
844
+ // Programmatically rotate the view
845
+ view.onMoveHandler('right', 1, 0); // Move right by 1 frame
846
+ view.onMoveHandler('left', 5, 0); // Move left by 5 frames
847
+ view.onMoveHandler('up', 0, 1); // Move up by 1 frame (Y-axis)
848
+ view.onMoveHandler('down', 0, 1); // Move down by 1 frame (Y-axis)
849
+
850
+ // Destroy the viewer
851
+ view.destroy();
852
+ ```
853
+
854
+ ---
855
+
856
+ ## Cloudimage Integration
857
+
858
+ Enhance performance with [Cloudimage](https://cloudimage.io) CDN for responsive, optimized images.
859
+
860
+ ### Setup
861
+
862
+ 1. Register at [cloudimage.io](https://cloudimage.io) to get your token
863
+ 2. Add the token to your viewer configuration:
332
864
 
333
865
  ```javascript
334
- onMoveHandler(movingDirection, itemsSkippedX = 1, itemsSkippedY = 1)
866
+ const config = {
867
+ folder: 'https://your-domain.com/images/',
868
+ filenameX: '{index}.jpg',
869
+ amountX: 36,
870
+ ciToken: 'your-cloudimage-token', // or use data-responsive attribute
871
+ };
335
872
  ```
336
873
 
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).
874
+ ### Benefits
875
+
876
+ - **25GB free CDN traffic** per month
877
+ - **Automatic optimization** - WebP, AVIF conversion
878
+ - **Responsive images** - Serve the right size for each device
879
+ - **Global CDN** - Fast delivery worldwide
880
+ - **Image transformations** - Resize, crop, filters on-the-fly
341
881
 
342
882
  ---
343
883
 
344
- ## Cloudimage Responsive Integration
884
+ ## Browser Support
345
885
 
346
- ### Overview
886
+ | Browser | Version |
887
+ |---------|---------|
888
+ | Chrome | 69+ |
889
+ | Firefox | 105+ |
890
+ | Safari | 16.4+ |
891
+ | Edge | 79+ |
892
+ | iOS Safari | 16.4+ |
893
+ | Android Chrome | 69+ |
347
894
 
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.
895
+ > **Note:** This library uses OffscreenCanvas for optimal performance, which requires the browser versions listed above.
349
896
 
350
- ### How It Works
897
+ ---
351
898
 
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.
899
+ ## Migration Guide (v3 v4)
353
900
 
354
- ### Requirements
901
+ Version 4 introduces significant improvements in performance, customization, and developer experience. This guide helps you upgrade from v3.
355
902
 
356
- Before you start using the Cloudimage Responsive plugin, make sure you have the following:
903
+ ### Breaking Changes
357
904
 
358
- - **Cloudimage Token**: You'll need a unique Cloudimage token to deliver your images over their CDN.
905
+ #### 1. CSS File Required
359
906
 
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.
907
+ v4 requires importing the CSS file separately:
363
908
 
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.
909
+ ```html
910
+ <!-- v3: Only JS needed -->
911
+ <script src=".../js-cloudimage-360-view.min.js"></script>
365
912
 
913
+ <!-- v4: Both CSS and JS required -->
914
+ <link rel="stylesheet" href=".../js-cloudimage-360-view.min.css">
915
+ <script src=".../js-cloudimage-360-view.min.js"></script>
916
+ ```
366
917
 
367
- ## 🔰 Contributing
918
+ For npm users:
368
919
 
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.
920
+ ```javascript
921
+ // v4
922
+ import CI360 from 'js-cloudimage-360-view';
923
+ import 'js-cloudimage-360-view/css';
924
+ ```
372
925
 
373
- <details closed>
374
- <summary>Contributing Guidelines</summary>
926
+ #### 2. Initialization API Changed
375
927
 
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>
928
+ ```javascript
929
+ // v3
930
+ window.CI360.init();
931
+ window.CI360.add('my-viewer');
932
+ window.CI360.update('my-viewer', true);
933
+ window.CI360.destroy();
934
+
935
+ // v4
936
+ const viewer = new CI360();
937
+ viewer.initAll(); // Initialize all
938
+ viewer.init(container, config); // Initialize specific container
939
+ viewer.updateView('my-viewer', newConfig); // Update with new config
940
+ viewer.getViewById('my-viewer').destroy(); // Destroy specific viewer
941
+ ```
397
942
 
398
- <details closed>
399
- <summary>Contributor Graph</summary>
943
+ #### 3. Browser Requirements Changed
944
+
945
+ v4 uses OffscreenCanvas for performance, requiring newer browsers:
946
+
947
+ | Browser | v3 | v4 |
948
+ |---------|-----|-----|
949
+ | Safari | 12+ | **16.4+** |
950
+ | iOS Safari | 12+ | **16.4+** |
951
+ | Firefox | 55+ | **105+** |
952
+ | Chrome | 60+ | 69+ |
953
+
954
+ ### Deprecated Configuration Options
955
+
956
+ The following options have been removed in v4:
957
+
958
+ | v3 Option | v4 Alternative |
959
+ |-----------|----------------|
960
+ | `data-box-shadow` | Use CSS: `.cloudimage-360 { box-shadow: ... }` |
961
+ | `data-ratio` | Container automatically maintains aspect ratio |
962
+ | `data-lazy-selector` | Use `data-lazyload` (boolean) |
963
+ | `data-hide-360-logo` | Use `data-initial-icon` (boolean, inverted) |
964
+ | `data-logo-src` | Custom logos not supported; use CSS to hide |
965
+ | `data-image-info` | Removed |
966
+ | `data-request-responsive-images` | Removed |
967
+ | `data-disable-drag` | Use `data-draggable` (inverted: `draggable="false"`) |
968
+ | `data-spin-reverse` | Use `data-drag-reverse` and `data-autoplay-reverse` |
969
+
970
+ ### Hotspot Configuration Changes
971
+
972
+ Hotspot properties have been simplified:
973
+
974
+ ```javascript
975
+ // v3 - Multiple specific properties
976
+ const hotspot = {
977
+ id: 'feature-1',
978
+ title: 'Feature Title',
979
+ description: 'Description text',
980
+ url: 'https://example.com',
981
+ newTab: true,
982
+ moreDetailsUrl: 'https://example.com/details',
983
+ moreDetailsTitle: 'Learn More',
984
+ popupSelector: '#custom-popup',
985
+ arrow: true,
986
+ placement: 'top',
987
+ offset: [0, 10],
988
+ positions: { 0: { x: 100, y: 200 } },
989
+ };
990
+
991
+ // v4 - Flexible HTML content
992
+ const hotspot = {
993
+ id: 'feature-1',
994
+ orientation: 'x',
995
+ containerSize: [1200, 800],
996
+ positions: { 0: { x: 100, y: 200 } },
997
+ content: `
998
+ <div class="my-tooltip">
999
+ <h3>Feature Title</h3>
1000
+ <p>Description text</p>
1001
+ <a href="https://example.com" target="_blank">Learn More</a>
1002
+ </div>
1003
+ `,
1004
+ onClick: () => console.log('Clicked!'),
1005
+ };
1006
+ ```
1007
+
1008
+ | v3 Property | v4 Alternative |
1009
+ |-------------|----------------|
1010
+ | `title`, `description` | Use `content` with HTML |
1011
+ | `url`, `newTab` | Include `<a>` tag in `content` |
1012
+ | `moreDetailsUrl`, `moreDetailsTitle` | Include in `content` HTML |
1013
+ | `popupSelector` | Use `content` with your HTML |
1014
+ | `arrow`, `placement`, `offset` | Popper.js handles positioning automatically |
1015
+ | `open` | Removed; hotspots open on click/hover |
1016
+
1017
+ ### New Features in v4
1018
+
1019
+ Take advantage of these new capabilities:
1020
+
1021
+ #### CSS Variables for Theming
1022
+
1023
+ ```css
1024
+ :root {
1025
+ --ci360-button-bg: #f0f0f0;
1026
+ --ci360-icon-color: #333;
1027
+ --ci360-hotspot-color: #00aaff;
1028
+ }
1029
+ ```
1030
+
1031
+ #### Built-in Themes
1032
+
1033
+ ```html
1034
+ <div class="cloudimage-360 ci360-theme-dark" ...></div>
1035
+ ```
1036
+
1037
+ #### Event Callbacks
1038
+
1039
+ ```javascript
1040
+ const config = {
1041
+ onReady: (e) => console.log('Ready'),
1042
+ onSpin: (e) => console.log(`Frame: ${e.activeImageX}`),
1043
+ onFullscreenOpen: () => console.log('Fullscreen'),
1044
+ };
1045
+ ```
1046
+
1047
+ #### Interaction Hints
1048
+
1049
+ ```javascript
1050
+ const config = {
1051
+ hints: true, // Auto-detect hints
1052
+ // or
1053
+ hints: ['drag', 'click', 'keys'], // Custom hints
1054
+ };
1055
+ ```
1056
+
1057
+ #### Pinch-to-Zoom (Mobile)
1058
+
1059
+ ```javascript
1060
+ const config = {
1061
+ pinchZoom: true, // Enabled by default
1062
+ };
1063
+ ```
1064
+
1065
+ ### Quick Migration Checklist
1066
+
1067
+ - [ ] Add CSS file import alongside JS
1068
+ - [ ] Update initialization code to use `new CI360()`
1069
+ - [ ] Replace `data-disable-drag` with `data-draggable="false"`
1070
+ - [ ] Replace `data-spin-reverse` with `data-drag-reverse`
1071
+ - [ ] Replace `data-hide-360-logo` with `data-initial-icon="false"`
1072
+ - [ ] Update hotspot configs to use `content` instead of individual properties
1073
+ - [ ] Test on Safari 16.4+ (older versions not supported)
1074
+ - [ ] Consider adding CSS variables for customization
1075
+ - [ ] Consider adding event callbacks for analytics/tracking
1076
+
1077
+ ---
1078
+
1079
+ ## Contributing
1080
+
1081
+ We welcome contributions! Here's how you can help:
1082
+
1083
+ - **[Report bugs](https://github.com/Scaleflex/js-cloudimage-360-view/issues)** - Found a bug? Let us know!
1084
+ - **[Request features](https://github.com/Scaleflex/js-cloudimage-360-view/issues)** - Have an idea? Share it!
1085
+ - **[Submit PRs](https://github.com/Scaleflex/js-cloudimage-360-view/pulls)** - Code contributions are welcome!
1086
+ - **[Join discussions](https://github.com/Scaleflex/js-cloudimage-360-view/discussions)** - Ask questions, share insights
1087
+
1088
+ ### Development Setup
1089
+
1090
+ ```bash
1091
+ git clone https://github.com/Scaleflex/js-cloudimage-360-view.git
1092
+ cd js-cloudimage-360-view
1093
+ npm install
1094
+ npm run dev
1095
+ ```
1096
+
1097
+ <details>
1098
+ <summary><strong>Contributors</strong></summary>
400
1099
  <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>
1100
+ <a href="https://github.com/Scaleflex/js-cloudimage-360-view/graphs/contributors">
1101
+ <img src="https://contrib.rocks/image?repo=Scaleflex/js-cloudimage-360-view" alt="Contributors">
1102
+ </a>
406
1103
  </details>
407
1104
 
408
1105
  ---
409
1106
 
410
- ## 🎗 License
1107
+ ## License
411
1108
 
412
- JS Cloudimage 360 View is provided under the [MIT License](https://opensource.org/licenses/MIT)
1109
+ This project is licensed under the [MIT License](https://opensource.org/licenses/MIT).
1110
+
1111
+ ---
1112
+
1113
+ <p align="center">
1114
+ Made with care by the <a href="https://www.scaleflex.com">Scaleflex</a> team
1115
+ </p>