A custom element for wrapping the hydra-synth engine.
Hydra is a video synth and coding environment that runs in the browser. It stands out for its elegant DSL, modeled on a fluent interface.
This project aims to simplify the render of Hydra scripts in HTML documents embedding hydra-synth (Hydra's video synthesizer and shader compiler) in a custom element.
By default each hydra-element
contains its own hydra-synth
(with its own sources, functions and outputs). In this way, several elements can be used in the same HTML document without collisions.
This package is published in the npm registry as hydra-element
. You can load it via CDN (the easiest way) or install it with a package manager.
Load the custom element via CDN adding the following script to your HTML file.
<script type="module" src="https://cdn.jsdelivr.net/npm/hydra-element"></script>
Install the package from npm with the following command.
npm install hydra-element
Once youβve done that, import the custom element in your JavaScript module.
import "hydra-element"
Include your code between the element tags.
<hydra-element>
s0.initImage("https://upload.wikimedia.org/wikipedia/commons/2/25/Hydra-Foto.jpg")
osc(30,0.01,1)
.mult(osc(() => (100 * Math.sin(time * 0.1)),-0.1,1).modulate(noise(3,1)).rotate(0.7))
.blend(src(s0))
.posterize([3,10,2].fast(0.5).smooth(1))
.modulateRotate(o0, () => mouse.x * 0.003)
.out()
</hydra-element>
If you need to update the code, use the code
property with JavaScript.
document.querySelector('hydra-element').code = 'osc().out()'
Finally, use CSS to style the element.
hydra-element {
width: 15rem;
height: 15rem;
color: white;
}
You can see and remix a live example here.
By default the embedded hydra-synth
engine is created with these settings:
canvas: null,
width: window.innerWidth,
height: window.innerHeight,
autoLoop: true,
makeGlobal: false,
detectAudio: false,
numSources: 4,
numOutputs: 4,
extendTransforms: [],
precision: null,
pb: null
You can use the following attributes and properties to configure these options. Read the hydra-synth
API documentation for more information.
In addition to the engine, the custom element also takes care of the canvas. By default it creates one the size of the window, which is useful for many cases. If this is not yours, you can use the width
and height
attributes to modify the canvas size.
<hydra-element width="250" height="250"></hydra-element>
If you prefer to take care of the canvas yourself, use the canvas
property to specify a canvas element to render on. In this case the component does not create any canvas but uses the assigned one.
document.querySelector('hydra-element').canvas = yourCanvasElement
If you want to use your own render loop for triggering Hydra updates, set the loop
attribute to false
.
<hydra-element loop="false"></hydra-element>
Note you will need to call the tick
method, where dt
is the time elapsed in milliseconds since the last update.
document.querySelector('hydra-element').tick(dt)
If you set the global
attribute to true
all sources, functions and outputs of the synthesizer will be stored in the window
object, so they will be directly available. You should use this option if you need to extend the functionality of the synthesizer by loading extensions or external libraries with loadScript
.
<hydra-element global="true">
await loadScript("https://cdn.statically.io/gl/metagrowing/extra-shaders-for-hydra/main/lib/lib-noise.js")
warp().out()
</hydra-element>
Warning You must not use more than one
hydra-element
withglobal
set totrue
in the same HTML document.
Hydra's audio capabilities are disabled by default because they require requesting microphone permissions and not all scripts use them, so don't forget to set the audio
attribute to true
if you use the a
object in your script.
<hydra-element audio="true">
a.show()
osc(10, 0, () => a.fft[0]*4).out()
</hydra-element>
You can use the sources
attribute to set the number of source buffers available for multimedia resources. The default value is 4
. Extra buffers are available via the synth
object.
<hydra-element sources="8">
const { s6, s7 } = synth
s0.initCam()
s1.initScreen()
s6.initImage('https://upload.wikimedia.org/wikipedia/commons/2/25/Hydra-Foto.jpg')
s7.initVideo('https://media.giphy.com/media/AS9LIFttYzkc0/giphy.mp4')
src(s0)
.blend(src(s1))
.blend(src(s6))
.blend(src(s7))
.out()
</hydra-element>
You can use the outputs
attribute to set the number of output buffers to use. The default value is 4
. Extra buffers are available via the synth
object.
<hydra-element outputs="8">
const { o7 } = synth
osc().out(o7)
render(o7)
</hydra-element>
Warning Note that
hydra-synth
itself has only been tested with4
outputs, so use this attribute with caution.
You can use the precision
attribute to force precision of shaders. By default no precision is specified, so the engine will use highp
for iOS and mediump
for everything else. Avaiblable options are highp
, mediump
and lowp
.
<hydra-element precision="highp"></hydra-element>
You can add custom GLSL functions setting the transforms
property with JavaScript.
document.querySelector('hydra-element').transforms = [{
name: 'yourNoise',
type: 'src',
inputs: [
{ type: 'float', name: 'scale', default: 5 },
{ type: 'float', name: 'offset', default: 0.5 }
],
glsl: `return vec4(vec3(_noise(vec3(_st*scale, offset*time))), 0.5);`
}]
Once done, you can use the new functions in your script. Generator functions (those of type src
) will be available via the synth
object.
<hydra-element>
const { yourNoise } = synth
yourNoise().out()
</hydra-element>
If you have access to an instance of rtc-patch-bay
for streaming, you can assign it to the pb
property with JavaScript.
document.querySelector('hydra-element').pb = yourRtcPatchBayInstance
- The
loadScript
function is only available whenglobal
istrue
. - It is not possible to work with p5.js as in the Hydra web editor.
This project uses Vite for development and Web Test Runner for testing. The following npm
scripts are available:
dev
: servesindex.html
for development (reloading on file changes)test
: runs the test suites in a headless chromebuild
: bundles the custom element for distribution (in thedist
directory)
- Naoto Hieda for improving the usability of the custom element πͺ
- Olivia Jack for creating such a fun tool as Hydra π
- The Hydra community for turning the tool into something even more fun π§©
Distributed under the GNU Affero General Public License.