Skip to content

automat/controlkit.js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Peng!

ControlKit is a lightweight controller and gui library for browser environments. Object properties can be modified with basic control components including buttons, sliders, string and number inputs, checkboxes, selects, color pickers and range inputs. Some more exotic components like xy-pads, value and function plotters provide additional control.


UsageSetupPanelContainerComponentStylingAlternativesDependenciesChangeLogLicense


Usage

When using node or browserify install

npm install controlkit

and require

var ControlKit = require('controlkit');

Alternatively use the standalone version found in ./bin

<script type='text/javascript' src='controlKit.js'></script>

or

<script type='text/javascript' src='controlKit.min.js'></script>

Setup

new ControlKit(options) -> {ControlKit}

The first step in using ControlKit is to create a new instance with some optional customisations. The instance created will serve as a root element for all panels constructed and defines some overall properties such as shared opacity, styling ...

Options

Name Type Description
opacity Number Overall opacity,default: 1.0
useExternalStyle Boolean If true, an external style is used instead of the build-in one, default: false
history Boolean (Experimental) Enables a value history for all components, default: false

controlKit.setShortcutEnable(char) -> {void}

Defines the char to be used with ctrl + char for enabling / disabling a ControlKit instance.

controlKit.registerKey(key,callback)

controlKit.getPanelById(id)->{Panel}

controlKit.getGroupById(id)->{Group}

controlKit.getSubGroupById(id)->{SubGroup}

controlKit.getComponentById(id)->{Component}

Structure

There are two main elements of ControlKit: containers and components. The latter are constructed per panel and grouped in Groups and SubGroups which root in Panels. To keep the amount of code necessary to set up complex controls to a minimum, groups and components initialisation are chained to their parent panel.

//html context example
...
<script type="text/javascript" src="controlKit.min.js">
<script type="text/javascript">
window.addEventListener('load',function(){
	var obj = {
	    number : 0,
	    string : 'abc'
	};
	var controlKit = new ControlKit();
	    controlKit.addPanel()
	        .addGroup()
	            .addSubGroup()
	                .addNumberInput(obj,'number')
	                .addStringInput(obj,'string');
});
</script>
...

Container

Panel

The Panel is the main container element. It can either float to the left or right, be draggable or docked. It´s height can be adjusted to its groups or constrained to a certain height. Floated panels get stacked next to each other.

controlKit.addPanel(options) -> {Panel}

Adds a new Panel.

controlKit.addPanel();
//
var panel = controllKit.addPanel(); //keep ref

Options

Name Type Description
label String Panel label, default: 'Control Panel'
width Number Panel width, default: 300
ratio Number The ratio of label (default:30%) and component (default:70%) width
align String Float 'left' or 'right', multiple panels get aligned next to each other
fixed Boolean If false the panel can be moved
position Array If unfixed, the panel panel position relative to alignment (eg. if 'left' 0 + position[0] or if 'right' window.innerHeight - position[0] - panelWidth)
opacity Number Panel opacity
dock Boolean (Experimental) Indicates whether the panel should be docked to either the left or right window border (depending on params.align), docked panels height equal window height, default: false

Group

panel.addGroup(options)

Adds a new Group to the Panel.

Options

Name Type Description
label String Group label, default: ''. If '' or null the group-head collapses
useLabel Boolean Trigger whether all contained SubGroups and Components should use labels, default: true
enable Boolean Defines initial state open / closed, default: true
height Number Defines whether the height of the Group should be constrained to a certain height

SubGroup

panel.addSubGroup(options) ->{Panel}

Adds a new SubGroup to the last added Group. Options

Name Type Description
label String SubGroup label, default: ''. If '' or null the subgroup-head collapses
useLabel Boolean Trigger whether all Components should use labels, default: true
enable Boolean Defines initial state open / closed, default: true
height Number Defines whether the height of the Group should be constrained to a certain height
//default init
controlKit.addPanel()
    .addGroup()
        .addSubGroup()
            .addComponentXY(object,propertyKey);
            
//If components are immediately added after panel creation,
//the initial Group and SubGroup are added automatically
controlKit.addPanel()
    .addComponentXY(object,propertyKey);
    
//multiple levels  
controlKit.addPanel()
    .addGroup()
        .addSubGroup()
            .addComponentXYZ(object,propertyKey)
            .addComponentXYZ(object,propertyKey)
            ...
    .addGroup() // add second Group
        .addSubGroup()
            .addComponentXYZ(object,propertyKey)
            ...
        .addSubGroup() // add second SubGroup
            .addComponentXYZ(object,propertyKey)
            ...
    ...

Component

[explain linked components here]

var obj = {
	valueA : 0.25,
	valueB : 1.25,	
	func : function(x,y){
		return Math.sin(x * this.valueA) * Math.cos(y * this.valueB);
	}
}

var controlKit = new ControlKit();

controlKit.addPanel()
	.addNumberInput(obj,'valueA')
	.addNumberInput(obj,'valueB')
	.addFunctionPlotter(obj,'func');

Built-in components

General advice!

All number related components including sliders have an option for specifying the amount of decimal places. To prevent weird behaviour when updating an objects number property from different number components with different decimal places settings, make sure to use the same amount of decimal places in every component modifying the same property.

NumberInput
NumberInputOption

panel.addNumberInput(object,propertyKey,options) -> {Panel}

