Skip to content

<oim-player> Developer Reference ​

<oim-player> is a premium, framework-agnostic Web Component that handles high-performance rendering of Object Interactive Media (both .oim images and .ovm interactive videos) with real-time multilingual injection in the dynamic layer.

Features ​

  • Shadow DOM Isolation: Complete style encapsulation prevents container page stylesheets from leaking or interfering with the player layers and interactivity.
  • Dynamic CSS Tokens: Simple styling customizations of controls and views using CSS custom properties (--oim-*).
  • Low-End Device Optimization: Automatically suspends rendering and layout computations of paused videos to zero out CPU cycles.
  • Native Lazy Loading: Integrates IntersectionObserver to defer network fetches and rendering until the player enters the viewport.
  • Unified Engine Architecture: Dynamically swaps between rendering engines (ImageEngine or VideoEngine) by reading the file's binary header signatures.
  • Dynamic Aspect Ratio Scaling: Features a precision dimensions calculator and ResizeObserver to adapt the canvas size to the host container dynamically.
  • Self-Contained Binary Fonts: Loads fonts packaged directly inside the .oim binary before lifting the curtain, ensuring zero external font requests and zero layout shift.

Installation & Basic Usage ​

Include the script in your HTML document and declare the custom tag:

html
<!-- Import the Web Component bundle -->
<script src="https://cdn.oim.media/oim-player.js"></script>

<!-- Declare the player in the DOM -->
<oim-player 
  src="hero.oim" 
  lang="en" 
  fit="contain" 
  align="center">
</oim-player>

Attributes & API ​

AttributeTypeDefaultDescription
srcstring""URL of the target .oim image or .ovm video file.
langstring"en"Active language code to display localized slot contents.
fit"contain" | "cover""contain"Controls the containment fit mode of the interactive canvas.
align"center" | "top" | "bottom""center"Vertical alignment of the interactive viewport.
allow-lottiebooleantruePermits or restricts loading of Vector Lottie JSON animations.
disable-animationsbooleanfrom modeDisables all visual animations (loops, hovers, Lottie) for accessibility (respects prefers-reduced-motion).
mode"image" | "full""image"Preset for the two capability flags below. image is a still picture with its language; full moves and responds. An explicit flag overrides the preset.
disable-actionsbooleanfrom modeSuspends click and hover actions declared in the file. Not affected by prefers-reduced-motion: that is a vestibular preference about motion, not a waiver of the ability to interact.
auto-rotate-langnumber | "false""false"Interval in ms to automatically cycle through available languages.
placeholderstringnoneThumbnail shown until the player paints. Only http:, https:, blob: and data:image/ URLs are used.
activate-on"visible" | "hover" | "manual""visible"hover moves the file only under the pointer (touch devices behave as visible); manual leaves it to play() and pause().
palettestringfile defaultName of one of the file's palettes. Unknown names are ignored.
show-slotsbooleantruefalse draws only the base image.

Advanced Features ​

Disabling Animations (disable-animations) ​

If enabled, or if the user's OS prefers reduced motion (prefers-reduced-motion: reduce), the player:

  • Halts all CSS keyframe loops and hover effects.
  • Loads Lottie files with loop: false, autoplay: false, and pauses them at frame 0.

Auto-Rotate Languages (auto-rotate-lang) ​

Dynamically rotate through all available translations in the metadata:

html
<!-- Cycle through languages every 4 seconds (4000ms) -->
<oim-player src="product.oim" auto-rotate-lang="4000"></oim-player>

The cycle automatically pauses when the video is paused (OVM mode) and resumes on playback.

JavaScript API Methods ​

You can control the custom element programmatically via JavaScript:

javascript
const player = document.querySelector('oim-player');

// Change language dynamically
player.setLang('es');

// Adjust zoom level (1.0 to 4.0)
player.setZoom(1.8);

// Play / Pause (OVM video engine only, toggles language rotation)
player.play();
player.pause();

// Seek to timestamp (OVM video engine only)
player.seek(12.5); // time in seconds

Styling Customizations (CSS Variables) ​

Customize the visual buttons, fonts, and backgrounds by adjusting the CSS variables in the component context:

css
oim-player {
  /* System Colors */
  --oim-bg: #050505;
  --oim-primary: #f59e0b;
  --oim-primary-hover: #fbbf24;
  --oim-red: #ef4444;
  
  /* User Interface & Controls */
  --oim-control-bg: rgba(0, 0, 0, 0.75);
  --oim-control-border: rgba(255, 255, 255, 0.15);
  --oim-control-text: #f0f0f0;
  --oim-control-hover-bg: rgba(255, 255, 255, 0.2);
  --oim-control-text-hover: #000000;
  
  /* Border Radii and Speeds */
  --oim-transition-duration: 0.2s;
  --oim-border-radius: 20px;
}

Imperative Mounting API ​

For dynamic SPA single-page environments, use the static OimPlayer.mount() method to instantiate a player over any DOM wrapper element:

javascript
import 'oim-player.js';

OimPlayer.mount('player-container-id', 'promo.ovm', {
  allowZoom: false,
  showLanguageSelector: true,
  showSlots: true,
  fit: 'contain',
  align: 'center'
});

Custom Lifecycle Events ​

The component dispatches standard HTML custom events to communicate engine and loading states:

oim:loaded ​

Dispatched when the metadata is successfully decrypted, validated, and mounted.

javascript
player.addEventListener('oim:loaded', (e) => {
  const { type, metadata } = e.detail;
  console.log(`OIM ${type} engine loaded successfully. Metadata:`, metadata);
});

oim:action ​

Dispatched when a slot's declared action runs. The file cannot cause anything on its own — no handler, no URL, no destination outside itself. It only announces, and only matters if the page listens. preventDefault() suppresses the local effect.

javascript
player.addEventListener('oim:action', (e) => {
  const { slot, name, trigger, targets, types } = e.detail;
  // If you want a click to navigate, the PAGE decides — with its own URL.
  if (name === 'Buy') window.location.href = '/product/42';
});

types can include play (contract 1.22.0). Shown and hidden layers move as their style.reveal says; with disable-animations or prefers-reduced-motion: reduce they appear and disappear instantly and play does nothing. pause() also freezes a reveal or a play in progress, and play() resumes it.


Dynamic Scaling Engine ​

To prevent interactive layouts from stretching or pixelating, .oim-player-viewport calculates its coordinates based on the original asset resolution.

  • Fit Contain (fit="contain"): Measures parent container space and scales the viewport to fit perfectly without cropping or distortion.
  • Fit Cover (fit="cover"): Scales the viewport to cover the container area entirely, clipping overflow margins.
  • Resize Watcher: Listens via a ResizeObserver to window resizes and parent layout modifications, dynamically recalibrating scales.

Advanced Integrations & Diagnostics ​

Premium Scrollbar Styling ​

Match high-fidelity dark themes without native browser scrollbars using webkit CSS selectors:

css
/* Custom fine scrollbar */
.custom-scrollbar::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
.custom-scrollbar::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.01);
  border-radius: 8px;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  transition: background 0.2s;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
  background: rgba(245, 158, 11, 0.4);
}

High-Fidelity JSON Syntax Highlighting ​

Render extracted metadata outputs programmatically using regex replacements:

javascript
function syntaxHighlightJson(json) {
  if (!json) return '';
  let str = typeof json !== 'string' ? JSON.stringify(json, null, 2) : json;
  
  str = str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
  
  return str.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)/g, function (match) {
    let style = 'color: #38bdf8;'; // numbers
    if (/^"/.test(match)) {
      if (/:$/.test(match)) {
        style = 'color: #fbbf24; font-weight: 600;'; // keys
      } else {
        style = 'color: #34d399;'; // strings
      }
    } else if (/true|false/.test(match)) {
      style = 'color: #c084fc; font-weight: bold;'; // booleans
    } else if (/null/.test(match)) {
      style = 'color: #71717a; font-style: italic;'; // nulls
    }
    return `<span style="${style}">${match}</span>`;
  });
}

Custom Integration without Web Components (Headless / Core Mode) ​

If you wish to integrate OIM into your own custom viewer or third-party application, you are not required to use the <oim-player> HTML tag. The ecosystem is designed under a modular principle that allows files to be decoded and rendered independently:

Option A: Pure Decoding with @oim-media/core (No HTML) ​

To extract metadata from an OIM file and render it using your own custom components (e.g., in React, Vue, Svelte, or a 2D Canvas):

javascript
import { extractOIM } from '@oim-media/core';

// 1. Fetch the .oim or .png file
const response = await fetch('image.oim');
const blob = await response.blob();

// 2. Extract metadata and the clean image (Layer −1)
const { image, metadata } = await extractOIM(blob);

// 'image' is an OIM-free PNG Blob ready to be placed in a standard <img>.
// 'metadata' is the OIM JSON containing slots and interactions.
console.log("OIM Metadata:", metadata);

Option B: Programmatic Initialization with ImageEngine ​

If you want the OIM engine to handle slot injection into the DOM but prefer to control the instance programmatically in JavaScript (without Web Components):

javascript
import { ImageEngine } from '@oim-media/player-oim/engines';

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

// Instantiate the engine on the container
const engine = new ImageEngine(myContainer, {
  disableAnimations: false,
  allowZoom: true
});

// Load the interactive file
await engine.load('image.oim');