experiments, minimalcomps

I’ve done variations of this a few times over the years. It’s essentially Jared Tarbell’s Substrate, but with fixed, isometric angles. This one draws all three angles at once. I have some other ideas for this as well, which I’ll be exploring.

Ran into a weird… bug(?) that I can’t figure out, but did find a workaround for. It added a couple of hours onto the time it took me to build this thing. The fact that it only happens on Firefox so far indicates it is a potential bug. See source for more info.


Controls: MinimalComps2

Graphics: BLJS

Support this work

More MinimalSynth

experiments, minimalcomps

You’d be forgiven if you came to the conclusion that I had any idea of what was going on here, especially with the filter node. I’m half decent at coding to an API, but I don’t really have much of a clue about music and sound.

Did a few more hours of work on top of yesterday’s demo. Started on a whole visual sound class library. It’s worth looking at the source. Not counting the library code, this whole demo was created in under 40 lines of code. Each node is a self contained UI. The toughest part was maintaining the connections. Especially with the oscillator node, which gets destroyed and recreated every time you stop and start it. This means you have to keep track of what is supposed to be connected to it – in both directions – and re-establish those connections as needed. After lots of overly complex solutions, I think I came up with a pretty clean way of managing it.

I’ll be continuing to work on this, adding more nodes, adding some more visualizations. There’s many areas of this web audio API that I haven’t even looked at.


Controls: MinimalComps2

Graphics: BLJS

Support this work

MinimalComps2 v1.5.0


I know, I know, too many releases in too short a time. But I think this is the last minor release for a while. Pretty sure I’ve done most of what I really want to do with these for a v1. And I have no idea what v2 will look like. So from here on out it should be mostly patches with bug fixes and minor tweaks.

What’s in it?

HSlider label positions

Up to now you could only change the position of the text label on an HSlider. Now you can put the value slider just about wherever you want it as well. Both can be placed top, left, right or bottom. There’s some logic in there to make sure they don’t overlap. A change on this one is that previously the value label would be to the right of the slider. Like this:

Old HSlider with value on right.

Now it defaults to on top. Like this:

New HSlider with value on top.

I think this looks a lot better, but it might mess things up for you. You can easily manually change it back to the right side.

ColorPicker with sliders

New color choosing sliders.

When you tab or click into the color picker’s input field, the panel will drop down, giving you RGB sliders to adjust your color. I like this SO much better. My favorite update for this release! You can make it drop up if you want, or turn this feature off altogether to just use the text field.

Dropdown drop up

You can now make the Dropdown component drop up if you don’t have room for it to drop down. This is not automatic. It’s a setting. Hey, these are minimal components.

VSlider swap labels

You can swap the position of the text and value labels on the VSlider, like you can on the Knob. Not a big deal, but someone might use it.

PlayButton component

Yup, a new component.


Functionally, this is the same as a Checkbox or Toggle. You click it to toggle it back and forth between two states (checked / not checked, toggled / not toggled, playing / not playing). But who wants to use a checkbox to start and stop an animation or audio?


That’s all folks. Like I said, I don’t anticipate a v1.6 for a while. But probably some v1.5.x patches here and there to fix bugs and give minor tweaks. Mostly I’m just going to be using them as much as I can in various experiments.

MinimalComps2 v1.4.0


I gotta admin, I’m not crazy about how the 2 in MinimalComps2 works with the semantic versioning. Version 1.4 of version 2? Whatever.

Anyway… VERSION 1.4.0!!!

No new components this time, but some super useful features, as well as a bunch of bug fixes.


There are some new defaults in the Defaults object. These are mostly useful if you are creating a bunch of components that need some specific property that is not settable in the constructor. Like HSlider’s text position. Rather than doing something like:

const hs1 = new HSlider(panel, x, y, "one", 0, 0, 100);
hs1.textPosition = "left";
const hs2 = new HSlider(panel, x, y, "two", 0, 0, 100);
hs2.textPosition = "left";
const hs3 = new HSlider(panel, x, y, "three", 0, 0, 100);
hs3.textPosition = "left";

You can do:

Defaults.hslider.textPosition = "left";
const hs1 = new HSlider(panel, x, y, "one", 0, 0, 100);
const hs2 = new HSlider(panel, x, y, "two", 0, 0, 100);
const hs3 = new HSlider(panel, x, y, "three", 0, 0, 100);

You can see all the properties that use this technique here.

Chainable setters

Another ease of use improvement. Basically, all settable properties now have a setter method that returns the current instance of the component. This lets you set a bunch of properties in a row and assign the result back to a variable that holds the instance. Especially useful for those properties that aren’t in the constructor, but some people don’t like the long constructors either. Along with this work, I made sure that just about all the constructor parameters are optional and have sensible defaults.

So now, if you want, you can do stuff like this:

const velSlider = new HSlider(panel)
  .move(x, y)
  .setSize(200, 30)

Maybe a little overboard with that example, but you get the idea.


Binding is one of my favorite features. It turns this:

new HSlider(panel, 20, 20, "velocity", 0, 0, 100, event => model.velocity =;

to this:

new HSlider(panel, 20, 20, "velocity", 0, 0, 100)
  .bind(model, "velocity");

I wrote about this in a lot more detail here: . So I’ll leave you with that.

Other stuff

I also upgraded the API docs a bit, both in style and content.

A bunch of bug fixes, more demos

Also, check my last few posts here for some more examples of the components in action.

I hope to get a showcase up eventually, linking to other real world uses of the library beyond my own. So if you do something with these, let me know!

Attraction and Repulsion


A particle wanders through a grid of cells, leaving a trail of points behind it. When in a cell, it is attracted to the center of that cell. It is also repelled by its previous trail of points.

Although the center attraction is stronger than the point repulsion, eventually the cell fills up with so many trail points that the particle is pushed into another cell.

Behavior emerges. Hilarity ensues. A good time was had by all.

Reminds me of a bee visiting flowers in a field.

Occasionally Eventually the particle either gets stuck or disappears. Shrug. Probably shouldn’t leave this running unattended for long periods of time.

Source (Warning – very unpolished code. Programmer discretion is advised.)

Controls: MinimalComps2

Graphics: BLJS

Support this work