Interface.js is a cross-platform library for touch, mouse and motion events oriented towards live performance. The library can be used to control JavaScript objects in the same web page, but can also be used to control remote applications using both MIDI and OSC using the included node.js script or the Interface.js Server application.
One goal of the library was to enable programmers to avoid having to place interface widgets using CSS and HTML; in general I don't think using all three technologies together make sense for the types of performance oriented layouts this library is intended for. As such, no knowledge of CSS is needed and a basic web page only needs html, head, body and script tags in order to create a full-window interface. There is an interface editor for people who would like to visually design interfaces that output MIDI and OSC instead of programming them in JavaScript.
Interface.js depends on zepto.js; jQuery can also be used. If you use Interface.js in conjunction with Interface.Server, Zepto will be loaded automatically upon including the interface.js script file in your html document.
See the reference documentation
var a = new Interface.Panel({
container:document.querySelector("#buttonPanel")
});
var b = new Interface.Button({
bounds:[.05,.05,.3,.9],
label:'toggle'
});
var c = new Interface.Button({
bounds:[.35,.05,.3,.9],
label:'momentary',
mode:'momentary'
});
var d = new Interface.Button({
bounds:[.65,.05,.3,.9],
label:'contact',
mode:'contact'
});
a.background = 'black';
a.add(b,c,d);
var a = new Interface.Panel({ background:"#000", container:document.querySelector("#buttonVPanel") });
var b0 = new Interface.ButtonV({
bounds:[.2,.15,.2,.2],
points: [{x:.2,y:0},{x:.8,y:0},{x:1,y:.5},{x:.8,y:1},{x:.2,y:1},{x:0,y:.5},{x:.2,y:0}],
mode:'toggle',
label:'Top',
textLocation : {x:.5, y:.5},
});
var b1 = new Interface.ButtonV({
bounds:[.04,.25,.2,.2],
points: [{x:.2,y:0},{x:.8,y:0},{x:1,y:.5},{x:.8,y:1},{x:.2,y:1},{x:0,y:.5},{x:.2,y:0}],
mode:'toggle',
label:'Top Left',
textLocation : {x:.5, y:.5},
});
var b2 = new Interface.ButtonV({
bounds:[.36,.25,.2,.2],
points: [{x:.2,y:0},{x:.8,y:0},{x:1,y:.5},{x:.8,y:1},{x:.2,y:1},{x:0,y:.5},{x:.2,y:0}],
mode:'toggle',
label:'Top Right',
textLocation : {x:.5, y:.5},
});
var b3 = new Interface.ButtonV({
bounds:[.2,.35,.2,.2],
points: [{x:.2,y:0},{x:.8,y:0},{x:1,y:.5},{x:.8,y:1},{x:.2,y:1},{x:0,y:.5},{x:.2,y:0}],
mode:'toggle',
label:'Middle',
textLocation : {x:.5, y:.5},
});
var b4 = new Interface.ButtonV({
bounds:[.04,.45,.2,.2],
points: [{x:.2,y:0},{x:.8,y:0},{x:1,y:.5},{x:.8,y:1},{x:.2,y:1},{x:0,y:.5},{x:.2,y:0}],
mode:'toggle',
label:'Bottom Left',
textLocation : {x:.5, y:.5},
});
var b5 = new Interface.ButtonV({
bounds:[.36,.45,.2,.2],
points: [{x:.2,y:0},{x:.8,y:0},{x:1,y:.5},{x:.8,y:1},{x:.2,y:1},{x:0,y:.5},{x:.2,y:0}],
mode:'toggle',
label:'Bottom Right',
textLocation : {x:.5, y:.5},
});
var b6 = new Interface.ButtonV({
bounds:[.2,.55,.2,.2],
points: [{x:.2,y:0},{x:.8,y:0},{x:1,y:.5},{x:.8,y:1},{x:.2,y:1},{x:0,y:.5},{x:.2,y:0}],
mode:'toggle',
label:'Bottom',
textLocation : {x:.5, y:.5},
});
var c = new Interface.ButtonV({
bounds:[.6,.05,.35,.9],
points: [{x:0,y:0},{x:1,y:0},{x:1,y:1},{x:0,y:1},{x:0,y:.2},{x:.8,y:.2},{x:.8,y:.8},{x:.2,y:.8},{x:.2,y:.4},{x:.6,y:.4},
{x:.6,y:.5},{x:.3,y:.5},{x:.3,y:.5},{x:.3,y:.7},{x:.7,y:.7},{x:.7,y:.3},{x:.1,y:.3},{x:.1,y:.9},{x:.9,y:.9},{x:.9,y:.1},{x:0,y:.1},{x:0,y:0}],
mode:'momentary',
label:'Spiral',
textLocation : {x:.45, y:.45},
});
a.background = 'black';
a.add(b0,b1,b2,b3,b4,b5,b6,c);
var a = new Interface.Panel({
container:document.querySelector("#sliderPanel")
});
var b = new Interface.Slider({
label: 'vertical slider',
bounds:[.05,.05,.3,.9]
});
var c = new Interface.Slider({
bounds:[.4,.35,.55,.3],
label: 'horizontal slider',
isVertical:false,
value:.5,
});
a.background = 'black';
a.add(b,c);
var a = new Interface.Panel({
container:document.querySelector("#xyPanel")
});
var xy = new Interface.XY({
childWidth: 25,
numChildren: 6,
background:"#111",
fill: "rgba(127,127,127,.2)",
bounds:[0,0,.6,1],
oninit: function() { this.rainbow() },
});
var c = new Interface.Slider({
bounds:[.65,0,.15,1],
min:.0, max:.25,
value:.125,
fill:'#333', background:'#111',
onvaluechange: function() { xy.friction = 1 - this.value; },
label:'friction',
});
var d = new Interface.Slider({
bounds:[.825,0,.15,1],
target:xy, key:'maxVelocity',
min:.5, max:20,
value:15,
fill:'#333', background:'#111',
label:'velocity',
});
a.background = 'black';
a.add(xy, c, d);
var a = new Interface.Panel({ container:document.querySelector("#knobPanel") });
var k1 = new Interface.Knob({
bounds:[.05,0,.25],
value:.25,
usesRotation:true,
centerZero: true,
});
var k2 = new Interface.Knob({
bounds:[.35,0,.25],
value:.75,
usesRotation:true,
centerZero: false,
});
var k3 = new Interface.Knob({
bounds:[.05,.5,.25],
value:.1,
usesRotation:false,
centerZero: true,
});
var k4 = new Interface.Knob({
bounds:[.35,.5,.25],
value:.9,
usesRotation:false,
centerZero: false,
});
var m = new Interface.Label({
bounds:[.7,.2,.25,.5],
value:"uses rotation gesture",
hAlign:'right',
});
var n = new Interface.Label({
bounds:[.7, .7, .25, .5],
value:"uses vertical gesture",
hAlign:'right',
});
a.background = 'black';
a.add(k1, k2, k3, k4, m, n)
var a = new Interface.Panel({ container:document.querySelector("#crossfaderPanel") });
var crossfaderLabel = new Interface.Label({
bounds:[.3,.2,.4,.2],
hAlign:'center',
value:0
});
var crossfader = new Interface.Crossfader({
bounds:[.1,.35,.8,.3],
min:-1, max:1,
crossfaderWidth:30,
target: crossfaderLabel, key:'setValue',
});
a.background = 'black';
a.add(crossfaderLabel, crossfader);
var a = new Interface.Panel({ container:document.querySelector("#rangePanel") });
var rangeLabel = new Interface.Label({
bounds:[.3,.2, .4, .2],
hAlign:'center',
value:0
});
var range = new Interface.Range({
bounds:[.1,.35,.8,.3],
min:-1, max:1,
crossfaderWidth:30,
onvaluechange : function(min, max) {
rangeLabel.setValue('min : ' + min + ', max : ' + max);
}
});
a.background = 'black';
a.add(rangeLabel, range);
var a = new Interface.Panel({ container:document.querySelector("#multiSliderPanel") });
var multiSlider = new Interface.MultiSlider({
count:15,
bounds:[.05,.05,.9,.8],
onvaluechange : function(number, value) {
multiSliderLabel.setValue( 'num : ' + number + ' , value : ' + value);
}
});
var multiSliderLabel = new Interface.Label({
bounds:[.05, .9, .9, .1],
hAlign:"left",
value:" ",
});
a.background = 'black';
a.add(multiSlider, multiSliderLabel);
for(var i = 0; i < multiSlider.count; i++) {
multiSlider.children[i].setValue( Math.random() );
}
var a = new Interface.Panel({ container:("#multiButtonPanel") });
var multiButton = new Interface.MultiButton({
row:4, columns:8,
bounds:[.05,.05,.9,.8],
onvaluechange : function(row, col, value) {
multiButtonLabel
.setValue( 'row : ' + row + ' , col : ' + col + ' , value : ' + value);
},
});
var multiButtonLabel = new Interface.Label({
bounds:[.05,.9, .9, .1],
hAlign:"left",
value:""
});
a.background = 'black';
a.add(multiButton, multiButtonLabel);
for(var i = 0; i < multiButton.count; i++) {
multiButton._values[i] = Math.random() > .5 ;
}
var a = new Interface.Panel({
container:document.querySelector("#pianoPanel")
});
var b = new Interface.Piano({
bounds:[0,0,1,.5],
startletter : "C",
startoctave : 3,
endletter : "C",
endoctave : 5,
noteLabels:true,
});
var c = new Interface.Piano({
bounds:[0,.5,1,.5],
startletter : "C",
startoctave : 3,
endletter : "C",
endoctave : 4,
});
a.background = 'black';
a.add(b,c);
var a = new Interface.Panel({ container:document.querySelector("#textFieldPanel") });
var textField = new Interface.TextField({
bounds:[.05,.05,.5,.2],
onvaluechange : function(value, oldValue) {
textFieldLabel.setValue( "new value : " + value );
},
value: " TEST ",
fill:"#fff",
});
var textFieldLabel = new Interface.Label({
bounds:[.05,.5],
size: 20,
hAlign:"left",
value:"Enter something in the text field above and hit return"
});
a.background = 'black';
a.add(textField, textFieldLabel);
var a = new Interface.Panel({ container:document.querySelector("#menuPanel") });
var menu = new Interface.Menu({
bounds:[.25,.45,.5,.1],
stroke:"#666",
options:['red','green','blue','pink','purple'],
target: a, key:'background',
});
a.background = 'black';
a.add(menu);
var a = new Interface.Panel({ container:document.querySelector("#labelPanel") });
var label = new Interface.Label({
value:"center aligned",
size: 25,
bounds:[0, .15, 1, .1],
});
var label2 = new Interface.Label({
value:"left aligned",
hAlign:'left',
size: 25,
bounds:[.5,.25,.5,.1],
});
var label3 = new Interface.Label({
value:"right aligned",
hAlign:'right',
size: 25,
bounds:[0, .35, .5,.1],
});
var label4 = new Interface.Label({
value:'bold',
style:'bold',
size: 25,
bounds:[0,.45,1,.1],
});
var label5 = new Interface.Label({
value:'Times Italic Big',
style:'italic',
font:'Times',
size: 45,
bounds:[0,.55,1,.25],
});
a.background = 'black';
a.add(label, label2, label3, label4, label5);
var a = new Interface.Panel({
container:document.querySelector("#patchbayPanel")
});
var b = new Interface.Patchbay({
bounds:[0,0,1,.75],
points:[
{name:0},{name:1},{name:2},{name:3},
{name:4, name2:'blargh' },{ name:5, name2:'blargh5' },{name:6}, {name:7}
],
onconnection: function( start, end ) {
c.setValue( start.name + ' connected to ' + end.name )
},
ondisconnection: function( start, end ) {
c.setValue( start.name + ' disconnected from ' + end.name )
},
});
var c = new Interface.Label({
bounds:[0,.75,1,.25],
vAlign:'middle',
value:'Drag a cable between patch points',
})
a.background = 'black';
a.add(b);
var a = new Interface.Panel({
container:document.querySelector("#sliderPanel")
});
var orientation = new Interface.Orientation({
onvaluechange : function(_pitch, _roll, _yaw, _heading) {
pitch.setValue(_pitch);
roll.setValue(_roll);
yaw.setValue(_yaw);
}
});
var pitch = new Interface.Slider({
label: 'pitch',
bounds:[.05,.05,.2,.9]
});
var roll = new Interface.Slider({
label: 'roll',
bounds:[.25,.05,.2,.9]
});
var yaw = new Interface.Slider({
label: 'yaw',
bounds:[.45,.05,.2,.9]
});
a.background = 'black';
a.add(pitch, roll, yaw);
var a = new Interface.Panel({
container:document.querySelector("#sliderPanel")
});
var accelerometer = new Interface.Accelerometer({
onvaluechange : function(_x,_y,_z) {
x.setValue(_x);
y.setValue(_y);
z.setValue(_z);
}
}).start();
var x = new Interface.Slider({
label: 'x',
bounds:[.05,.05,.2,.9]
});
var y = new Interface.Slider({
label: 'y',
bounds:[.25,.05,.2,.9]
});
var z = new Interface.Slider({
label: 'z',
bounds:[.45,.05,.2,.9]
});
a.background = 'black';
a.add(x,y,z);
var a = new Interface.Panel({
container:document.querySelector("#hboxPanel")
});
var hbox = new Interface.HBox({
bounds:[0,0,1,.45]
})
var b = new Interface.Crossfader();
var c = new Interface.Button();
var d = new Interface.Slider();
var vbox = new Interface.VBox({ bounds:[ 0,.55,1,.45 ] })
var e = new Interface.Range();
var f = new Interface.Range();
var g = new Interface.Range();
a.add( hbox,vbox );
hbox.add( a,b,c )
vbox.add( e,f,g )
a.background = 'black';