Latest Threat Research:Malicious dYdX Packages Published to npm and PyPI After Maintainer Compromise.Details
Socket
Book a DemoInstallSign in
Socket

js-cloudimage-360-view

Package Overview
Dependencies
Maintainers
3
Versions
69
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

js-cloudimage-360-view

latest
Source
npmnpm
Version
4.3.5
Version published
Weekly downloads
1.1K
-13.25%
Maintainers
3
Weekly downloads
 
Created
Source

Cloudimage logo

JS Cloudimage 360 View

A powerful JavaScript library for creating interactive 360-degree product views

Release Size Downloads License Cloudimage

View Demo · React CodeSandbox · Vanilla CodeSandbox · Report Bug

Table of Contents

Overview

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.

Why Choose This Library?

  • Easy Integration - Get started in minutes with CDN or npm
  • Fully Customizable - CSS variables, callbacks, and extensive configuration options
  • Mobile-Friendly - Touch and swipe support out of the box
  • Performance Optimized - Lazy loading, responsive images, and efficient rendering
  • Feature Rich - Hotspots, zoom, fullscreen, autoplay, and more

Features

FeatureDescription
360° RotationSmooth horizontal and vertical rotation with customizable speed
Touch & DragIntuitive mouse and touch controls with inertia/momentum
Pinch-to-ZoomNatural pinch gesture zooming on mobile devices
AutoplayAutomatic rotation with configurable behavior and direction
ZoomPointer zoom and magnifier glass for detailed views
FullscreenImmersive fullscreen mode with ESC key support
HotspotsInteractive markers with tooltips for highlighting features
Keyboard NavigationArrow key support for accessibility
Lazy LoadingOptimized loading for better performance
ResponsiveWorks on all screen sizes with Cloudimage CDN integration
ThemingCSS variables for easy customization
Event CallbacksHook into viewer lifecycle and user interactions

Quick Start

Add the library via CDN and create your first 360 viewer in seconds:

<!-- Add the library (CSS is auto-injected) -->
<script src="https://scaleflex.cloudimg.io/v7/plugins/js-cloudimage-360-view/latest/js-cloudimage-360-view.min.js"></script>

<!-- Create a container with data attributes -->
<div
  class="cloudimage-360"
  data-folder="https://scaleflex.cloudimg.io/v7/demo/360-car/"
  data-filename-x="car-{index}.jpg"
  data-amount-x="36"
></div>

<!-- Initialize -->
<script>
  const viewer = new window.CI360();
  viewer.initAll();
</script>

Installation

<script src="https://scaleflex.cloudimg.io/v7/plugins/js-cloudimage-360-view/latest/js-cloudimage-360-view.min.js"></script>

Note: CSS is automatically injected by the script - no separate stylesheet needed.

Option 2: Package Manager

# npm
npm install js-cloudimage-360-view

# yarn
yarn add js-cloudimage-360-view

# pnpm
pnpm add js-cloudimage-360-view

Then import in your JavaScript:

import CI360 from 'js-cloudimage-360-view';
import 'js-cloudimage-360-view/css';

Usage

Method 1: Data Attributes (Declarative)

The simplest way to create a 360 viewer using HTML data attributes:

<div
  id="my-360-viewer"
  class="cloudimage-360"
  data-folder="https://your-domain.com/images/"
  data-filename-x="{index}.jpg"
  data-amount-x="36"
  data-autoplay
  data-fullscreen
  data-magnifier="2"
></div>

<script>
  const viewer = new CI360();
  viewer.initAll(); // Initializes all elements with class "cloudimage-360"
</script>

Method 2: JavaScript Configuration (Programmatic)

For more control, initialize with a JavaScript configuration object:

const viewer = new CI360();

const container = document.getElementById('product-viewer');

