Skip to content

Commit 8b3871a

Browse files
committed
Add documentation for custom actions and event signal
1 parent 1f296c1 commit 8b3871a

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

contributor_docs/creating_libraries.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,31 @@ if (typeof p5 !== undefined) {
282282

283283
In the above snippet, an additional `if` condition is added around the call to `p5.registerAddon()`. This is done to support both direct usage in ESM modules (where users can directly import your addon function then call `p5.registerAddon()` themselves) and after bundling support regular `<script>` tag usage without your users needing to call `p5.registerAddon()` directly as long as they have included the addon `<script>` tag after the `<script>` tag including p5.js itself.
284284

285+
## Accessing custom actions
286+
In certain circumstances, such as when you have a library that listens to a certain browser event, you may wish to run a function that your user defined on the global scope, much like how a `click` event triggers a user defined `mouseClicked()` function. We call these functions "custom actions" and your addon can access any of them through `this._customActions` object.
287+
288+
The following addon snippet listens to the `click` event on a custom button element.
289+
```js
290+
function myAddon(p5, fn, lifecycles){
291+
lifecycles.presetup = function(){
292+
let customButton = this.createButton('click me');
293+
customButton.elt.addEventListener('click', this._customActions.myAddonButtonClicked);
294+
};
295+
}
296+
```
297+
298+
In a sketch that uses the above addon, a user can define the following:
299+
```js
300+
function setup(){
301+
createCanvas(400, 400);
302+
}
303+
304+
function myAddonButtonClicked(){
305+
// This function will be run each time the button created by the addon is clicked
306+
}
307+
```
308+
309+
This approach supports accessing the custom action functions in both global mode and instance mode with the same code, simplifying your code from what it otherwise may need to be.
285310

286311
## Next steps
287312

@@ -315,6 +340,19 @@ fn.myMethod = function(){
315340

316341
**p5.js library filenames are also prefixed with p5, but the next word is lowercase** to distinguish them from classes. For example, p5.sound.js. You are encouraged to follow this format for naming your file.
317342

343+
**In some cases, you will need to make sure your addon cleans up after itself after a p5.js sketch is removed** by the user calling `remove()`. This means adding relevant clean up code in the `lifecycles.remove` hook. In most circumstances, you don't need to do this with the main exception being cleaning up event handlers: if you are using event handlers (ie. calling `addEventListeners`), you will need to make sure those event handlers are also removed when a sketch is removed. p5.js provides a handy method to automatically remove any registered event handlers with and internal property `this._removeSignal`. When registering an event handler, include `this._removeSignal` as follow:
344+
```js
345+
function myAddon(p5, fn, lifecycles){
346+
lifecycles.presetup = function(){
347+
// ... Define `target` ...
348+
target.addEventListener('click', function() { }, {
349+
signal: this._removeSignal
350+
});
351+
};
352+
}
353+
```
354+
With this you will not need to manually define a clean up actions for event handlers in `lifecycles.remove` and all event handlers associated with the `this._removeSignal` property as above will be automtically cleaned up on sketch removal.
355+
318356
**Packaging**
319357

320358
**Create a single JS file that contains your library.** This makes it easy for users to add it to their projects. We suggest using a [bundler](https://rollupjs.org/) for your library. You may want to provide options for both the normal JavaScript file for sketching/debugging and a [minified](https://terser.org/) version for faster loading.

0 commit comments

Comments
 (0)