Guide

3D Premium hooks

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

HookArgumentsPurpose
PC.premium3d.ar.svg.icon$iconThe SVG markup inside the AR button

PHP actions

HookArgumentsPurpose
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

HookArgumentsPurpose
PC.fe.hotspot.clickhotspot, triggerElA hotspot was clicked, before any of its actions run
PC.fe.hotspot.actionaction, hotspot, triggerElOne configured hotspot action is about to run
PC.fe.hotspot.elementel, hotspot, dataA hotspot element has been created, before it is added to the page
PC.premium3d.ar.readyviewer, api, serviceThe AR button is wired up for a viewer
PC.3d.postprocessing.registered(none)The add-on has registered its postprocessing filters

JavaScript filters

HookArgumentsPurpose
PC.fe.hotspot.template_datadata, hotspotThe values passed to the hotspot template
PC.fe.hotspot.templatetemplateId, hotspot, dataThe template used for a hotspot, without its tmpl- prefix
PC.3d.createPostprocessingLayernullReplace 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.

javascript custom.js
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.click.

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.

javascript custom.js
wp.hooks.addAction( 'PC.fe.hotspot.action', 'my-plugin/3d', function ( action, hotspot ) {	if ( 'open_layer' === action.action ) {		closeMyOwnPanel();	}} );
PC.fe.hotspot.action.

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. Setting class_name adds 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.
javascript custom.js
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.template_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:

MethodPurpose
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.

javascript custom.js
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' } );	} );} );
Play an animation when a choice is selected.

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:

javascript custom.js
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();} );
Replace the play command.

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:

MemberReturns
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
javascript custom.js
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();	} );} );
PC.premium3d.ar.ready.

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.

php functions.php
add_filter( 'PC.premium3d.ar.svg.icon', function ( $icon ) {	return '<img src="' . esc_url( plugin_dir_url( __FILE__ ) . 'ar.svg' ) . '" alt="" />';} );
PC.premium3d.ar.svg.icon.

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.