const config = {
  folder: 'https://your-domain.com/images/',
  filenameX: 'product-{index}.jpg',
  amountX: 36,
  autoplay: true,
  speed: 100,
  dragSpeed: 150,
  fullscreen: true,
  magnifier: 2,
  pointerZoom: 2,
  inertia: true,

  // Event callbacks
  onReady: () => console.log('Viewer ready!'),
  onSpin: (e) => console.log(`Frame: ${e.activeImageX + 1}/${e.amountX}`),
};

viewer.init(container, config);

X and Y Axis Rotation

Support 360° rotation on both axes for full product exploration:

const config = {
  folder: 'https://your-domain.com/images/',
  filenameX: 'product-x-{index}.jpg',
  filenameY: 'product-y-{index}.jpg',
  amountX: 36,
  amountY: 18,
  autoplayBehavior: 'spin-xy', // Options: 'spin-x', 'spin-y', 'spin-xy', 'spin-yx'
};

React / Next.js

The library provides a React wrapper for seamless integration with React and Next.js applications.

Installation

npm install js-cloudimage-360-view

Basic Usage

import { CI360Viewer } from 'js-cloudimage-360-view/react';
import 'js-cloudimage-360-view/css';

function ProductView() {
  return (
    <CI360Viewer
      folder="https://example.com/images/"
      filenameX="product-{index}.jpg"
      amountX={36}
      autoplay
      fullscreen
      aspectRatio="16/9"
      style={{ width: '100%', maxWidth: 800 }}
    />
  );
}

Imperative Control with Ref

Use a ref to control the viewer programmatically:

import { useRef } from 'react';
import { CI360Viewer, CI360ViewerRef } from 'js-cloudimage-360-view/react';
import 'js-cloudimage-360-view/css';

function ProductView() {
  const viewerRef = useRef<CI360ViewerRef>(null);

  return (
    <>
      <CI360Viewer
        ref={viewerRef}
        folder="https://example.com/images/"
        filenameX="{index}.jpg"
        amountX={36}
        onSpin={(e) => console.log(`Frame: ${e.activeImageX}`)}
      />
      <button onClick={() => viewerRef.current?.play()}>Play</button>
      <button onClick={() => viewerRef.current?.stop()}>Stop</button>
      <button onClick={() => viewerRef.current?.goToFrame(17)}>Go to Frame 17</button>
    </>
  );
}

Available Ref Methods

MethodDescription
play()Start autoplay
stop()Stop autoplay
moveLeft(steps?)Move left by specified frames (default: 1)
moveRight(steps?)Move right by specified frames (default: 1)
moveTop(steps?)Move up on Y-axis (default: 1)
moveBottom(steps?)Move down on Y-axis (default: 1)
zoomIn()Toggle zoom in
zoomOut()Zoom out
goToFrame(frame, hotspotId?)Animate to specific frame
getViewer()Get underlying viewer instance

With Hotspots

import { CI360Viewer, Hotspot } from 'js-cloudimage-360-view/react';

const hotspots: Hotspot[] = [
  {
    id: 'feature-1',
    label: 'Engine',
    orientation: 'x',
    containerSize: [1200, 800],
    positions: { 0: { x: 500, y: 300 } },
    content: '<div>Engine details</div>',
  },
];

function ProductView() {
  return (
    <CI360Viewer
      folder="https://example.com/images/"
      filenameX="{index}.jpg"
      amountX={36}
      hotspots={hotspots}
    />
  );
}

Next.js (SSR)

For Next.js applications, use dynamic import to disable server-side rendering:

import dynamic from 'next/dynamic';
import 'js-cloudimage-360-view/css';

const CI360Viewer = dynamic(
  () => import('js-cloudimage-360-view/react').then(mod => mod.CI360Viewer),
  { ssr: false }
);

export default function ProductPage() {
  return (
    <CI360Viewer
      folder="https://example.com/images/"
      filenameX="{index}.jpg"
      amountX={36}
    />
  );
}

useCI360 Hook

For advanced use cases, you can use the useCI360 hook directly:

import { useRef } from 'react';
import { useCI360 } from 'js-cloudimage-360-view/react';

