Let's get started creating a control panel full of “knobs” to interactively tweak values in our application.
When creating a knob, two considerations are important.
The first is the type of the value you need to control.
So far we don't have many options, as only knobs that control numbers (Ints and Floats) are available in this package.
The second important consideration is the interface you want to provide to manipulate that value,
i.e. the control itself.
This package's knobs are named putting the value's type first,
so it's easier to find the one you want according to the value you need to produce.
First up, within our app's init let's create a Knob and put it in the model.
The following are the functions you can use to create basic knobs that map to a single primitive value.
Creates an input field knob for manually entering any floating point number.
The step argument specifies the amount the number will increase or decrease
when pressing the up and down keys.
initial is just the value it takes on first load.
Creates an input field knob for manually entering numbers within a specific range,
where range = ( min, max ).
The step argument specifies the amount the number will increase or decrease
when pressing the up and down keys.
initial is just the value it takes on first load.
Creates a slider knob useful for quickly tweaking numbers when precision is not needed.
Requires a range = ( min, max ) to set the boundaries of the slider control.
initial is just the value it takes on first load.
The step argument indicates the granularity of the values the slider will allow,
so a step of 1 will produce a slider that jumps between values like 1, 2, 3 as you slide it to the right,
whereas a step of 0.1 will produce one that allows setting values like 1.1 or 2.5.
Creates an input field knob for manually entering any integer.
The step argument specifies the amount the number will increase or decrease
when pressing the up and down keys.
initial is just the value it takes on first load.
Creates an input field knob for manually entering integers within a specific range.
The step argument specifies the amount the number will increase or decrease
when pressing the up and down keys.
initial is just the value it takes on first load.
Creates a slider knob useful for quickly tweaking integers when precision is not needed.
Requires a range = ( min, max ) to set the boundaries of the slider control.
initial is just the value it takes on first load.
The step argument indicates the granularity of the values the slider will allow,
so a step of 1 will produce a slider that will set on any integer value as you slide it to the right,
whereas a step of 10 will produce one that makes bigger jumps between 10, 20, 30, etc.
The next step is to actually show our knob in the page.
Converts a knob into HTML to put in your view.
You should display a single Knob value at any which time,
so if you need multiple knobs, make sure you compose them into a single value!
Knobs keep track of their state once they're put in the view, but for that you need to wire them up with a message, which is the first argument that this function takes.
This function produces plain HTML with no styles, so make sure you also include styles
in your page to make it display properly, or provide your own custom styles.
-- Prepare a message for your knob:
type Msg =
KnobUpdated (Knob YourType)
-- Put this as an HTML node within your view:
Knob.view KnobUpdated yourKnobCheck the documentation's readme for a full demonstration on how to wire things up.
Default styles for the knobs, provided as a <style> tag.
Put this as a child somewhere in your view in order to use them.
You could choose not to use these default styles and instead provide your own. I recommend you check the DOM output in your browser's inspector—the structure of the HTML produced is pretty simple!
Of course, our knobs are of no use to us if we can't read the value entered by the user.
Extract the current value out of a knob. Use it in your view to affect what you display.
Knob.value someKnobMost of the time you'll want to control multiple values. For that purpose we're going to “stack” our knobs together.
Creates a knob that joins multiple knobs to build up a record
(or actually any data structure you want, depending on the constructor argument you pass it!).
Pipe (|>) the knobs into it
using stack or stackLabel in order to provide the arguments.
type alias Controls =
{ someNumber : Float
, anInteger : Int
}
aKnob =
Knob.compose Controls
-- This knob will map to `someNumber`:
|> Knob.stack (Knob.float 1 0)
-- This one will map to `anInteger`:
|> Knob.stack (Knob.int 1 0)Here's how you use it to build up a different data structure, in this case a tuple. Notice that the number of arguments in the function matches the number of “stacks”.
anotherKnob =
Knob.compose (\theFloat theInt -> ( theFloat, theInt ))
|> Knob.stack (Knob.float 1 0)
|> Knob.stack (Knob.int 1 0)Adds a knob into a compose knob.
See the documentation for that for an example.
This function is called “stack” because the order you compose your knobs does matter, as they will be displayed one on top of the other!
We could have a bunch of similar knobs in our panel and not know what each of them does, so let's make sure we do!
Attaches a text description next to a knob, as a way to identify what the control is for.
The following example will produce a float knob described as “x position”.
Knob.label "x position" (Knob.float 1 0)
Represents one user-interactive control mapped to one value of type
a, which this package refers to as a “knob”. This is the base type used to create your knobs control panel! Normally you'll have one of these stored in your model.