Skip to the page
TACTILE UI

02Object 02 · Dials & knobs

Detent Dial

A rotary control you count by feel. The value sticks at each notch and clicks over, and the light stays where the lamp is. Not a slider in a round costume.

Version
0.1.0
Size
19.5 KB gzipped
Access
With a Pass
Needs
detent-dial.mjs + detent-dial.css
Tests
19 tests · 11 states
On this page
  1. Use it
  2. Options
  3. Methods
  4. States
  5. How it works
  6. Blocks built with it
01

Use it

Set a value by turning, where a slider would lose the sense of travel: levels, gain, selectors, set points. Built for both hands on a pointer and hands on a keyboard.

Copy the detent-dial folder from its package next to your page, link its stylesheet and construct it on an element. Every option has a default; the lab’s Code tab writes the same example at any settings, and for React, Vue, Svelte or a custom element (Using a framework).

<link rel="stylesheet" href="detent-dial/detent-dial.css">
<div id="detent-dial"></div>

<script type="module">
  import DetentDial from './detent-dial/detent-dial.mjs';

  const detentDial = new DetentDial(document.getElementById('detent-dial'), {
    min: 0,
    max: 100,
    step: 1,
  });

  // detentDial.update({ … });   change any option in place
  // detentDial.destroy();        and take it away again
</script>
02

Options

OptionTypeDefaultWhat it does
rangepercent · gain · selector · temperature'percent'Four jobs for one knob: a level, a gain in decibels, an eight-way selector, a thermostat.
positionnumber, 0 to 10050How far through the range. Turning the dial in the preview writes here too.
detentsnumber, 0 to 2411Felt notches across the sweep, ends included. 0 is a smooth dial.
snapbooleanfalseA selector rather than a level.
strengthnumber, 0 to 1.50.6How hard each notch holds before the knob clicks over.
sweepnumber, 180 to 330270Sweep (degrees)
finishaluminium · graphite · brass · bone'aluminium'Spun aluminium, turned brass, anodised graphite with a diamond-cut chamfer, glazed bone ceramic.
lightnumber, 0 to 3453150 is from above, clockwise. The spun band, the glints on the grip, the engraving and the shadow all follow it.
sizenumber, 64 to 400320From a panel of 64 px knobs to a hero dial. Numerals and minor ticks appear when there is room for them.
numeralsvalue · index · none'value'The detent values, or 0, 1, 2… the way a hardware knob is marked.
captionbelow · above · inset · none'below'Label and value under the dial, above it, set into the open throat of the scale, or hidden (still named for assistive technology).
ledbooleanfalseA ring of lenses that light up to the value, in --dd-led.
labeltext''The accessible name. Leave empty to use the range’s own name, so it is never blank and never wrong.
dragrotary · vertical'rotary'Rotary follows the pointer round; vertical is the audio-plugin convention.
readoutbooleantrueShow value
ticksbooleantrueShow scale
soundbooleanfalseSynthesised, no audio file. Starts only after you touch the dial.
hapticsbooleantrueWhere the device supports it.
disabledbooleanfalseDisabled
03

Methods

new DetentDial(element, options)
Builds it inside the element with these options.
value
set(v, { emit = false, animate = true } = {})
Set the value programmatically.
update(opts = {})
Change options in place; the value is clamped into any new range.
destroy()
Stops it and cleans up after it.

Events it fires, which bubble from the element: dial:change, dial:input.

04

States

  1. IdleThe knob rests at its value; the scale fills to it and every passed detent takes the accent.
  2. DraggingAngular drag with unwrapping, vertical travel near the centre, Shift for a fifth of the speed; the knob follows a magnetised position between notches.
  3. Tap on the scaleA click or tap on the printed scale or the LED ring, with no drag, sets the value at that angle and the knob travels there on its usual settle. A tap within reach of a detent lands on it (on a printed 60 it is 60, not 61); with snap on it always lands on the nearest detent. The open throat below the scale takes no tap, and the knob keeps focus for the keys.
  4. SettlingOn release the knob settles onto the landed value; reduced motion removes the flight and keeps the value.
  5. SnappingWith snap on, the value only ever lands on a detent: a selector rather than a level.
  6. At an endHome and End reach the limits; nothing, including a drag past the stop, moves beyond them.
  7. DisabledPointer, scale taps, keys and wheel are ignored and the dial leaves the tab order.
  8. AsleepOnce the knob has settled nothing is drawn: no frame is requested, and the loop also pauses off screen and in a hidden tab.
  9. LED ringAn optional lit arc around the collar shows the value from its start to the pointer, in the signal colour, drawn with the rest of the knob.
  10. Caption placementThe value readout can sit below, above, inside the open bottom of the scale, or be hidden while still announced as the slider value text.
  11. Reduced motionThe knob lands on each value with no flight or settle: the value, the detents, the keys, the drag and the scale tap all stay; only the travel between positions goes.
05

How it works

Made of: Rotary input, Angle unwrapping, Magnetic detents, Fixed lighting, Keyboard slider, Tap to set scale.

Original. Informed by physical detented potentiometers rather than by a catalogue reference, so references is honestly empty. The click is synthesised with Web Audio; no audio file ships.

06

Blocks built with it

Docs
Finish
Volume