Hydra⚡Intro
by
and
🐰https://hydra.ojack.xyz
solid(1,1,1)
.out()
This is a quick introduction to the basic Hydra APIs.
It was built by David Vandenbogaerde, aka d17e, for the Creative Coding Amsterdam Meetup on November 17th, 2024.
This is one long HTML page, so we built in an auto-scroller for you. You can press the space-bar to play/pause the scroller. Or click on the hidden button in the top-right of the screen to change its speed.
The original inspiration for this 'talk/site' was the live-coding 101 Workshop by Timo Hoogland and Saskia Freeke in June 2024.
In case you're interested in finding out more on live coding in general, you can find a list of resources at https://github.com/tmhglnd/live-coding-101
What is Hydra?
Hydra is an open-source project initiated by Olivia Jack.
It is a web-based live-coding environment that
allows you to create visuals using JavaScript and WebGL. It
is inspired by analog modular synthesizers and early video synthesis. Hydra allows you to create visuals
collaboratively in a browser window, and stream them in real time.
shortcuts
- CTRL-Enter: run a line of code
- CTRL-Shift-Enter: run all code on screen
- ALT-Enter: run a block
- CTRL-Shift-H: hide or show code
- CTRL-Shift-F: format code using Prettier
- CTRL-Shift-S: Save screenshot and download as local file
- CTRL-Shift-G: Share to twitter (if available). Shares to @hydra_patterns
solid(1, 1, 1)
.out()
solid(1, 0, 1)
.out()
solid(1, 0, 0)
.out()
solid(0, 0, 0)
.out()
from hydra-scrollable-webpage
shape(99)
.scale(1, 1, ()=> window.innerWidth / window.innerHeight)
.mult(osc(20, 0.1, 2))
.modulateScale(
osc(1, 2).invert(), 0.5, 0.5)
.out()
solid(0, 0, 0)
.layer(src(o0)
.scale(1.01).mask(
shape(99)
.scale(1.5, 1.5, () => window.innerWidth / window.innerHeight)))
.blend(
shape(99)
.scale(1.5, 1.5, () => window.innerWidth / window.innerHeight)
.mult(osc(20, 0.1, 2))
, 0.1)
.out()
src(o0)
.modulateHue(
src(o0)
.scale(1.01)
, 1)
.out()
src(o0)
.scale(1.01)
.out()
src(o0)
.modulateRotate(
src(o0)
.scale(1.01)
.hue(() => time/9)
.brightness(-0.3), .01)
.out()
src(o0)
.modulatePixelate(
src(o0)
.hue(()=>time/9)
.r()
.contrast(2)
.pixelate(32,32)
, 1024
, 8)
.out()
src(o0)
.scale(0.99)
.out()
👀👀👀
What just happened?
But I do know a few things that I want to share here, that should help you along at least a little bit...
src(o0)
.mult(solid(), 0.01)
.out()
solid()
.out()
source, geometry, color, blend and modulate
Sources
- solid: solid colors
- gradient: gradients
- shape: basic shapes
- osc: oscillators
- noise: Perlin noise
- voronoi: Voronoi diagrams
- src: output of another layer
- ...
solid
solid( r, g, b, a = 1 )
solid(1, 0, 0).out()
solid(0, 1, 0).out()
solid(0, 0, 1).out()
solid(0, 0, 99999).out()
gradient
gradient( speed )
gradient(0).out()
speed = 1;
gradient(1).out()
speed
speed = 10;
gradient(1).out()
speed = 1;
gradient(10).out()
shape
shape( sides = 3, radius = 0.3, smoothing = 0.01 )
shape().out()
// hexagons
shape(6).out()
// and comments!
shape(6, 0.1, 1).out()
shape(
[3, 6],
[.6, .1, .2, .9]
).out()
array functions
fast( speed = 1 )
smooth( smooth = 1)
ease( ease = 'linear' )
offset( offset = 0.5 )
fit( low = 0, high = 1)
shape(
[3, 6]
.smooth(),
[.6, .1, .2, .9]
).out()
shape(
[3, 9]
.smooth(),
[.6, .1, .2, .9]
.smooth()
.fast(3)
.ease('easeInOutCubic')
).out()
🤯
noise
noise( scale = 10, offset = 0.1 )
noise().out()
noise(
[9, 99]
.smooth()
.fast(0.3)
)
.out()
noise(
11,
[0.1, 0.8].smooth()
)
.out()
voronoi
voronoi( scale = 5, speed = 0.3, blending = 0.3)
voronoi().out()
osc
osc( frequency = 60, sync = 0.1, offset)
osc().out()
osc(1, 1, 0)
.out()
0 .. Math.PI/2
osc(1, 1, Math.PI/2)
.out()
osc(1, 1,
[Math.PI/2, Math.PI*2].smooth()
)
.out()
🪄🪄🪄
// offset
osc(1, 1,
() => {
console.info(Math.round(time));
return Math.sin(time / 99)
* (Math.PI/2);
})
.out()
⏱️
Synth Settings
- speed: change overall speed (R/W)
- bpm: change overall bpm (R/W)
- width: canvas width
- height: canvas height
- mouse: mouse coordinates ({x, y})
- time: tick tock tick tock
- ...
shape(99)
.scroll(
() => -mouse.x / width,
() => -mouse.y / height)
.out()
💡
shape(99)
.out();
shape(99)
.scale(1, 1,
window.innerWidth /
window.innerHeight
)
.out()
shape(99)
.scale(1, 1, () =>
window.innerWidth /
window.innerHeight
)
.out()
src
.out()?
osc().out(o0);
shape().out(o1);
voronoi().out(o2);
gradient().out(o3);
render();
src( tex )
src(o0)
.modulate(noise(3), 0.005)
.blend(shape(4), 0.01)
.out(o0)
🔊🎸🔊🎸🔊
😮
Geometry
rotate( angle = 10, speed )
scale( amount = 1.5, xMult = 1, yMult = 1, offsetX = 0.5, offsetY = 0.5 )
pixelate( pixelX = 20, pixelY = 20)
kaleid( nSides = 4 )
...
noise()
.pixelate(20, 20)
.out()
noise()
.kaleid(9)
.out()
repeat
repeat( repeatX = 3, repeatY = 3, offsetX, offsetY )
repeatX( reps = 3, offset )
repeatY( reps = 3, offset )
shape()
.repeat()
.out()
scroll
scroll( scrollX = 0.5, scrollY = 0.5, speedX, speedY )
scrollX( scrollX = 0.5, speed )
scrollY( scrollY = 0.5, speed )
shape()
.scroll(0.1, 0.1, 0.9, 0.3)
.out()
Color
brightness( amount = 0.4 )
contrast( amount = 1.6 )
luma( threshold = 0.5, tolerance = 0.1 )
thresh( threshold = 0.5, tolerance = 0.04 )
...
voronoi(99)
.out()
voronoi(99)
.brightness([.3, .7].smooth())
.out()
voronoi(99)
.contrast([.5, 3].smooth())
.out()
voronoi(99)
.luma([.3, .7].smooth())
.out()
voronoi(99)
.thresh([.3, .7].smooth())
.out()
Color Cont'd
color( r = 1, g = 1, b = 1, a = 1 )
saturate( amount = 2 )
hue( hue = 0.4 )
colorama( amount = 0.005 )
posterize( bins = 3, gamma = 0.6 )
...
voronoi(99)
.color(3, .2, .9)
.out()
voronoi(99)
.color(3, .2, .9)
.saturate([.3, 4].smooth().fast(.3))
.out()
voronoi(99)
.color(3, .2, .9)
.saturate([.3, 4].smooth().fast(.3))
.hue(() => (Math.sin(time) + 1) / 4)
.out()
voronoi(99)
.color(3, .2, .9)
.saturate([.3, 4].smooth().fast(.3))
.hue(() => (Math.sin(time) + 1) / 4)
.posterize(1)
.out()
voronoi(99)
.colorama(
[0, Math.PI/2]
.smooth()
.fast(.1))
.out()
Color Cont'd
shift( r = 0.5, g, b, a )
invert( amount = 1 )
r( scale = 1, offset )
g( scale = 1, offset )
b( scale = 1, offset )
🥱
Blend
add( texture, amount = 1 )
sub( texture, amount = 1 )
mult( texture, amount = 1 )
diff( texture )
...
// TOP LEFT
osc().color(.6, .2, .1).out(o0);
// TOP RIGHT
osc().color(.2, .8, .7).rotate(-Math.PI/2).out(o2);
src(o0).add(src(o2)).out(o1);
src(o2).add(src(o0)).out(o3);
render();
// TOP LEFT
osc().color(.6, .2, .1).out(o0);
// TOP RIGHT
osc().color(.2, .8, .7).rotate(-Math.PI/2).out(o2);
src(o0).mult(src(o2)).out(o1);
src(o2).mult(src(o0)).out(o3);
render();
// TOP LEFT
osc().color(.6, .2, .1).out(o0);
// TOP RIGHT
osc().color(.2, .8, .7).rotate(-Math.PI/2).out(o2);
src(o0).diff(src(o2)).out(o1);
src(o2).diff(src(o0)).out(o3);
render();
Blend Cont'd
blend( texture, amount = 0.5 )
layer( texture )
mask( texture )
// TOP LEFT
osc().color(.6, .2, .1).out(o0);
// TOP RIGHT
osc().color(.2, .8, .7).rotate(-Math.PI/2).out(o2);
src(o0).blend(src(o2)).out(o1);
src(o2).blend(src(o0)).out(o3);
render();
// TOP LEFT
osc().color(.6, .2, .1).out(o0);
// TOP RIGHT
osc().color(.2, .8, .7).rotate(-Math.PI/2).out(o2);
src(o0).layer(src(o2)).out(o1);
src(o2).layer(src(o0)).out(o3);
render();
// TOP LEFT
osc().color(.6, .2, .1).out(o0);
// TOP RIGHT
osc().color(.2, .8, .7).rotate(-Math.PI/2).out(o2);
src(o0).mask(src(o2)).out(o1);
src(o2).mask(src(o0)).out(o3);
render();
src(o0)
.mult(solid(), 0.01)
.out()
solid()
.out()
🥁🥁🥁
Modulate
modulate( texture, amount = 0.1 )
voronoi().out(o0);
osc().out(o2);
src(o0).modulate(src(o2)).out(o1);
src(o2).modulate(src(o0)).out(o3);
render();
speed = .33;
voronoi().out(o0);
osc().out(o2);
src(o0).modulate(
src(o2),
[0, 1].smooth())
.out(o1);
src(o2).modulate(
src(o0),
[0, 1].smooth())
.out(o3);
render();
// Example from Hydra Reference
src(o0)
.modulateHue(src(o0).scale(1.01),1)
.layer(osc(4,0.5,2).mask(shape(4,0.5,0.001)))
.out(o0)
Modulate
modulateHue( texture, amount = 1 )
modulateScale ( texture, multiple = 1, offset = 1 )
modulatePixelate ( texture, multiple = 10, offset = 3 )
modulateRotate ( texture, multiple = 1, offset )
// Example from Hydra Reference
src(o0)
.modulateHue(
src(o0).scale(1.01), 1)
.layer(
osc(4,0.5,2).mask(
shape(4,0.5,0.001)))
.out(o0)
Modulate Cont'd
modulateRepeat( texture, repeatX = 3, repeatY = 3, offsetX = 0.5, offsetY = 0.5 )
modulateRepeatX ( texture, reps = 3, offset = 0.5 )
modulateRepeatY ( texture, reps = 3, offset = 0.5 )
// Example from Hydra Reference
// straight lines illusion
shape(4,0.9)
.mult(osc(4,0.25,1))
.modulateRepeatX(
osc(10), 5.0,
({time}) => Math.sin(time) * 5)
.scale(1,0.5,0.05)
.out(o0)
Modulate Cont'd
modulateKaleid( texture, nSides = 4 )
modulateScrollX( texture, scrollX = 0.5, speed )
modulateScrollY( texture, scrollY = 0.5, speed )
// Example from Hydra Reference
osc(10, 0.1, 2)
.modulateKaleid(
osc(16).kaleid(999), 1)
.out(o0)
External Sources
Audio
s0.initImage('https://i.imgur.com/B2wV89r.png');
src(s0)
.scale(.2, .8, .3)
.modulatePixelate(
osc(() => Math.sin(time)), 999)
.color([.7, .3].smooth(), [.3, .7].smooth(),.4)
.out()
🙏
s0.initImage('https://i.imgur.com/B2wV89r.png');
src(s0)
.scale(.2, .8, .3)
.modulatePixelate(
osc(() => Math.sin(time)), 999)
.color([.7, .3].smooth(), [.3, .7].smooth(),.4)
.modulateKaleid(voronoi(), [2, 6].smooth().fast(.4))
.out()
Hydra⚡Intro
by
and
🐰