Adds a new NumberInput to the last added SubGroup. Returns panel.
Options

Name Type Description
label String Component label
onChange Function Callback on change
step Number Amount subbed/added on arrowDown/arrowUp press
dp Number Decimal places displayed
presets Array A set of presets [0,1,2,3,4]

NumberOutput

panel.addNumberOutput(object,propertyKey,options) -> {Panel}

Adds a new NumberOutput to the last added SubGroup. In contrast to NumberInput this component doesn't allow modifying the property.
Options

Name Type Description
label String Component label
dp Number Decimal places displayed

StringInput
StringInputOption

panel.addStringInput(object,propertyKey,options) -> {Panel}

Adds a new StringInput to the last added SubGroup.
Options

Name Type Description
label String Component label
onChange Function Callback on change
presets Array A set of presets ['abc','def','ghi']

StringOutput

panel.addStringOutput(object,propertyKey,options) -> {Panel}

Adds a new StringOutput to the last added SubGroup. In contrast to StringInput this component doesn't allow modifying the property.
Options

Name Type Description
label String Component label

Slider

panel.addSlider(object,propertyKey,rangeKey,options) -> {Panel}

Adds a new Slider to the last added SubGroup.

var obj = {value:0,range:[-1,1]};

panel.addSlider(obj,'value','range');

Options

Name Type Description
label String Component label
onChange Function Callback on drag
onFinish Function Callback on drag end
step Number Amount subbed/added on arrowDown/arrowUp press
dp Number Decimal places displayed

Range

panel.addRange(object,propertyKey,options) -> {Panel}

Adds a new Checkbox to the last added SubGroup. Options

Name Type Description
label String Component label
onChange Function Callback on change

Button

panel.addButton(label,onPress,options) -> {Panel}

Adds a new Button to the last added SubGroup.

panel.addButton('fire',function(){console.log('Peng!);});

Options

Name Type Description
label String Component label

Checkbox

panel.addCheckbox(object,propertyKey,options) -> {Panel}

Adds a new Checkbox to the last added SubGroup. Options

Name Type Description
label String Component label
onChange Function Callback on change

Select
SelectOption

panel.addSelect(object,propertyKey,options) -> {Panel}

Adds a new Select to the last added SubGroup.

var obj = {
    options:['Some','options','to','choose'], 
    selection : null
};
obj.selection = obj.options[0];

//'Some' selected
panel.addSelect(obj,'options',{
    target:'selection'
});

//No item as preset selected, 'Choose' displayed
panel.addSelect(obj,'options',{
    onChange:function(index){
        obj.selection = obj.options[index];
});

Options

Name Type Description
label String Component label
onChange Function Callback on select - function(index){}
target String Target property key - property to be set on select

Color
ColorOption
Picker

panel.addColor(object,propertyKey,options) -> {Panel}

Adds a new Color modifier to the last added SubGroup.

var obj = {color:'#ff00ff'};

panel.addColor(obj,'color',{colorMode:'hex'});

Options

Name Type Description
label String Component label
onChange Function Callback on change
colorMode String The colorMode to be used: 'hex' #ff00ff, 'rgb' [255,0,255], 'rgbfv' [1,0,1]
presets Array A set of preset colors matching params.colorMode

Pad

panel.addPad(object,propertyKey,options) -> {Panel}

Adds a new XY-Pad to the last added SubGroup. Options

Name Type Description
label String Component label

FunctionPlotter

panel.addFunctionPlotter(object,propertyKey,options) -> {Panel}

Adds a new FunctionPlotter to the last added SubGroup. Options

Name Type Description
label String Component label
lineWidth Number Graph line width
lineColor Array Graph line color [255,255,255]

ValuePlotter

panel.addValuePlotter(object,propertyKey,options) -> {Panel}

Adds a new ValuePlotter to the last added SubGroup. Options

Name Type Description
label String Component label
height Number Plotter height
resolution Number Graph resolution
lineWidth Number Graph line width
lineColor Array Graph line color [255,255,255]

Custom Components

Custom Canvas Component

Custom SVG Component

Sync to external change

If a value gets changed externally, eg in an update loop, you can sync ControlKit by using: (be aware that this might have a quite huge performance impact when using complex control setups)

update(){	//your update loop
	controlKit.update();
}

Styling

If the default styling is too photoshoppy for your taste, you can completly replace it by modifying the default one located in ./style.

Its written in scss and split into _images.scss (up/down arrows, close btn images, undo ...), _presets.scss (all variables, sizes, colors, ratios, font related...) and style.scss (defining the actual structure). Although a great amount of time has been spend translating the designs to css, the files need a little cleanup and restructure.

Apply your custom style by either using an external stylesheet (eg. when developing a custom style) via:

var controlKit = new ControlKit({useExternalStyle:true});

Or create a standalone version of controlKit with a custom built-in style using:

utils/node build -o outFileDir -s yourCustomCSS

If for some reason, you want to completly replace the default styling. Alter it within the original folder and just run.

utils/node update

This will inject the new default style into to the packaged version controlKit.js and controlKit.min.js within ./bin, but will also completly replace the default module version.


Alternatives

dat.gui — The de facto standard
Palette — Juerg Lehni
Guido — Processing.js compatible, Florian Jenett

DevDepencies

browserify
uglify-js clean-css

License

The MIT License (MIT)

Copyright (c) 2013-2014 Henryk Wollik

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.