function CustomViewer() {
  const containerRef = useRef<HTMLDivElement>(null);
  const { viewer, isReady } = useCI360(containerRef, {
    folder: 'https://example.com/images/',
    filenameX: '{index}.jpg',
    amountX: 36,
    onReady: () => console.log('Viewer ready!'),
  });

  return (
    <div>
      <div ref={containerRef} style={{ width: '100%', maxWidth: 800, aspectRatio: '16/9' }} />
      {isReady && <p>Viewer is ready!</p>}
    </div>
  );
}

TypeScript Support

The React wrapper is fully typed. Import types as needed:

import type {
  CI360ViewerProps,
  CI360ViewerRef,
  CI360Config,
  SpinEventData,
  Hotspot,
} from 'js-cloudimage-360-view/react';

Configuration Options

All options can be set via JavaScript config or HTML data attributes.

Image Source Options

OptionData AttributeDefaultDescription
folderdata-folder'/'Path to the folder containing images
filenameXdata-filename-x'image-{index}.jpg'Filename pattern for X-axis images. Use {index} as placeholder
filenameYdata-filename-ynullFilename pattern for Y-axis images
imageListXdata-image-list-xnullArray of image URLs for X-axis (alternative to folder/filename)
imageListYdata-image-list-ynullArray of image URLs for Y-axis
amountXdata-amount-x0Total number of X-axis images
amountYdata-amount-y0Total number of Y-axis images
indexZeroBasedata-index-zero-base0Starting index for image filenames

Behavior Options

OptionData AttributeDefaultDescription
autoplaydata-autoplayfalseEnable automatic rotation
autoplayBehaviordata-autoplay-behavior'spin-x'Autoplay pattern: 'spin-x', 'spin-y', 'spin-xy', 'spin-yx'
autoplayReversedata-autoplay-reversefalseReverse autoplay direction
playOncedata-play-oncefalseStop after one complete rotation
speeddata-speed80Autoplay speed (ms between frames)
inertiadata-inertiafalseEnable momentum after drag release

Control Options

OptionData AttributeDefaultDescription
draggabledata-draggabletrueEnable mouse drag rotation
swipeabledata-swipeabletrueEnable touch swipe rotation
dragSpeeddata-drag-speed150Drag sensitivity
dragReversedata-drag-reversefalseReverse drag direction
keysdata-keysfalseEnable keyboard arrow navigation
keysReversedata-keys-reversefalseReverse keyboard direction
stopAtEdgesdata-stop-at-edgesfalseStop rotation at first/last frame
pinchZoomdata-pinch-zoomtrueEnable pinch-to-zoom on touch devices

Display Options

OptionData AttributeDefaultDescription
aspectRatiodata-aspect-rationullAspect ratio for the container (e.g., "16/9", "4/3", "1/1")
fullscreendata-fullscreenfalseShow fullscreen button
magnifierdata-magnifiernullMagnifier zoom level (1-5)
pointerZoomdata-pointer-zoom0Pointer zoom level on click (1-5)
bottomCircledata-bottom-circletrueShow 360° progress indicator
bottomCircleOffsetdata-bottom-circle-offset5Progress indicator offset (px)
initialIconShowndata-initial-icontrueShow 360° icon on load
lazyloaddata-lazyloadtrueEnable lazy loading
hintsdata-hintstrueShow interaction hints on load
themedata-themenullColor theme: 'light' or 'dark'
hotspotTriggerdata-hotspot-trigger'hover'Hotspot trigger mode: 'hover' or 'click'
hotspotTimelineOnClickdata-hotspot-timeline-on-clicktrueShow hotspot popup when clicking timeline dot

Cloudimage CDN Options

OptionData AttributeDefaultDescription
ciTokendata-responsivenullCloudimage token for responsive images
ciFiltersdata-filtersnullCloudimage filters
ciTransformationdata-transformationnullCloudimage transformations

Event Callbacks

