During the course of an interactive video, UI elements often appear or disappear to fit the context of the experience. For UI elements created with Eko studio, such as Decision Buttons and Timers this happens automatically based on the current state of the Decision using the DecisionController.
When we mention a UI element disappears, we mean that it is removed from the React rendering tree, subsequently causing it to be removed from the DOM. This improves performance by ensuring that only visible elements take computational resources for rendering.
There are several approaches to show and hide custom UI.
UI visibility with EkoGroupController
The EkoGroupController allows you to define the visibility of components based on node time, variables state or the combination of both. The same EkoGroupController can be used to drive visibility of any number of components by setting the desired components’ stateSourceId
to that of the EkoGroupController
stateSourceId
is a property that tells a UI component where to “look” in the reduxState to determine how to present itself. For example, an EkoButton with astateSourceId
ofmyController
will look at the decision controller state underglobalState.ui.myController
to determine if the button should be visible, selected, disabled etc
based on nodes/time
In the following example, “myComponent” will be visible only on nodes 1 and 3, For node_1
starting at the 5 second mark and ending at the 20 second mark and for node_3
displaying for its full duration. The enableTransition
prop is required to, well, enable the transition and visibility logic. By omitting this prop or setting it to false, the component will not be subjected to any visibility logic, and will be displayed at all times.
For more configuration options see EkoGroupController.
In app.js
// Define the controller
player.ui.addController('myController', "GROUP", {
showInNodes: {
node_1: {
showTime: 5,
hideTime: 20
},
node_3: true
}
});
// Add a new component whose visibility will be
// controlled by the controller defined above
player.ui.add('myComponent1', MyComponentClass, {
stateSourceId: 'myController',
enableTransition: true
});
UI visibility based on state
In the following example, “myComponent” will be visible when the variable pastry
‘s value is equal to “donut”, as defined with the variables plugin. More advanced configuration is also possible.
See EkoGroupController.
In app.js
// Define the controller
player.ui.addController({
id: 'myController',
type: 'GROUP',
showIfVariables: {
pastry: 'donut'
}
});
// Add a new component whose visibility will be
// controlled by the controller defined above
player.ui.add('myComponent1', MyComponentClass, {
stateSourceId: 'myController',
enableTransition: true
});
UI visibility of multiple components
If you wish to change visibility of several component at the same time, add your components as child components of an EkoGroup and set its stateSourceId
to a GroupController.
In the following example, there are two UI elements, myComponent1
and myComponent2
, contained within the EkoGroup topPanel
. By attaching the topPanel
to myController
, the element and its children will be visible only on nodes 1 and 3, For node_1
starting at the 5 second mark and ending at the 20 second mark and for node_3
displaying for its full duration.
Note that in this case it’s not necessary to include enableTransition: true
. It is enabled by default for EkoGroup.
In app.js
import EkoUIComponents from 'EkoUIComponents';
// Define the controller
player.ui.addController({
id: 'myController',
type: 'GROUP',
showInNodes: {
node_1: {
showTime: 5,
hideTime: 20
},
node_3: true
}
});
// Add group and children
player.ui.add('topPanel', EkoUIComponents.EkoGroup, {
stateSourceId: 'myController',
children: [
{
id: 'myComponent1',
component: myComponent1,
props: {}
},
{
id: 'myComponent2',
component: myComponent2,
props: {}
}
]
});
UI visibility in custom components
You can also opt to implement any custom display logic in your own components by leveraging React conditional rendering and the reduxState.
For example, the following component will only appear once the player is paused:
In pauseMessage.jsx
import React from 'react';
export default function pauseMessage(props){
let isPaused = props.player.ui.useSelector(globalState => globalState.player.isPaused);
if (isPaused) {
return <div>Paused!</div>;
} else {
return null;
}
}