Cascade is a live-coding environment
It runs in the web browser, turning CSS rules into sound
Cascade is a live coding parasite to Cascading Style Sheets
$ python -m SimpleHTTPServer 8000
.Cascade interprets the HTML element with a .cas
class. You can start by creating a visible div with the background color you like, more details about how to start in Getting started.
Cascade also provides useful commands to execute in the browser’s webdev console, (see Commands). Any other way to modify a web page is compatible with Cascade, collaborative editing, static HTML pages, live coding performances… Be creative!
Download Cascade and import the following files present in the /js
folder to your HTML page:
<script src="path-to/Tone.js" charset="utf-8"></script>
<script src="path-to/instruments.js" charset="utf-8"></script>
<script src="path-to/cascade.js" charset="utf-8"></script>
You will also need to link cascade.css
to your page. You can find it in the /css
folder:
<link rel="stylesheet" href="path-to/cascade.css">
Create an HTML structure with divs and background colors, for instance:
<body style="background-color: navy; height: 100vh;">
<div class="cas" style="top: 2vh; left: 10vw; background-color: yellow; width:100px; height:300px;"></div>
<div class="cas" style="top: 1vh; left: 30vw; background-color: red; width:100px; height:30px;"></div>
</body>
Now you need to initialize Cascade with JavaScript, here we take body
as the Cascade container:
let c = new Cascade("body")
You should now hear something. To go further, open your browser’s devtool and move the divs around by changing their positions, background colors, sizes… A couple of scripts will help you to play around, for instance, js/interface.js
will make every element draggable, change their background color on shift + click, and remove it with a double click.
new Cascade(querySelector root element, {options})
The default cascade class is .cas
. Only elements containing that class are taken into account. To override that default:
let c = new Cascade("body", {
cascadeClass: '.yourOwnClass',
})
Available options are:
cascadeClass
: the class that will be used to interpret the HTML elements on the page. The default value is .cas
.defaultStyle
: default style applied to a div when add
is used without specifying style.instruments
: array of objects containing Tonejs instruments. See /js/instruments.js
for example.startButton
: if false
, the start button will not be used. The default value is true
.activeStyle
: The style of an element when it is played. The default value is opacity:.5;
.bpmRange
: array of two values, the first one being the minimum BPM for the darkest color, the second value being the maximum BPM Cascade can reach for the lightest color. The default value is [10, 200]
.An example with custom options:
let c = new Cascade("body",{
cascadeClass: ".toplay",
defaultStyle: "width:20px; height:70px; background:olive;",
startButton: false,
activeStyle: "border-bottom:4px solid red;",
bpmRange:[30, 300],
})
The following commands can be executed in your browser’s devtool console:
add(style, parent, copies)
: adds a new div
element to the page with an optional style
[string] inline CSS parameter and an optional parent
[int] id and the number of copiesclear()
: clears the pageclone(style, id)
: clones element and its style, optional style
to adddl(file-name)
: downloads the current state of the composition as an HTML page with optional file-name
. This function requires js/download.js
mod(style, id)
: adds or changes an element’s style. If id
is an array, it will affect many elements at once.scan()
: reveals elements informations such as ID, ratio, instrument, and color tablels()
: lists elements on pagemute()
: toggles mute on all instrumentsstart()
: starts cascade, with an optional delay
attribute in secondsstop()
: stops cascaderawStyle()
: injects raw CSS to the pagerm(id)
: removes the element id
. If id
is an array, it will affect many elements at once.If you use the following cascade variable name:
let c = new Cascade("body")
… you will access to the commands this way, on your page or live, in the devtool’s console:
c.start()
c.add('width:10vh; height:30px; background:cyan; top:80vh;')
Alternatively, for the sake of typing speed, you can add the file js/live-shortcut.js
to directly access the commands:
add()
The following events can be listened: add
, clone
, start
, stop
, rm
, update
. You can use events this way:
let c = new Cascade("body")
c.on('add', function(e) {
console.log(`Created: ${e.detail.newNode.id}`)
})
The following table associates graphic and sound characteristics. Some properties are vague on purpose (positions) because they can be impacted by many CSS rules: top
, right
, bottom
, left
, margin
, transform
, flex
…
CSS | Sound | Comments |
---|---|---|
Body background color | BPM | Only body ’s background color luminosity will set the piece’s BPM. E.g. yellow = 150 BPM MidnightBlue = 81 BPM. |
Horizontal position | Delay | Time delay within the beat period: if the element moves 10% from the left, it is to be delayed 10% after the time. |
Vertical position | Note | The note pitch. Higher = louder. |
Width / Height ratio | Beat distribution | The width / height ratio sets the number of beats and the number of steps, following Godfried Toussaint’s Euclidean rhythm distribution. E.g. a ratio 8:13 will play 0 1 1 0 1 1 0 1 , 1:2 will play 1 0 . The ratio ignores the orientation, in this sense 4:3 = 3:4 ; the greatest of the two ratio numbers is always used for the number of steps, and the smallest for the number of beats. |
Background color | Instrument | The background-color of an element will define the instrument: Cascade comes by default with 10 color CSS variables you can overwrite, those variable numbers (e.g.:--c3 ) will set the third instrument. Any other color will be interpreted as the closest one defined by a variable. The color associated with CSS variable --c0 (white by default) will ignore ratio for parents in case of nesting. |
Surface | Velocity (volume) | The surface of an element (width × height) will affect the volume of the associated instrument. The bigger the louder. |
Opacity | Probability | The opacity value will affect the chance an element will have to be played. E.g. opacity:0.5; will play the element randomly 1 over 2 times. |
Border radius | Duration | The cumulated 4 border radius of the element will define the duration of the sound it triggers. High radius => short sound. |
Border top width | Cycle shift | This value in px will shift the rhythmic pattern. E.g. a 1px border top will change 1 0 0 0 into 0 1 0 0 . This can also be known as “Euclidean rotation”. |
Border left / Right width | Pan (soon) | The difference between left and right borders width will define the left / right pan. E.g. to place an instrument at the max. right, add a 10px right border or more. |
More to come… |
Only a few CSS properties are interfaced with sound, other properties are ignored. The chosen CSS properties were picked for the following reasons:
With Pool mode, you can use Cascade with other performers in real time, or broadcast a live performance to another browser.
Go to /pool
, then install npm modules with:
$ npm install
… and run the app with:
$ node index.js
Then got to either localhost:8080/performer
for performing (can listen, see, and modify) or localhost:8080/
to attend the performance (can listen and see only).
Cascade pool comes with the following limitations:
rm()
triggers a non-fatal errorContributions are welcome, let’s talk about your feedback and ideas in the issues.
Huge thanks to @alicericci for her dev skills and @svilayphiou and her students for the early adoption, and Éléonore Siboni for the documentation proofreading.
Cascade is released under GNU AGPL.