Hook into viewer events for custom functionality. Callbacks are only available via JavaScript configuration.

CallbackEvent DataDescription
onReady{ viewerId }Viewer initialized and ready
onLoad{ viewerId, imagesX, imagesY }All images loaded
onSpin{ viewerId, direction, activeImageX, activeImageY, amountX, amountY }Each rotation frame
onAutoplayStart{ viewerId }Autoplay started
onAutoplayStop{ viewerId }Autoplay stopped
onDragStart{ viewerId }User started dragging
onDragEnd{ viewerId }User stopped dragging
onZoomIn{ viewerId, zoomLevel }Pointer zoom activated
onZoomOut{ viewerId }Pointer zoom deactivated
onFullscreenOpen{ viewerId }Fullscreen mode opened
onFullscreenClose{ viewerId }Fullscreen mode closed

Example

const config = {
  folder: 'https://example.com/images/',
  filenameX: '{index}.jpg',
  amountX: 36,

  onReady: (e) => {
    console.log(`Viewer ${e.viewerId} is ready`);
  },

  onSpin: (e) => {
    // Update custom progress indicator
    const progress = ((e.activeImageX + 1) / e.amountX * 100).toFixed(0);
    document.getElementById('progress').textContent = `${progress}%`;
  },

  onFullscreenOpen: () => {
    // Pause background video when entering fullscreen
    document.getElementById('bg-video')?.pause();
  },
};

Hotspots

Add interactive markers to highlight product features.

Configuration

const hotspots = [
  {
    id: 'feature-1',
    orientation: 'x',
    containerSize: [1200, 800], // Reference container size for positioning
    positions: {
      0: { x: 500, y: 300 },
      1: { x: 520, y: 300 },
      2: { x: 540, y: null }, // null inherits from previous frame
      3: { x: 560, y: null },
      // ... positions for frames where hotspot is visible
    },
    content: '<div class="tooltip"><strong>Premium Feature</strong><p>Description here</p></div>',
    onClick: () => {
      console.log('Hotspot clicked!');
    },
  },
];

const config = {
  folder: 'https://example.com/images/',
  filenameX: '{index}.jpg',
  amountX: 36,
  hotspots: hotspots,
};

Hotspot Properties

PropertyRequiredDescription
idYesUnique identifier
orientationYes'x' or 'y' axis
containerSizeYes[width, height] reference dimensions
positionsYesObject mapping frame index to { x, y } coordinates
contentYesHTML content for the tooltip
labelNoShort label for the hotspot (used in timeline tooltips)
onClickNoClick handler function

Hotspot Timeline

When hotspots are configured, a timeline navigation bar automatically appears below the viewer. This timeline shows:

  • Position indicator - Shows current rotation position
  • Hotspot dots - One dot per hotspot at its center frame position
  • Hover tooltips - If a hotspot has a label, hovering over its dot shows a tooltip

Clicking a dot animates the viewer to that hotspot's position and optionally shows its popup.

Timeline Tooltips

Tooltips display the hotspot's label property when hovering over a timeline dot:

const hotspots = [
  {
    id: 'engine',
    label: 'Engine Bay',  // This text appears in the tooltip
    orientation: 'x',
    containerSize: [1200, 800],
    positions: { 0: { x: 500, y: 300 }, /* ... */ },
    content: '<div>Full hotspot content here</div>',
  },
];

Tooltip behavior:

  • Appears after a 400ms hover delay to prevent accidental triggers
  • Positioned above the dot with an arrow pointer
  • Hidden on mouse leave or click (navigation)

Timeline Configuration

OptionDefaultDescription
hotspotTimelineOnClicktrueShow hotspot popup when clicking a timeline dot
const config = {
  hotspots: [...],
  hotspotTimelineOnClick: true,  // Show popup on click (default)
  // or
  hotspotTimelineOnClick: false, // Only navigate, don't show popup
};

Timeline CSS Variables

Customize the timeline appearance with CSS variables:

:root {
  /* Timeline track */
  --ci360-timeline-height: 6px;
  --ci360-timeline-track-bg: rgba(0, 0, 0, 0.12);

  /* Hotspot dots */
  --ci360-timeline-dot-size: 18px;
  --ci360-timeline-dot-color: var(--ci360-hotspot-color);
  --ci360-timeline-dot-border: 2px solid #fff;

  /* Position indicator */
  --ci360-timeline-indicator-size: 12px;
  --ci360-timeline-indicator-color: #333333;

  /* Tooltip styling (matches theme) */
  --ci360-timeline-tooltip-bg: rgba(255, 255, 255, 0.95);
  --ci360-timeline-tooltip-color: #333333;
}

/* Dark theme uses dark tooltip */
.ci360-theme-dark {
  --ci360-timeline-tooltip-bg: rgba(40, 40, 45, 0.95);
  --ci360-timeline-tooltip-color: #e0e0e0;
}

Custom tooltip styling example:

/* Increase tooltip font size */
.cloudimage-360-hotspot-timeline-tooltip {
  font-size: 14px;
  padding: 8px 16px;
}

/* Brand-colored tooltip */
.my-viewer {
  --ci360-timeline-tooltip-bg: #2563eb;
  --ci360-timeline-tooltip-color: #ffffff;
}

Interaction Hints

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.

Configuration

const config = {
  // Auto-detect hints based on enabled features (default)
  hints: true,

  // Disable hints
  hints: false,

  // Custom hints array
  hints: ['drag', 'click', 'keys'],
};

Available Hint Types

TypeDesktopMobileDescription
drag-"Drag to rotate"
swipe-"Swipe to rotate"
click-"Click to zoom" (when pointerZoom enabled)
pinch-"Pinch to zoom" (when pinchZoom enabled)
keys-"Use arrow keys" (when keys enabled)

Styling & Theming

Built-in Themes

Apply a theme by setting the theme option or using the ci360-theme-dark class:

// Via config
const config = {
  theme: 'dark', // or 'light'
  // ...other options
};

// Or via HTML
<div class="cloudimage-360 ci360-theme-dark" ...></div>

The easiest way to customize the viewer appearance:

:root {
  /* Buttons */
  --ci360-button-bg: #f0f0f0;
  --ci360-button-bg-hover: #e0e0e0;
  --ci360-button-size: 40px;
  --ci360-button-border-radius: 6px;
  --ci360-button-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

  /* Icons */
  --ci360-icon-color: #37414b;
  --ci360-icon-color-hover: #1a1f24;
  --ci360-icon-size: 20px;

  /* 360° Indicator */
  --ci360-initial-icon-bg: rgba(255, 255, 255, 0.9);
  --ci360-initial-icon-color: #505050;
  --ci360-initial-icon-size: 80px;
  --ci360-initial-icon-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);

  /* Loading Spinner */
  --ci360-spinner-color: #fff;
  --ci360-spinner-accent: #a3a3a3;
  --ci360-spinner-size: 30px;

  /* Fullscreen */
  --ci360-fullscreen-bg: #fff;

  /* Magnifier */
  --ci360-magnifier-size: 250px;
  --ci360-magnifier-border: 2px solid rgba(0, 0, 0, 0.3);
  --ci360-magnifier-shadow: 0 8px 16px rgba(0, 0, 0, 0.4);

  /* Hotspots */
  --ci360-hotspot-color: #00aaff;
  --ci360-hotspot-border: 1px solid #fff;
  --ci360-hotspot-size: 18px;

  /* Tooltips */
  --ci360-popper-bg: rgba(255, 255, 255, 0.95);
  --ci360-popper-color: #333;
  --ci360-popper-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  --ci360-popper-border-radius: 6px;

  /* Hints Overlay */
  --ci360-hints-bg: rgba(0, 0, 0, 0.75);
  --ci360-hints-color: #ffffff;
  --ci360-hints-font-size: 14px;
  --ci360-hints-border-radius: 12px;

  /* Bottom Circle Indicator */
  --ci360-circle-color-start: rgba(0, 0, 0, 0.05);
  --ci360-circle-color-mid: rgba(0, 0, 0, 0.3);
  --ci360-circle-color-end: rgba(0, 0, 0, 0.05);
  --ci360-circle-dot-color: rgba(0, 0, 0, 0.4);

  /* Other */
  --ci360-focus-color: #0066cc;
  --ci360-overlay-bg: rgba(255, 255, 255, 1);
}

