Web Component¶
<vexy-stax> puts a deck on a page with markup only. Load the element bundle
once; the element registers itself under the tag name vexy-stax.
<script type="module" src="https://vexy.dev/vexy-stax-js/vexy-stax.element.js"></script>
<!-- a deck from a list of images -->
<vexy-stax slides="layer-0.png layer-1.png layer-2.png"></vexy-stax>
<!-- a deck from a scene file -->
<vexy-stax scene="deck.scene.json" view="compact" aspect="16/9" buttons></vexy-stax>
The global bundle vexy-stax.global.js registers the same element.
How the element mounts¶
When the element is added to the page, it:
- sets
display: blockandposition: relativeunless they are already set, and applieswidth,heightandaspect; - finds the scene, in this order of precedence:
- the
configproperty orconfigattribute (an inline scene), - a child
<script type="application/json">or<script type="application/vexy-scene+json">(an inline scene), - the
sceneattribute (a URL to fetch), - the
slidesattribute (a list of image URLs);
- the
- creates a
VexyStaxinstance inside itself and waits until the textures are loaded; - starts scroll tracking if
mode="scrollspy"; - turns on click-to-toggle unless
click-toggle="false"; - adds control buttons if
buttonsis present; - fires
ready.
If none of the four scene sources is present, the element renders nothing.
Relative slide paths in an inline scene or in slides resolve against the
page URL; in a scene file they resolve against the scene file's URL.
Attributes¶
Scene source¶
| Attribute | Value | Effect |
|---|---|---|
slides |
Image URLs separated by spaces or newlines | Builds a scene with makeScene. The first URL is the backmost plate. |
captions |
true or false |
With slides only: the global captions setting of the built scene |
scene |
URL of a .scene.json file |
Fetches and parses the scene |
config |
Scene as a JSON string | Inline scene; read once when the element connects |
A child <script> holds a full scene without attribute escaping:
<vexy-stax view="compact" aspect="3">
<script type="application/json">
{
"version": 1,
"transition": { "kind": "expand_collapse" },
"slides": [
{ "src": "https://example.com/layer-0.png", "caption": { "text": "First layer" } },
{ "src": "https://example.com/layer-1.png" }
]
}
</script>
</vexy-stax>
Invalid JSON in that child fails the mount with
<vexy-stax>: inline <script> scene is not valid JSON (…).
View and size¶
| Attribute | Value | Default | Effect |
|---|---|---|---|
view |
expanded or compact |
the scene's view, else expanded |
Initial view. Changing it later calls setView. |
width |
CSS length; a bare number means pixels | — | CSS width of the element |
height |
CSS length; a bare number means pixels | — | CSS height of the element |
aspect |
3, 3/1, 3:1, 16x9, … |
— | CSS aspect-ratio; : and x become / |
The camera fits the deck to the element's box whenever its size changes.
Playback mode¶
| Attribute | Value | Default | Effect |
|---|---|---|---|
mode |
static, playable or scrollspy |
static |
See below |
trigger |
CSS selector | the element | The element whose scroll position drives scrollspy |
staticrenders the initial view.playablealso renders the initial view. The element does not start the transition itself; callel.transition()from your script, for example from a button or thereadyevent. (createStaxwithmode: "playable"does play the transition once.)scrollspymaps the scroll position of the trigger to the morph between compact and expanded. Seescrollspy.
Interaction¶
| Attribute | Value | Default | Effect |
|---|---|---|---|
click-toggle |
false to turn off |
on | A click inside the element animates to the other view |
buttons |
toggle, pair, or empty |
no buttons | toggle: one button whose label follows the view. pair: two buttons. An empty buttons attribute means toggle. false means no buttons. |
explain-label |
text | Explain |
Label of the button that expands the deck |
preview-label |
text | Preview |
Label of the button that collapses the deck |
buttons-position |
bottom, top, bottom-left, bottom-right, top-left, top-right, center |
bottom |
Position of the buttons inside the element |
Changing width, height, aspect, view or click-toggle updates the
mounted deck in place. Changing any other observed attribute mounts the deck
again.
Properties¶
| Property | Type | Effect |
|---|---|---|
config |
object, JSON string or null |
Inline scene; setting it mounts the deck again |
scene |
string or object | Setting an object, or a string that starts with {, sets config. Setting another string sets the scene attribute. Reading returns config, else the scene attribute. |
instance |
VexyStax or null |
The underlying instance, null until mounted |
Methods¶
The element forwards these calls to its VexyStax instance. Before the
instance exists they return undefined.
| Method | See |
|---|---|
setView(view) |
setView |
seek(t) |
seek |
transition(kind, opts) |
transition |
toggleView() |
toggleView |
toImage(opts) |
toImage |
toVideo(opts) |
toVideo |
scrollspy(opts) |
scrollspy |
Events¶
All events are CustomEvents dispatched on the element.
| Event | detail |
Fired when |
|---|---|---|
ready |
{ instance } |
The deck is mounted and its first view is rendered |
error |
{ error } |
Mounting failed, for example because the scene is invalid |
transitionstart |
{ kind } |
A transition animation starts |
transitionend |
{ kind } |
A transition animation finishes |
viewchange |
{ view } |
The current view changes between compact and expanded, including when a scroll-driven seek crosses the halfway point |
const el = document.querySelector("vexy-stax");
el.addEventListener("ready", (e) => {
e.detail.instance.transition("expand");
});
Styling the buttons¶
The buttons read these CSS custom properties from the element:
| Property | Default |
|---|---|
--vexy-btn-color |
#000 |
--vexy-btn-bg |
rgba(0,0,0,0.05) |
--vexy-btn-blur |
10px |
--vexy-btn-border |
1px solid rgba(0,0,0,0.08) |
--vexy-btn-radius |
999px |
--vexy-btn-pad |
9px 18px |
--vexy-btn-font |
14px (font size) |
--vexy-btn-weight |
600 |
--vexy-btn-shadow |
0 2px 10px rgba(0,0,0,0.06) |
--vexy-btn-bg-solid |
rgba(255,255,255,0.92) (Safari) |
--vexy-btn-bg-solid-hover |
rgba(255,255,255,0.97) (Safari, hover) |
Safari ignores backdrop-filter over a canvas, so it uses the two -solid
backgrounds instead of the blurred one.
Exports of the element bundle¶
vexy-stax.element.js is also an ES module. Besides registering the
element, it exports VexyStax, createStax, makeScene, loadScene,
parseScene and the element class VexyStaxElement: