JavaScript API and Events
The viewer is a UMD module exposed as TNCFlipbook. Inside the iframe, addons can also reach the live instance via window.__tncfb.instance.
Constructing a viewer
import { TNCFlipbook } from '/wp-content/plugins/tnc-flipbook-3d/assets/flipbook/tnc-flipbook.js';
const fb = new TNCFlipbook('#container', config, options);
await fb.ready();
For embedded flipbooks, the WP plugin handles construction automatically — you don't normally instantiate TNCFlipbook yourself.
Event API
fb.on('page-changed', e => console.log(e.detail.page));
fb.once('ready', handler);
fb.off('page-changed', handler);
fb.emit('custom-event', { foo: 1 });
Methods
Category
Methods
Navigation
goToPage(n), nextPage(), prevPage(), firstPage(), lastPage()
State
getCurrentPage(), getTotalPages(), getZoomLevel(), getViewMode(), isFullscreen(), getConfig()
View
setZoom(level), toggleFullscreen(), setTheme('light'|'dark')
Gating
grantAccess(), revokeAccess(), hasAccess(), getGatingConfig(), setGating({...})
Plugins
fb.use({ name, init(fb), destroy() })
CustomEvents
Every notable event is dispatched on the viewer container with the tncfb: prefix:
Event
Detail
ready
—
page-changed
{ page, total }
zoom-changed
{ level }
view-mode-changed
{ mode }
theme-changed
{ theme }
fullscreen-entered / fullscreen-exited
—
reading-mode-entered / reading-mode-exited
—
search-started / search-result-found / search-complete
results metadata
tts-started / tts-paused / tts-resumed / tts-stopped
playback metadata
download-started / download-complete
—
print-started
—
annotation-added / annotation-removed
annotation payload
hotspot-clicked
hotspot config
access:granted / access:revoked
—
gating:changed
new gating config
error
{ message, code }
Listen on the container element:
const el = document.querySelector('#flipbook');
el.addEventListener('tncfb:page-changed', e => {
console.log('Page', e.detail.page);
});
postMessage bridge
When the viewer is in an iframe (the default), every event is forwarded to the parent window. From the host page:
window.addEventListener('message', e => {
if (e.data?.type !== 'tncfb-event') return;
// { type, id, event, detail }
if (e.data.event === 'page-changed') {
console.log('Page', e.data.detail.page);
}
});
The id field matches the flipbook's post ID, so multiple flipbooks on one host page are distinguishable.
Plugin pattern
fb.use({
name: 'my-plugin',
init(viewer) {
viewer.on('page-changed', e => { /* ... */ });
},
destroy() { /* cleanup */ }
});
fb.use() is the recommended seam for addon developers — it gives you a stable lifecycle (init / destroy) and doesn't depend on internal viewer state.
CSS hooks
Theme classes set on the viewer root: .chrome-slate, .chrome-paper, .chrome-midnight, .chrome-ocean, .chrome-forest, .chrome-glass, .chrome-sepia, .light-theme, .dark-theme, .tncfb-fullscreen.
CSS custom properties (set dynamically by applyColorScheme):
--tncfb-brand
--tncfb-brand-dark
--tncfb-brand-light
--tncfb-surface-primary
--tncfb-surface-secondary
--tncfb-text-primary
--tncfb-text-secondary
--tncfb-hover, --tncfb-active, --tncfb-disabled
--tncfb-border, --tncfb-shadow
Major selectors: .tncfb-container, .tncfb-viewer, .tncfb-toolbar, .tncfb-toolbar-*, .tncfb-sidebar, .tncfb-gating-overlay, .tncfb-watermark, .tncfb-a11y-*.
Style customizations should target these custom properties rather than hardcoding values — they're respected by every chrome and theme.