Custom Dark Theme Example

If you prefer to customize beyond the built-in dark theme:

.my-dark-viewer {
  --ci360-button-bg: rgba(30, 30, 35, 0.9);
  --ci360-button-bg-hover: rgba(45, 45, 50, 0.95);
  --ci360-icon-color: #e0e0e0;
  --ci360-icon-color-hover: #ffffff;
  --ci360-fullscreen-bg: #1a1a1f;
  --ci360-initial-icon-bg: rgba(30, 30, 35, 0.9);
  --ci360-initial-icon-color: #e0e0e0;
  --ci360-popper-bg: rgba(40, 40, 45, 0.95);
  --ci360-popper-color: #e0e0e0;
  --ci360-hints-bg: rgba(255, 255, 255, 0.12);
  --ci360-circle-color-mid: rgba(255, 255, 255, 0.25);
  --ci360-circle-dot-color: rgba(255, 255, 255, 0.4);
  --ci360-overlay-bg: rgba(26, 26, 31, 1);
}

Scope to Specific Viewer

#my-special-viewer {
  --ci360-button-bg: #4a90d9;
  --ci360-icon-color: #ffffff;
  --ci360-hotspot-color: #ff6b6b;
}

CSS Classes Reference

ClassDescription
.cloudimage-360Main container
.cloudimage-360-inner-boxInner container
.cloudimage-360-buttonControl buttons
.cloudimage-360-icons-containerButton container
.cloudimage-initial-icon360° indicator icon
.cloudimage-360-view-360-circleBottom progress indicator
.cloudimage-loading-spinnerLoading spinner
.cloudimage-360-fullscreen-modalFullscreen container
.cloudimage-360-img-magnifier-glassMagnifier element
.cloudimage-360-hotspotHotspot marker
.cloudimage-360-popperHotspot tooltip
.cloudimage-360-hints-overlayHints overlay container
.cloudimage-360-hints-containerHints content box
.cloudimage-360-hotspot-timelineHotspot timeline container
.cloudimage-360-hotspot-timeline-trackTimeline track
.cloudimage-360-hotspot-timeline-dotTimeline hotspot dot
.cloudimage-360-hotspot-timeline-indicatorTimeline position indicator
.cloudimage-360-hotspot-timeline-tooltipTimeline dot tooltip (appears on hover)
.ci360-theme-darkDark theme class

Methods

Instance Methods

const viewer = new CI360();

// Initialize all viewers with class "cloudimage-360"
viewer.initAll();

// Initialize a specific container
viewer.init(containerElement, config);

// Get a viewer by its container ID
const view = viewer.getViewById('my-viewer');

// Get all viewer instances
const allViews = viewer.getViews();

// Update a viewer's configuration
viewer.updateView('my-viewer', { speed: 50, autoplay: true });

View Methods

const view = viewer.getViewById('my-viewer');

// Playback control
view.play();                    // Start autoplay
view.stopAutoplay();            // Stop autoplay

// Rotation (stopAtEdges: boolean, steps: number)
view.moveLeft(false, 5);        // Rotate left by 5 frames
view.moveRight(false, 5);       // Rotate right by 5 frames
view.moveTop(false, 1);         // Rotate up by 1 frame (Y-axis)
view.moveBottom(false, 1);      // Rotate down by 1 frame (Y-axis)

