Plugins
Plugins are at the heart of Veloxi’s functionality. You can think of a plugin as a small application integrated into your main Veloxi application (created with createApp()
).
Without creating and using plugins, Veloxi can’t do anything. Therefore, it’s important to understand how they work and how to use them—they are quite simple.
Creating a Plugin
There are two API styles for creating a plugin: Functions and Classes. There is no difference between them; it’s merely a matter of coding preference—some developers favor classes, while others prefer functions.
To create a plugin using classes, you simply need to extend the main Plugin
class from Veloxi.
To create a plugin using functions, you just need to define a function that accepts a context
object.
In both cases, it’s important to note that each plugin must specify its name, as shown above.
Going forward, you can select your preferred coding style by using the toggle provided above each code snippet.
Using a Plugin
To use a plugin, you need to add it to your Veloxi app instance using app.addPlugin()
.
Run The App
Creating an app instance by itself won’t activate the app. To start it, you need to explicitly invoke the run() method on your app instance.
When you run the app, Veloxi adds listeners to native events, such as pointer and keyboard events, and initiates the app loop. Within this loop, Veloxi reads, updates, and renders each view during each frame.
Plugin setup()
Each plugin has a single opportunity to perform all the necessary preparations for its state and views. You can consider this as the plugin’s entry point, which is defined within the setup()
function.
Accessing Views
To access a view within a plugin, you must first assign it to that plugin. Then, you can utilize getViews(viewName)
to retrieve multiple views or getView(viewName)
to retrieve a single one (typically the first one if you have defined multiple).
To assign a view to a plugin, use data-vel-plugin="MyPlugin"
on the desired element.
In this case we have created two views named circle
and assigned them to a plugin named MyPlugin
.
Here’s how you can access them:
Scoped Plugins
The previous example works well when you intend to create an interaction involving multiple views, perhaps where they interact with each other.
However, what if you want the plugin to exclusively operate with one view at a time? In other words, you need a mechanism to generate a new plugin instance for each view.
This can be accomplished using scoped plugins.
Scoped plugins are designed to operate within the context of a particular view. To employ them, simply assign the scope
property with the name of the desired view.
Subscribe to Global Events
When the user clicks the mouse or touches the screen, Veloxi generates a global event related to that action. All added plugins can listen to this event and respond accordingly.
To subscribe to a global event, you can utilize the global eventBus
provided to the subscribeToEvents()
function.
Currently, Veloxi supports only these events:
- PointerClickEvent
- PointerMoveEvent
- PointerDownEvent
- PointerUpEvent
The event
object in all pointer events includes these three values:
- x: The x position of the pointer.
- y: The y position of the pointer.
- target: the EventTarget of the pointer.
Emit Events
The primary method for your plugin to communicate with the outside world is through events. Your plugin emits events, and your Veloxi app object listens to them.
To emit an event, you need to define the event and then invoke emit(YourEvent, eventData)
within the plugin.
Plugin Config
Sometimes, you’ll need to provide settings to the plugin to modify how it works. For example, when creating a resizing plugin, users might want to specify the maximum width and height for view expansion.
Users can pass these settings through the second argument of app.addPlugin(Plugin, config)
. Your plugin can then access and utilize these settings via the config
field.
Plugin’s Update and Render Hooks
The main app loop consists of four main steps, executed in the following sequence:
- Handling events
- Reading view properties
- Updating views
- Rendering views
In every frame, we have the chance to update and then render our views. This will be useful when we want to have full control over views per frame.
The frame update and render code go into the update
and render
functions, respectively.