<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
IntersectionObserverto defer network fetches and rendering until the player enters the viewport. - Unified Engine Architecture: Dynamically swaps between rendering engines (
ImageEngineorVideoEngine) by reading the file's binary header signatures. - Dynamic Aspect Ratio Scaling: Features a precision dimensions calculator and
ResizeObserverto adapt the canvas size to the host container dynamically. - Self-Contained Binary Fonts: Loads fonts packaged directly inside the
.oimbinary 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:
<!-- 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
| Attribute | Type | Default | Description |
|---|---|---|---|
src | string | "" | URL of the target .oim image or .ovm video file. |
lang | string | "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-lottie | boolean | true | Permits or restricts loading of Vector Lottie JSON animations. |
disable-animations | boolean | from mode | Disables 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-actions | boolean | from mode | Suspends 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-lang | number | "false" | "false" | Interval in ms to automatically cycle through available languages. |
placeholder | string | none | Thumbnail 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(). |
palette | string | file default | Name of one of the file's palettes. Unknown names are ignored. |
show-slots | boolean | true | false 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:
<!-- 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:
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 secondsStyling Customizations (CSS Variables)
Customize the visual buttons, fonts, and backgrounds by adjusting the CSS variables in the component context:
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:
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.
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.
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
ResizeObserverto 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:
/* 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:
function syntaxHighlightJson(json) {
if (!json) return '';
let str = typeof json !== 'string' ? JSON.stringify(json, null, 2) : json;
str = str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
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):
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):
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');