// Navigation
view.animateToFrame(36);        // Animate to frame 36
view.animateToFrame(10, 'hotspot-1'); // Go to frame and show hotspot

// UI control
view.hideAllIcons();            // Hide all overlay icons

// State
view.activeImageX;              // Current X-axis frame (0-indexed)
view.activeImageY;              // Current Y-axis frame (0-indexed)
view.amountX;                   // Total X-axis frames
view.amountY;                   // Total Y-axis frames

// Cleanup
view.destroy();                 // Destroy the viewer

Cloudimage Integration

Enhance performance with Cloudimage CDN for responsive, optimized images.

Setup

  • Register at cloudimage.io to get your token
  • Add the token to your viewer configuration:
const config = {
  folder: 'https://your-domain.com/images/',
  filenameX: '{index}.jpg',
  amountX: 36,
  ciToken: 'your-cloudimage-token', // or use data-responsive attribute
};

Benefits

  • 25GB free CDN traffic per month
  • Automatic optimization - WebP, AVIF conversion
  • Responsive images - Serve the right size for each device
  • Global CDN - Fast delivery worldwide
  • Image transformations - Resize, crop, filters on-the-fly

Browser Support

BrowserVersion
Chrome69+
Firefox105+
Safari16.4+
Edge79+
iOS Safari16.4+
Android Chrome69+

Note: This library uses OffscreenCanvas for optimal performance, which requires the browser versions listed above.

Mobile Considerations

Memory Limitations

Mobile browsers (especially Safari) have strict memory limits that can cause tab crashes when loading many high-resolution images. The library includes built-in optimizations for mobile that are automatically enabled:

  • Sequential image loading (3 concurrent on mobile vs 6 on desktop)
  • Main-thread canvas rendering (avoids OffscreenCanvas memory issues on Safari)
  • Reduced touch event rate (30fps vs 100fps on desktop)
  • Capped device pixel ratio (max 2x on mobile)
  • Automatic memory management (releases off-screen viewers, frees memory when page backgrounded)
SettingDesktopMobileNotes
amountX60-100+30-40 maxEach image uses ~4MB GPU memory
pointerZoomLoads higher-res images
magnifierLoads higher-res images

Detecting Mobile Devices

The library automatically detects mobile devices, but you can also adjust your configuration:

const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
  navigator.userAgent
);

const viewer = new CI360();
viewer.init(container, {
  folder: 'https://example.com/images/',
  filenameX: '{index}.jpg',
  amountX: isMobile ? 36 : 72,           // Fewer images on mobile
  pointerZoom: isMobile ? false : 2,     // Disable zoom on mobile
  magnifier: isMobile ? false : 3,       // Disable magnifier on mobile
});

Memory Management API

Memory management is automatically enabled on mobile. For desktop or manual control:

const viewer = new CI360();
viewer.initAll();

// Manually enable (already auto-enabled on mobile)
viewer.enableMemoryManagement();

// Disable if needed
viewer.disableMemoryManagement();

This uses IntersectionObserver to:

  • Release memory when viewers scroll off-screen
  • Reload images when viewers become visible again
  • Release all viewer memory when the page is backgrounded

Migration Guide (v3 → v4)

Version 4 introduces significant improvements in performance, customization, and developer experience. This guide helps you upgrade from v3.

Breaking Changes

1. CSS Handling

For CDN users, CSS is now auto-injected (same as v3):

<!-- v4: Just include the script -->
<script src=".../js-cloudimage-360-view.min.js"></script>

For npm/bundler users, import CSS separately:

import CI360 from 'js-cloudimage-360-view';
import 'js-cloudimage-360-view/css';

2. Initialization API Changed

// v3
window.CI360.init();
window.CI360.add('my-viewer');
window.CI360.update('my-viewer', true);
window.CI360.destroy();

// v4
const viewer = new CI360();
viewer.initAll();                           // Initialize all
viewer.init(container, config);             // Initialize specific container
viewer.updateView('my-viewer', newConfig);  // Update with new config
viewer.getViewById('my-viewer').destroy();  // Destroy specific viewer

3. Browser Requirements Changed

v4 uses OffscreenCanvas for performance, requiring newer browsers:

Browserv3v4
Safari12+16.4+
iOS Safari12+16.4+
Firefox55+105+
Chrome60+69+

Deprecated Configuration Options

The following options have been removed in v4:

v3 Optionv4 Alternative
data-box-shadowUse CSS: .cloudimage-360 { box-shadow: ... }
data-ratioContainer automatically maintains aspect ratio
data-lazy-selectorUse data-lazyload (boolean)
data-hide-360-logoUse data-initial-icon (boolean, inverted)
data-logo-srcCustom logos not supported; use CSS to hide
data-image-infoRemoved
data-request-responsive-imagesRemoved
data-disable-dragUse data-draggable (inverted: draggable="false")
data-spin-reverseUse data-drag-reverse and data-autoplay-reverse

Hotspot Configuration Changes

Hotspot properties have been simplified:

// v3 - Multiple specific properties
const hotspot = {
  id: 'feature-1',
  title: 'Feature Title',
  description: 'Description text',
  url: 'https://example.com',
  newTab: true,
  moreDetailsUrl: 'https://example.com/details',
  moreDetailsTitle: 'Learn More',
  popupSelector: '#custom-popup',
  arrow: true,
  placement: 'top',
  offset: [0, 10],
  positions: { 0: { x: 100, y: 200 } },
};

// v4 - Flexible HTML content
const hotspot = {
  id: 'feature-1',
  orientation: 'x',
  containerSize: [1200, 800],
  positions: { 0: { x: 100, y: 200 } },
  content: `
    <div class="my-tooltip">
      <h3>Feature Title</h3>
      <p>Description text</p>
      <a href="https://example.com" target="_blank">Learn More</a>
    </div>
  `,
  onClick: () => console.log('Clicked!'),
};
v3 Propertyv4 Alternative
title, descriptionUse content with HTML
url, newTabInclude <a> tag in content
moreDetailsUrl, moreDetailsTitleInclude in content HTML
popupSelectorUse content with your HTML
arrow, placement, offsetPopper.js handles positioning automatically
openRemoved; hotspots open on click/hover

New Features in v4

Take advantage of these new capabilities:

CSS Variables for Theming

:root {
  --ci360-button-bg: #f0f0f0;
  --ci360-icon-color: #333;
  --ci360-hotspot-color: #00aaff;
}

Built-in Themes

<div class="cloudimage-360 ci360-theme-dark" ...></div>

Event Callbacks

const config = {
  onReady: (e) => console.log('Ready'),
  onSpin: (e) => console.log(`Frame: ${e.activeImageX}`),
  onFullscreenOpen: () => console.log('Fullscreen'),
};

Interaction Hints

const config = {
  hints: true,  // Auto-detect hints
  // or
  hints: ['drag', 'click', 'keys'],  // Custom hints
};

Pinch-to-Zoom (Mobile)

const config = {
  pinchZoom: true,  // Enabled by default
};

Quick Migration Checklist

  • Add CSS file import alongside JS
  • Update initialization code to use new CI360()
  • Replace data-disable-drag with data-draggable="false"
  • Replace data-spin-reverse with data-drag-reverse
  • Replace data-hide-360-logo with data-initial-icon="false"
  • Update hotspot configs to use content instead of individual properties
  • Test on Safari 16.4+ (older versions not supported)
  • Consider adding CSS variables for customization
  • Consider adding event callbacks for analytics/tracking

Contributing

We welcome contributions! Here's how you can help:

Development Setup

git clone https://github.com/Scaleflex/js-cloudimage-360-view.git
cd js-cloudimage-360-view
npm install
npm run dev
Contributors
Contributors

License

This project is licensed under the MIT License.

Made with care by the Scaleflex team

Keywords

image

FAQs

Package last updated on 24 Jan 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts