Skip to the page
TACTILE UI

10Object 10 · Dials & knobs

Compass

A liquid-damped compass. The card swings past the mark and settles while a lit display reads the bearing. Your hand turns the knurled bezel, one click a degree.

Version
0.1.0
Size
14.4 KB gzipped
Access
Free with an account
Needs
compass.mjs + compass.css
Tests
14 tests · 12 states
On this page
  1. Use it
  2. Options
  3. Methods
  4. States
  5. How it works
01

Use it

An angle input and an angle readout that people believe. As an input it is a real slider (0–359, spoken as "274 degrees, west", arrows, Shift, Page keys, Home for north) for a heading, a bearing, a camera or antenna azimuth, a solar tracker. As a readout it is a wind direction on an energy or weather dashboard, a vehicle or drone heading in a fleet console, or a device's own orientation from its compass sensor.

Copy the compass 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="compass/compass.css">
<div id="compass" style="width: min(90vw, 520px); height: min(80vh, 520px); display: grid"></div>

<script type="module">
  import Compass from './compass/compass.mjs';

  const compass = new Compass(document.getElementById('compass'), {
    bearing: 274,
    damping: 0.6,
    card: 'cardinal',
  });

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

Options

OptionTypeDefaultWhat it does
bearingnumber, 0 to 359274Where it points. Turn the bezel in the preview to change it.
dampingnumber, 0.1 to 1.50.6The liquid: low swings past and rings; 1 and above arrive without passing.
carddegrees · cardinal · aviation'cardinal'Degrees only, cardinal points, or an aviation heading card (3, 6, 12…).
finishauto · aluminium · graphite'auto'Auto follows the page’s data-finish. Graphite reads its display on a VFD.
sizenumber, 0 to 64000 fills its frame; any other value is the dial’s diameter, shrunk only to fit.
lightnumber, 0 to 3453150 is from above, clockwise. The sheen stays with the lamp as the card turns.
readonlybooleanfalseA wind or heading readout: it turns to values from code, not the hand.
displaybooleantrueThe lit readout in the hub.
labeltext'Heading'Accessible name
03

Methods

new Compass(element, options)
Builds it inside the element with these options.
value
The bearing the compass is set to, 0–359.
heading
Where the card is pointing right now (it lags the value while it swings).
state
setValue(v, { instant = false } = {})
Turn to a bearing.
update(opts = {})
Change options in place.
useSensor()
Let the device's own compass drive it.
stopSensor()
destroy()
Stops it and cleans up after it.

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

04

States

  1. At restThe card's N sits boxed under the bezel's index and the bearing is under the lubber; the display reads it; the loop is asleep.
  2. Turning the bezelDrag anywhere on the dial: the bezel follows the hand in 1° detents with no lag; the card follows it through the liquid; input fires on every degree.
  3. SwingingAfter a turn or a flick the card passes the mark and swings back (about a tenth of the swing at the default damping) and settles within two seconds; the display reads the card as it swings.
  4. KeyboardArrows step 1°, Shift or Page keys 10°, Home goes north; values wrap from 359 to 0; change fires on each key.
  5. From codesetValue() swings it to a bearing without firing input or change: a wind feed or a heading stream.
  6. Read-onlyA readout: the hand does nothing and aria-readonly says so.
  7. Device compassuseSensor() asks for permission and lets the device's own heading drive it; off by default.
  8. AluminiumA bead-blasted aluminium bezel, a black anodised lip ring, a warm-white card and a reflective LCD.
  9. GraphiteA soft-touch graphite bezel, a black card with light print and a glowing VFD.
  10. SmallUnder a 90 px card radius it drops the 1° ticks, it leaves off labels too small to read, and under 96 px across it hides the display.
  11. Off screen or hiddenThe loop pauses mid-swing and finishes when it is back; a returning tab advances one clamped frame.
  12. Reduced motionIt points at once and no frame is requested; keys and drags still set it.
05

How it works

Made of: Short way damped spring, Detented bezel, Heightfield turned metal, Phase baked knurl, Room fixed sheen, Split turning print, Lit display readout, Device orientation, Sleeping loop, Fit to host.

Original. Canvas 2D for the instrument, DOM for the lit display (the kit's LCD on aluminium, VFD on graphite). The housing is a heightfield shaded per pixel once per size and finish; the knurl is baked at three phases of its 3° pitch so its teeth light by where they are as the bezel turns in 1° detents. A frame is five drawImage calls. The integrator assigns cut (0 is not a valid cut, so the field is left out).

Docs
Finish
Volume