Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
blocks:api:javascript [2022-11-18 16:09] admin created |
blocks:api:javascript [2023-08-09 13:08] (current) melvin Fix typos |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== | + | ====== |
- | You use a Web Block to show a web page by specifying its URL. If you have control over the code runnin in that web page, you can do some limited interaction from the web page hosted inside the //IFRAME// of the Web Block up into Blocks | + | Occasionally, |
- | :!: **HINT** If you have made the complete web page specifically for use from within a Web Block, you may host that web page on the Blocks | + | The APIs described here provide access to all the same Blocks properties that you can use with buttons, sliders, text fields and other controls inside |
- | All interactions with Blocks from within your custom web page are done using the browser' | + | There are two separate, but similar, such Javascript APIs available: |
- | ==== action | + | * One for use from within custom web pages designed to be hosted in a Web Block. |
+ | * Another one that can be used regardless of whether the web pages is used inside a Web Block or as a separate, independent web page. | ||
+ | |||
+ | ===== Hosting your Custom Web Page ===== | ||
+ | |||
+ | If desired, you can host your custom web page on your Blocks server unless your web page has specific server side needs not provided by Blocks (such as PHP server-side scripting). | ||
+ | |||
+ | === Hosting Custom Web Content Inside a Block === | ||
+ | |||
+ | If your web page is designed to be used through a Web Block, then you can place it inside the directory of the root block containing the Web Block. You can find this directory here: | ||
+ | |||
+ | < | ||
+ | public/ | ||
+ | </ | ||
+ | |||
+ | where GROUP_NAME and BLOCK_NAME is the name of the block group and block name in question. Create a directory inside that BLOCK_NAME called, for example, // | ||
+ | |||
+ | < | ||
+ | ~/ | ||
+ | </ | ||
+ | |||
+ | Where the tilde character (~) represents "the current block", | ||
+ | |||
+ | === Hosting Custom Web Content under /public === | ||
+ | |||
+ | If your custom web content isn't specific to a particular block, or is designed to be used independently as a stand-alone web page, you can still host it on your Blocks server like this: | ||
+ | |||
+ | - Create a separate directory somewhere under the //public// directory found inside your Blocks root directory. | ||
+ | - Put your web page and any associated CSS and JS files inside that directory, making sure the main HTML file is called // | ||
+ | - Open a browser with a URL like this: | ||
+ | |||
+ | < | ||
+ | http:// | ||
+ | </ | ||
+ | |||
+ | where NAME_OR_IP is the domain name or IP address of your Blocks server (possibly followed by a port number if using a non-standard port, separated by a colon) and YOUR_CUSTOM_WEB_DIRECTORY is the name of the directory you created under the //public// directory, as described in point 1 above. | ||
+ | |||
+ | ===== Publish/ | ||
+ | The main purpose of the Javascript APIs is to provide property access. Properties are used throughout Blocks to control most functions, so by setting such properties from your custom script, you can affect the state of all Blocks objects, such as Spots, Network Devices, Artnet/DMX devices, etc. The core functions providing such property access are common across both APIs, once you have access to the object providing this service. The method of accessing this object is different for the two APIs, and is described below. The common functions provided are: | ||
+ | |||
+ | * **subscribe** to learn about when the value of a property changes. | ||
+ | * **unsubscribe** to stop listening to value changes. | ||
+ | * **set** for setting the value of a property. Will have no effect if the property is read-only or if access to the property is restricted to certain roles in Blocks. | ||
+ | * **add** adjusts the value of a numeric property incrementally or appends to a string property. | ||
+ | |||
+ | === subscribe === | ||
+ | Subscribe to value of property at path, calling dataCallback.dataReceived when value changes. | ||
+ | Returns the current value of propety, if known, else undefined. If synchronousCallback and | ||
+ | the current value is known, then call dataCallback right away (before the function returns). Function and type declarations below use TypeScript syntax. | ||
+ | |||
+ | < | ||
+ | subscribe( | ||
+ | path: string, // Property path | ||
+ | dataCallback: | ||
+ | synchronousCallback: | ||
+ | ): any; | ||
+ | </ | ||
+ | |||
+ | where DataCallback is an object that has a dataReceived function, thus implementing the following interface. | ||
+ | |||
+ | < | ||
+ | interface DataCallback { | ||
+ | dataReceived(newValue: | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | In some cases, the value of the property subscribed to may be available right away. If so, you will get access to that value by either of the following means: | ||
+ | |||
+ | - By the return value from the // | ||
+ | - By passing //true// as the // | ||
+ | |||
+ | === unsubscribe === | ||
+ | Stops dataCallback from receiving callbacks for changes to property at path. | ||
+ | |||
+ | < | ||
+ | unsubscribe( | ||
+ | path: string, // Property path - string | ||
+ | dataCallback: | ||
+ | ): void; | ||
+ | </ | ||
+ | |||
+ | :!: **NOTE**: The dataCallback object passed to // | ||
+ | |||
+ | === set === | ||
+ | Set the value of property. The type of the value passed to this function must match the type of the property being set. | ||
+ | |||
+ | < | ||
+ | set( | ||
+ | path: string, // Property path | ||
+ | value: any // value to set (number, string, boolean matching the property' | ||
+ | ): void; | ||
+ | </ | ||
+ | |||
+ | === add === | ||
+ | Add (number) or append (string) value to property. | ||
+ | |||
+ | < | ||
+ | add( | ||
+ | path: string, // Property path | ||
+ | value: any // value to add (number) or append (string) | ||
+ | ): void; | ||
+ | </ | ||
+ | |||
+ | For a numeric property, specify the value by which to increase. To decrease, pass a negative value. For a string property, the value will be appended to the property. Not applicable for boolean properties. | ||
+ | |||
+ | |||
+ | ===== Javascript API Usable from within a Web Block ===== | ||
+ | |||
+ | Find the API integration script and an example HTML file here: | ||
+ | |||
+ | https:// | ||
+ | |||
+ | To obtain the object on which you can call the functions described above, first import the PubSubWebBlock class, then instantiate an instance of this class like this | ||
+ | |||
+ | < | ||
+ | // Create our single host API connection | ||
+ | const pubSub = new PubSubWebBlock(); | ||
+ | </ | ||
+ | |||
+ | Then call the functions on the pubSub instance, as shown in the example index.html file included. | ||
+ | |||
+ | If you need access to this instance from other Javascript files/ | ||
+ | |||
+ | < | ||
+ | // Make available as a global to use from elsewhere | ||
+ | window.PIXILAB_BLOCKS.pubSub = pubSub; | ||
+ | </ | ||
+ | |||
+ | ==== Additional Web Block Interaction Capabilities ==== | ||
+ | |||
+ | Custom code hosted inside a Web Block has some additional capabilities for talking to the enclosing Spot. Those are made available through the the browser' | ||
+ | |||
+ | === action | ||
Keeps any enclosing Attractor Block in its active state. This is useful since Blocks can not automatically detect user interaction, | Keeps any enclosing Attractor Block in its active state. This is useful since Blocks can not automatically detect user interaction, | ||
Line 13: | Line 145: | ||
</ | </ | ||
- | ==== set-location | + | === set-location === |
Tells any enclosing Locator block to locate the Spot path or Location ID specified. The example shown below passes the number 12, which will be interpreted as a Location ID (since it's numeric). | Tells any enclosing Locator block to locate the Spot path or Location ID specified. The example shown below passes the number 12, which will be interpreted as a Location ID (since it's numeric). | ||
Line 22: | Line 154: | ||
Alternatively, | Alternatively, | ||
- | ==== goto-block | + | === goto-block === |
Navigate to specified block path inside the current root block. | Navigate to specified block path inside the current root block. | ||
Line 29: | Line 161: | ||
</ | </ | ||
- | ==== go-back | + | === go-back === |
Navigate back, just like the browser' | Navigate back, just like the browser' | ||
Line 36: | Line 168: | ||
</ | </ | ||
- | ==== set-tags | + | === set-tags === |
Set tags on the Spot, for use with Tag Selector. | Set tags on the Spot, for use with Tag Selector. | ||
Line 43: | Line 175: | ||
</ | </ | ||
+ | ===== Stand-alone Javascript API ===== | ||
+ | |||
+ | This flavor of the API can be used independently of any surrounding Web Block; e.g., from a web page rendered outside of Blocks. Such a web page can still be served from the Blocks server, but is rendered as its own, top level web page. Since this is not running within the context of a Blocks Spot, it can not access any of the services provided by a Spot, as described above. In this case, your web page will use its own websocket connection to Blocks, as provided by this API. | ||
+ | |||
+ | :!: For a fully working example of this API, see [[blocks: | ||
+ | |||
+ | To use this method, first include the pub-sub-peer.js script into your web page: | ||
+ | |||
+ | < | ||
+ | <script src=" | ||
+ | </ | ||
+ | |||
+ | This load the API and establishes the global PIXILAB_BLOCKS object, which can subsequently be used to open a connection to Blocks, like this: | ||
+ | |||
+ | < | ||
+ | /** | ||
+ | * Instantiate a PubSubPeer that auto-connects to the blocks server | ||
+ | * using a websocket. | ||
+ | * | ||
+ | * The PIXILAB Websocket API is defined in the pub-sub-peer.js script, which | ||
+ | * attaches its root object as a global (window) variable named PIXILAB_BLOCKS. | ||
+ | */ | ||
+ | const pubSubPeer = new PIXILAB_BLOCKS.PubSubPeer( | ||
+ | onServerConnectionChange | ||
+ | ); | ||
+ | </ | ||
+ | |||
+ | This call returns a pubSubPeer that manages the websocket connection to the server. | ||
+ | |||
+ | The example shown above assumes that the custom web page is served by the Blocks server. If it is served from some other server, you must add a second parameter specifying the URL for the websocket endpoint on your Blocks server, like this; | ||
+ | |||
+ | < | ||
+ | const pubSubPeer = new PIXILAB_BLOCKS.PubSubPeer( | ||
+ | onServerConnectionChange, | ||
+ | " | ||
+ | ); | ||
+ | </ | ||
+ | |||
+ | Replace < | ||
+ | |||
+ | < | ||
+ | const pubSubPeer = new PIXILAB_BLOCKS.PubSubPeer( | ||
+ | onServerConnectionChange, | ||
+ | " | ||
+ | ); | ||
+ | </ | ||
+ | |||
+ | The first parameter of the PubSubPeer constructor call is an optional callback function, in the example above called // | ||
+ | |||
+ | < | ||
+ | /** | ||
+ | * The server connection state has changed. Here we just log that event, but you | ||
+ | * may want to use it to indicate the server is temporarily offline, or similar. | ||
+ | */ | ||
+ | function onServerConnectionChange(connected) { | ||
+ | console.log(connected ? ' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | The argument passed to this function is //true// when the connection is established and //false// if the connection is lost. The example above merely logs a message when this happens. | ||
+ | Once you have access to the pubSubPeer object and the connection has been established, | ||
+ | :!: **IMPORTANT** If you need to access the connection from multiple scripts/ | ||