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 +978 -275
- package/dist/js-cloudimage-360-view.min.css +1 -1
- package/dist/js-cloudimage-360-view.min.js +1490 -901
- 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 +48 -8
- package/src/react/types.d.ts +228 -0
- package/src/types/ci360.d.ts +66 -0
- package/.prettierrc +0 -9
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,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="
|
|
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 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
|
-
|
|
120
|
+
## Installation
|
|
92
121
|
|
|
93
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
104
|
-
#### Option 2: Install with Package Manager
|
|
131
|
+
### Option 2: Package Manager
|
|
105
132
|
|
|
106
|
-
|
|
133
|
+
```bash
|
|
134
|
+
# npm
|
|
135
|
+
npm install js-cloudimage-360-view
|
|
107
136
|
|
|
108
|
-
|
|
137
|
+
# yarn
|
|
138
|
+
yarn add js-cloudimage-360-view
|
|
109
139
|
|
|
110
|
-
|
|
111
|
-
|
|
140
|
+
# pnpm
|
|
141
|
+
pnpm add js-cloudimage-360-view
|
|
112
142
|
```
|
|
113
143
|
|
|
114
|
-
|
|
144
|
+
Then import in your JavaScript:
|
|
115
145
|
|
|
116
|
-
```
|
|
117
|
-
|
|
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
|
-
|
|
177
|
+
### Method 2: JavaScript Configuration (Programmatic)
|
|
178
|
+
|
|
179
|
+
For more control, initialize with a JavaScript configuration object:
|
|
121
180
|
|
|
122
181
|
```javascript
|
|
123
|
-
|
|
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
|
-
|
|
206
|
+
### X and Y Axis Rotation
|
|
207
|
+
|
|
208
|
+
Support 360° rotation on both axes for full product exploration:
|
|
127
209
|
|
|
128
210
|
```javascript
|
|
129
|
-
|
|
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
|
-
|
|
223
|
+
## React / Next.js
|
|
134
224
|
|
|
135
|
-
|
|
225
|
+
The library provides a React wrapper for seamless integration with React and Next.js applications.
|
|
136
226
|
|
|
137
|
-
|
|
227
|
+
### Installation
|
|
138
228
|
|
|
139
|
-
|
|
229
|
+
```bash
|
|
230
|
+
npm install js-cloudimage-360-view
|
|
231
|
+
```
|
|
140
232
|
|
|
141
|
-
|
|
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
|
-
|
|
144
|
-
|
|
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
|
-
|
|
282
|
+
### Available Ref Methods
|
|
147
283
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
-
|
|
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
|
-
|
|
325
|
+
### Next.js (SSR)
|
|
159
326
|
|
|
160
|
-
|
|
327
|
+
For Next.js applications, use dynamic import to disable server-side rendering:
|
|
161
328
|
|
|
162
|
-
```
|
|
163
|
-
|
|
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
|
-
|
|
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
|
-
|
|
389
|
+
---
|
|
170
390
|
|
|
171
|
-
|
|
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
|
-
|
|
174
|
-
To initialize a view programmatically, use the following configuration options:
|
|
455
|
+
---
|
|
175
456
|
|
|
457
|
+
## Event Callbacks
|
|
176
458
|
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
-
|
|
262
|
-
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
## Hotspots
|
|
503
|
+
|
|
504
|
+
Add interactive markers to highlight product features.
|
|
505
|
+
|
|
506
|
+
### Configuration
|
|
507
|
+
|
|
263
508
|
```javascript
|
|
264
|
-
const
|
|
509
|
+
const hotspots = [
|
|
265
510
|
{
|
|
266
|
-
id: '
|
|
511
|
+
id: 'feature-1',
|
|
267
512
|
orientation: 'x',
|
|
268
|
-
containerSize: [
|
|
513
|
+
containerSize: [1200, 800], // Reference container size for positioning
|
|
269
514
|
positions: {
|
|
270
|
-
0: { x:
|
|
271
|
-
1: { x:
|
|
272
|
-
2: { x:
|
|
273
|
-
3: { x:
|
|
274
|
-
|
|
275
|
-
|
|
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
|
-
|
|
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
|
-
|
|
308
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
315
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
322
|
-
|
|
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
|
-
|
|
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
|
-
|
|
331
|
-
|
|
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
|
-
|
|
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
|
-
|
|
338
|
-
|
|
339
|
-
-
|
|
340
|
-
-
|
|
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
|
-
##
|
|
884
|
+
## Browser Support
|
|
345
885
|
|
|
346
|
-
|
|
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
|
-
|
|
895
|
+
> **Note:** This library uses OffscreenCanvas for optimal performance, which requires the browser versions listed above.
|
|
349
896
|
|
|
350
|
-
|
|
897
|
+
---
|
|
351
898
|
|
|
352
|
-
|
|
899
|
+
## Migration Guide (v3 → v4)
|
|
353
900
|
|
|
354
|
-
|
|
901
|
+
Version 4 introduces significant improvements in performance, customization, and developer experience. This guide helps you upgrade from v3.
|
|
355
902
|
|
|
356
|
-
|
|
903
|
+
### Breaking Changes
|
|
357
904
|
|
|
358
|
-
|
|
905
|
+
#### 1. CSS File Required
|
|
359
906
|
|
|
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.
|
|
907
|
+
v4 requires importing the CSS file separately:
|
|
363
908
|
|
|
364
|
-
|
|
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
|
-
|
|
918
|
+
For npm users:
|
|
368
919
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
920
|
+
```javascript
|
|
921
|
+
// v4
|
|
922
|
+
import CI360 from 'js-cloudimage-360-view';
|
|
923
|
+
import 'js-cloudimage-360-view/css';
|
|
924
|
+
```
|
|
372
925
|
|
|
373
|
-
|
|
374
|
-
<summary>Contributing Guidelines</summary>
|
|
926
|
+
#### 2. Initialization API Changed
|
|
375
927
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
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
|
-
|
|
399
|
-
|
|
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
|
-
<
|
|
402
|
-
|
|
403
|
-
|
|
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
|
-
##
|
|
1107
|
+
## License
|
|
411
1108
|
|
|
412
|
-
|
|
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>
|