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 +972 -276
- package/dist/js-cloudimage-360-view.min.js +29 -2105
- package/dist/react/assets/canvas.worker-Cg0fkpD1.js.map +1 -0
- package/dist/react/ci360-COjOXkWS.js +35 -0
- package/dist/react/ci360-COjOXkWS.js.map +1 -0
- package/dist/react/ci360-CbNlMnNZ.mjs +2700 -0
- package/dist/react/ci360-CbNlMnNZ.mjs.map +1 -0
- package/dist/react/index.cjs +2 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.ts +228 -0
- package/dist/react/index.js +273 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/style.css +1 -0
- package/package.json +49 -10
- package/src/react/types.d.ts +228 -0
- package/src/types/ci360.d.ts +66 -0
- package/.prettierrc +0 -9
- package/dist/js-cloudimage-360-view.min.css +0 -1
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
|
|
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
|
-
|
|
9
|
-
</h1
|
|
6
|
+
|
|
7
|
+
<h1 align="center">JS Cloudimage 360 View</h1>
|
|
8
|
+
|
|
10
9
|
<p align="center">
|
|
11
|
-
<
|
|
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="
|
|
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-
|
|
27
|
+
<img src="https://img.shields.io/badge/Powered%20by-Cloudimage-blue" alt="Cloudimage">
|
|
34
28
|
</a>
|
|
35
29
|
</p>
|
|
36
|
-
|
|
37
|
-
</p>
|
|
30
|
+
|
|
38
31
|
<p align="center">
|
|
39
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
- [
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
- [
|
|
56
|
-
- [
|
|
57
|
-
- [
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
- [
|
|
63
|
-
- [
|
|
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
|
-
##
|
|
61
|
+
## Overview
|
|
68
62
|
|
|
69
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
|
77
|
-
|
|
78
|
-
|
|
|
79
|
-
|
|
|
80
|
-
|
|
|
81
|
-
|
|
|
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
|
-
##
|
|
94
|
+
## Quick Start
|
|
86
95
|
|
|
87
|
-
|
|
96
|
+
Add the library via CDN and create your first 360 viewer in seconds:
|
|
88
97
|
|
|
89
|
-
|
|
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
|
-
|
|
119
|
+
## Installation
|
|
92
120
|
|
|
93
|
-
|
|
121
|
+
### Option 1: CDN (Recommended for Quick Setup)
|
|
94
122
|
|
|
95
123
|
```html
|
|
96
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
104
|
-
#### Option 2: Install with Package Manager
|
|
129
|
+
### Option 2: Package Manager
|
|
105
130
|
|
|
106
|
-
|
|
131
|
+
```bash
|
|
132
|
+
# npm
|
|
133
|
+
npm install js-cloudimage-360-view
|
|
107
134
|
|
|
108
|
-
|
|
135
|
+
# yarn
|
|
136
|
+
yarn add js-cloudimage-360-view
|
|
109
137
|
|
|
110
|
-
|
|
111
|
-
|
|
138
|
+
# pnpm
|
|
139
|
+
pnpm add js-cloudimage-360-view
|
|
112
140
|
```
|
|
113
141
|
|
|
114
|
-
|
|
142
|
+
Then import in your JavaScript:
|
|
115
143
|
|
|
116
|
-
```
|
|
117
|
-
|
|
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
|
-
|
|
175
|
+
### Method 2: JavaScript Configuration (Programmatic)
|
|
176
|
+
|
|
177
|
+
For more control, initialize with a JavaScript configuration object:
|
|
121
178
|
|
|
122
179
|
```javascript
|
|
123
|
-
|
|
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
|
-
|
|
204
|
+
### X and Y Axis Rotation
|
|
205
|
+
|
|
206
|
+
Support 360° rotation on both axes for full product exploration:
|
|
127
207
|
|
|
128
208
|
```javascript
|
|
129
|
-
|
|
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
|
-
|
|
221
|
+
## React / Next.js
|
|
134
222
|
|
|
135
|
-
|
|
223
|
+
The library provides a React wrapper for seamless integration with React and Next.js applications.
|
|
136
224
|
|
|
137
|
-
|
|
225
|
+
### Installation
|
|
138
226
|
|
|
139
|
-
|
|
227
|
+
```bash
|
|
228
|
+
npm install js-cloudimage-360-view
|
|
229
|
+
```
|
|
140
230
|
|
|
141
|
-
|
|
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
|
-
|
|
144
|
-
|
|
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
|
-
|
|
280
|
+
### Available Ref Methods
|
|
147
281
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
-
|
|
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
|
-
|
|
323
|
+
### Next.js (SSR)
|
|
159
324
|
|
|
160
|
-
|
|
325
|
+
For Next.js applications, use dynamic import to disable server-side rendering:
|
|
161
326
|
|
|
162
|
-
```
|
|
163
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
453
|
+
---
|
|
172
454
|
|
|
173
|
-
|
|
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
|
-
|
|
178
|
-
|
|
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
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
-
|
|
262
|
-
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## Hotspots
|
|
501
|
+
|
|
502
|
+
Add interactive markers to highlight product features.
|
|
503
|
+
|
|
504
|
+
### Configuration
|
|
505
|
+
|
|
263
506
|
```javascript
|
|
264
|
-
const
|
|
507
|
+
const hotspots = [
|
|
265
508
|
{
|
|
266
|
-
id: '
|
|
509
|
+
id: 'feature-1',
|
|
267
510
|
orientation: 'x',
|
|
268
|
-
containerSize: [
|
|
511
|
+
containerSize: [1200, 800], // Reference container size for positioning
|
|
269
512
|
positions: {
|
|
270
|
-
0: { x:
|
|
271
|
-
1: { x:
|
|
272
|
-
2: { x:
|
|
273
|
-
3: { x:
|
|
274
|
-
|
|
275
|
-
|
|
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
|
-
|
|
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
|
-
|
|
308
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
315
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
322
|
-
|
|
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
|
-
|
|
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
|
-
|
|
331
|
-
|
|
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
|
-
|
|
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
|
-
|
|
338
|
-
|
|
339
|
-
-
|
|
340
|
-
-
|
|
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
|
-
##
|
|
882
|
+
## Browser Support
|
|
345
883
|
|
|
346
|
-
|
|
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
|
-
|
|
893
|
+
> **Note:** This library uses OffscreenCanvas for optimal performance, which requires the browser versions listed above.
|
|
349
894
|
|
|
350
|
-
|
|
895
|
+
---
|
|
351
896
|
|
|
352
|
-
|
|
897
|
+
## Migration Guide (v3 → v4)
|
|
353
898
|
|
|
354
|
-
|
|
899
|
+
Version 4 introduces significant improvements in performance, customization, and developer experience. This guide helps you upgrade from v3.
|
|
355
900
|
|
|
356
|
-
|
|
901
|
+
### Breaking Changes
|
|
357
902
|
|
|
358
|
-
|
|
903
|
+
#### 1. CSS Handling
|
|
359
904
|
|
|
360
|
-
|
|
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
|
-
|
|
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
|
-
|
|
914
|
+
```javascript
|
|
915
|
+
import CI360 from 'js-cloudimage-360-view';
|
|
916
|
+
import 'js-cloudimage-360-view/css';
|
|
917
|
+
```
|
|
368
918
|
|
|
369
|
-
|
|
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
|
-
|
|
374
|
-
|
|
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
|
-
|
|
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
|
-
|
|
399
|
-
|
|
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
|
-
<
|
|
402
|
-
|
|
403
|
-
|
|
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
|
-
##
|
|
1100
|
+
## License
|
|
411
1101
|
|
|
412
|
-
|
|
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>
|