3D Premium adds hotspots, an animation controller, postprocessing and AR to the 3D viewer. Its hooks cover hotspot interaction and markup, animations and AR; the postprocessing chain and everything to do with the Three.js scene are documented separately in The 3D runtime API, which is the right starting point for custom materials, shaders, animations and render passes.
See the hook reference index for how to register PHP and JavaScript callbacks.
PHP filters
| Hook | Arguments | Purpose |
|---|---|---|
PC.premium3d.ar.svg.icon | $icon | The SVG markup inside the AR button |
PHP actions
| Hook | Arguments | Purpose |
|---|---|---|
tmpl-mkl-pc-hotspot-attributes | (none) | Print extra attributes on the hotspot <button> |
tmpl-mkl-pc-hotspot-before | (none) | Print markup inside the hotspot, after its icon and before its label |
tmpl-mkl-pc-hotspot | (none) | Print markup at the end of the hotspot |
JavaScript actions
| Hook | Arguments | Purpose |
|---|---|---|
PC.fe.hotspot.click | hotspot, triggerEl | A hotspot was clicked, before any of its actions run |
PC.fe.hotspot.action | action, hotspot, triggerEl | One configured hotspot action is about to run |
PC.fe.hotspot.element | el, hotspot, data | A hotspot element has been created, before it is added to the page |
PC.premium3d.ar.ready | viewer, api, service | The AR button is wired up for a viewer |
PC.3d.postprocessing.registered | (none) | The add-on has registered its postprocessing filters |
JavaScript filters
| Hook | Arguments | Purpose |
|---|---|---|
PC.fe.hotspot.template_data | data, hotspot | The values passed to the hotspot template |
PC.fe.hotspot.template | templateId, hotspot, data | The template used for a hotspot, without its tmpl- prefix |
PC.3d.createPostprocessingLayer | null | Replace the whole effect chain — see the 3D runtime API |
PC.fe.hotspot.click
Fires as soon as a hotspot is clicked, before any of its configured actions run. The second argument is the DOM element the customer actually clicked.
wp.hooks.addAction( 'PC.fe.hotspot.click', 'my-plugin/3d', function ( hotspot, triggerEl ) { myAnalytics.track( 'hotspot', { id: hotspot._id, label: hotspot.hotspot_label } );} );
PC.fe.hotspot.action
Fires once per configured action on the hotspot, just before it is carried out — opening a layer,
switching an angle, and so on. action.action holds the action type.
wp.hooks.addAction( 'PC.fe.hotspot.action', 'my-plugin/3d', function ( action, hotspot ) { if ( 'open_layer' === action.action ) { closeMyOwnPanel(); }} );
This is an action, not a filter — you cannot cancel the built-in behaviour from here, only run alongside it.
Hotspot markup
Each hotspot is rendered from the Underscore template tmpl-mkl-pc-hotspot, printed on the
configurator's front-end templates hook. data holds id, type (pin, label or
annotation), icon, label, content, aria_label, class_name, and hotspot, the raw
3D item.
There are three ways to change the markup, from lightest to heaviest:
PC.fe.hotspot.template_data: change the values. Settingclass_nameadds a class to the button.- The PHP actions: add attributes or inner markup to the existing template.
PC.fe.hotspot.template: return the id of your own template, printed on the page as<script type="text/html" id="tmpl-…">. Its first element becomes the hotspot. Keep it a single root element: the add-on positions it and binds its click handler.
wp.hooks.addFilter( 'PC.fe.hotspot.template_data', 'my-plugin/3d', function ( data, hotspot ) { if ( 'annotation' === data.type ) { data.class_name = 'is-feature'; } return data;} );
PC.fe.hotspot.element receives the finished element once it has been built. Use it to attach
your own listeners.
Animations from code
The animation controllers are run by a service per viewer, reachable through
PC.premium3d.animationTriggers:
| Method | Purpose |
|---|---|
getServices() | A Map of the services, one per 3D viewer on the page |
registerCommand( name, executor ) | Add a command, or replace a built-in one: play, stop, pause, resume, reverse |
registerTriggerType( name, handler ) | Replace the handler behind angle_enter or angle_leave |
A service's runAnimationObject( { animation_object_id, command } ) runs a controller, the same
way a view or hotspot trigger does. This makes it possible to play an animation when a choice is
selected, which the settings don't offer. animation_object_id is the controller's _id, listed
in PC.fe.currentProductData.objects3d.
wp.hooks.addAction( 'PC.fe.choice.change', 'my-plugin/3d', function ( choice ) { if ( 'Doors open' !== choice.get( 'name' ) || ! choice.get( 'active' ) ) { return; } PC.premium3d.animationTriggers.getServices().forEach( function ( service ) { service.runAnimationObject( { animation_object_id: '12', command: 'play' } ); } );} );
An executor receives the service, the Three.js AnimationAction, the clip row from the
controller, and the trigger. Replacing play changes how every Play trigger behaves, for
example to play all clips at half speed:
PC.premium3d.animationTriggers.registerCommand( 'play', function ( service, action, clipCfg ) { action.reset(); action.setLoop( service.THREE.LoopOnce, 1 ); action.clampWhenFinished = true; action.timeScale = 0.5; action.play();} );
Run this after the add-on's script has loaded, for example from a script that depends on the
mkl_pc/js/fe/3d-premium handle. The command list in the admin is fixed. A command with a new
name can only be used from your own code.
PC.premium3d.ar.ready
Fires when the AR button has been bound for a viewer. It only fires where AR can actually open: the product has AR enabled, and the device supports Quick Look or WebXR. On a desktop, or a phone without AR, it never fires, so it is the place to reveal anything of your own that promotes AR. The third argument is the AR service:
| Member | Returns |
|---|---|
service.activate() | Start the AR session |
service.can_activate() | Whether AR can start now. It is false while a session is already opening |
service.mode | 'quick-look' on iOS, 'webxr' on Android |
wp.hooks.addAction( 'PC.premium3d.ar.ready', 'my-plugin/3d', function ( viewer, api, service ) { var promo = document.querySelector( '.my-ar-promo' ); promo.hidden = false; promo.addEventListener( 'click', function () { service.activate(); } );} );
The same members are also exposed on the registry as activate(), getService(), canActivate()
and getMode().
PC.premium3d.ar.svg.icon
The icon markup inside the "View in your space" button. The button's label comes from the add-on's own settings, so this filter is only about the icon.
add_filter( 'PC.premium3d.ar.svg.icon', function ( $icon ) { return '<img src="' . esc_url( plugin_dir_url( __FILE__ ) . 'ar.svg' ) . '" alt="" />';} );
Output is intentionally not escaped so SVG markup survives — return trusted markup only.
PC.3d.postprocessing.registered
Fires after the add-on has registered PC.3d.createPostprocessingLayer and
PC.3d.postprocessingEnabled. Use it if your own code needs to know an effect chain is available
before it decides what to do.
Postprocessing and the 3D scene
PC.3d.createPostprocessingLayer replaces the entire effect chain and is a single slot — the
first registration wins. To add a pass rather than replace everything, use
PC.3d.postprocessingPasses instead, which works with or without this add-on installed. Both are
documented in The 3D runtime API.