Docs

Component inputs

inputDefs are static inspector values. Asset inputs store IDs on the clip and resolve to playback URLs or VidovaClipData before they reach the class.

View as Markdown

inputDefs are static values on the clip. The inspector sets them. They do not tween. Animation still lives in generators and class signals. See Animation.

Types

typeClip valueClass signal
stringstringSimpleSignal<string, this>
numbernumberSimpleSignal<number, this>
booleanbooleanSimpleSignal<boolean, this>
colorhex stringColorSignal<this> with @colorSignal
enumone of optionsSimpleSignal<string, this>
fontfamily stringSimpleSignal<string, this>
assetasset ID on the clipplayback URL string, or VidovaClipData

Each def needs name, type, and default. label is optional. enum needs options. asset needs assetTypes.

Asset contract

The clip stores an asset UUID in inputs and in inputDefs.default. At preview and render, Vidova replaces that ID before the class constructor runs.

assetTypesRuntime prop
['image']playback URL string
['video']playback URL string
['audio']playback URL string
['model3d']playback URL string
['vidova']VidovaClipData object

Do not mix kinds on one input. An image slot is assetTypes: ['image'] only.

The class signal for a URL asset must use @initial(''). Never put the UUID in @initial. inputDefs.default may be an asset ID. @initial must not.

@initial('')
@signal()
public declare readonly image: SimpleSignal<string, this>;

Pass that signal to the media node with explicit size:

<Img
  src={() => this.image()}
  width={() => this.frameWidth()}
  height={() => this.frameHeight()}
/>

Empty string is a no-op. A UUID is not a URL. <Img> will refuse it.

For screen recordings:

import { ScreenRecording, FaceCamera, type VidovaClipData } from '@vidova/components';
 
@initial(undefined)
@signal()
public declare readonly screen: SimpleSignal<VidovaClipData | undefined, this>;

Use fields on this.screen() (screenSrc, cameraSrc, cursor arrays). Do not pass the whole object to <Video src>.

Timeline

After component create or edit, place one clip:

timeline_edit addClip
  type: component
  assetId: <component asset id>
  componentInputs: { image: "<image asset id>" }

Do not add a parallel type: image or type: video clip for the same file. The component input is the media. A leftover still on the timeline means the shader never ran.

componentInputs overrides inputDefs.default. Both store asset IDs, not URLs.

Example

[
  {
    "name": "image",
    "type": "asset",
    "default": "",
    "label": "Image",
    "assetTypes": ["image"]
  },
  {
    "name": "refraction",
    "type": "number",
    "default": 0.04,
    "label": "Refraction"
  }
]

refraction is a static knob. If it should move over time, keep a class signal and tween it in animate() instead of expecting the input to change.

Shaders that sample this image: Shaders.