Skip to content

mirame360/360-image-plugin

Repository files navigation

360 Image Player

npm version license

A framework-agnostic equirectangular image player built with Three.js, TypeScript, and Vite.

Features

  • Mouse, touch, pinch, inertia, zoom controls, compass, and WebXR.
  • Runtime color filters and configurable nadir covers.
  • Typed hotspots for links, quizzes, clues, locked content, and products.
  • Branded and MLS-friendly unbranded rendering modes.
  • Local canvas snapshots and high-resolution server snapshot requests.
  • Serializable player state and ZIP export for offline self-hosting.
  • React wrapper with typed callbacks.
  • GPL-3.0 licensed.

Hosting your source media

This player renders whatever equirectangular image URL you give it — you still need somewhere to upload, store, and serve the actual panorama files. Mirame360 is a free 360° photo/video hosting platform built by the same team: upload once, get optimized web-ready URLs and secure embeds, and drop them straight into this player (or use the Mirame360 WordPress plugin if your site runs WordPress).

Installation

npm install 360-image-player three

React is an optional peer dependency.

Basic Usage

import { Image360Player } from '360-image-player';

const player = new Image360Player({
  container: document.getElementById('viewer')!,
  imageUrl: [
    'https://example.com/panorama.webp',
    'https://example.com/panorama.jpeg',
  ],
  showControls: true,
  compass: true,
  initialView: { yaw: 20, pitch: 0, hfov: 80 },
  nadir: {
    imageUrl: 'https://example.com/logo.png',
    radius: 55,
  },
});

player.addHTMLOverlay({
  id: 'product-1',
  type: 'product',
  yaw: 45,
  pitch: 5,
  product: {
    id: 'chair-1',
    title: 'Chair',
    price: '$99',
    vendor: 'shopify',
  },
});

player.on('addtocart', ({ product }) => {
  // Delegate the actual cart mutation to Shopify, PrestaShop, or the host app.
  console.log(product);
});

imageUrl accepts either one URL or an ordered list. When a source cannot be loaded or decoded, the player tries the next URL and emits error only after all configured sources have failed. Existing integrations using a string do not need to change.

Viewport And Snapshots

player.setView({ yaw: 30, pitch: -5, hfov: 70 });
const viewport = player.getView();

// Optional low-cost motion for visible previews.
player.startAutoRotate(2);
player.setRenderingActive(false); // suspend GPU work while offscreen
player.setRenderingActive(true);
player.stopAutoRotate();

// Browser-resolution PNG from the current canvas.
const localBlob = await player.takeSnapshot();

// High-resolution image generated by the Mirame360 backend.
const result = await player.requestSnapshot({
  endpoint: `/api/media/${mediaId}/snapshot/`,
  width: 4096,
  height: 2304,
  format: 'jpeg',
  headers: { Authorization: `Bearer ${token}` },
});

The backend endpoint queues an FFmpeg v360 task and the player polls its authenticated status URL until the generated storage URL is available.

Gamification

player.addHTMLOverlay({
  id: 'question-1',
  type: 'quiz',
  yaw: 10,
  pitch: 0,
  title: 'Which door is correct?',
  quizChoices: [
    { id: 'left', label: 'Left' },
    { id: 'right', label: 'Right', correct: true },
  ],
  unlocks: ['exit-door'],
});

player.addHTMLOverlay({
  id: 'exit-door',
  type: 'locked',
  yaw: 90,
  pitch: 0,
  requires: ['exit-door'],
  text: 'Exit',
});

player.setGameState(savedState);
const stateToPersist = player.getGameState();

Branding And Security

Use brandingMode: 'unbranded' to hide hotspots unless they explicitly set branded: false. External URL opening can also be disabled with allowExternalLinks: false.

Custom hotspot HTML is sanitized by default. Supply sanitizeHTML to integrate a stricter application sanitizer.

Offline Export

const zip = await player.exportOffline({
  playerScriptUrl: '/assets/360-image-player.standalone.umd.min.js',
  fetchAssets: true,
});

The ZIP contains the standalone player, panorama, optional nadir image, config.json, and a ready-to-host index.html. Remote assets must allow CORS.

Main Options

Option Default Description
imageUrl required Panorama URL or ordered list of primary and fallback URLs.
autoLoad true Load the panorama immediately.
showControls true Render zoom and reset controls.
compass false Render a heading compass.
initialView { yaw: 0, pitch: 0, hfov: 90 } Initial viewport.
brandingMode branded Hide branded content in unbranded mode.
allowExternalLinks true Allow URL hotspots to open new pages.
nadir none Circular nadir image configuration.
snapshotEndpoint none Default high-resolution snapshot endpoint.
colorFilters neutral WebGL color adjustments.

Development

  • npm run build
  • npm run lint
  • npm run typecheck
  • npm run test:unit

About

Web plugin for 360 images

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages