Basic styled svg knob
<script> import { SvgKnob } from 'svelte-knobs'; let value = $state(0.0); </script> <div> <SvgKnob bind:value /> <span>{value.toFixed(2)}</span> <SvgKnob bind:value disabled /> </div> <style> div { color: #22bfee; } </style>
You can use an image strip for a knob too.
<script lang="ts"> import { ImageKnob } from 'svelte-knobs'; import imageSource from '../assets/PurpleKnob2.webp'; let value = $state(0.0); </script> <ImageKnob bind:value src={imageSource} width={90} height={90} />
In reality, svgknob and image knob are both based from a <Draggable/>
component,
that you can use as well, creating your very own custom made knob.
<script lang="ts"> import { valueToAngle, Draggable } from 'svelte-knobs'; let valueSmoothed = $state(0.5); let angle = $derived(valueToAngle(valueSmoothed, -135, 135)); </script> <Draggable bind:valueSmoothed> <div class="knob"> <div class="glow" style="filter: blur({valueSmoothed * 5}px);transform: scale({valueSmoothed})" ></div> <div class="thumb" style="transform: rotate({angle}deg) translateY(-10px)"></div> <span>{valueSmoothed.toFixed(2)}</span> </div> </Draggable> <style> .knob { z-index: 0; user-select: none; width: 60px; height: 60px; border-radius: 100px; background: #000; position: relative; display: grid; place-items: center; } .glow, .thumb { z-index: -1; position: absolute; background: red; border-radius: 30px; } .glow { width: 30px; height: 30px; } .thumb { width: 10px; height: 20px; } </style>
Since all knobs operate on values between 0 and 1 any type of scaling is done outside of the scope of a knob with parameter objects.
<script lang="ts"> import { LinearParam, LogParam } from 'svelte-knobs/params'; import { SvgKnob } from '$lib'; let value = $state(0.0); const freqParam = new LogParam(20, 20_000, 10); const linParam = new LinearParam(0, 100); </script> <section> <div> <SvgKnob bind:value /> <span>{freqParam.denormalize(value) | 0}hz</span> </div> <div> <SvgKnob bind:value /> <span>{linParam.denormalize(value) | 0}%</span> </div> </section> <style> section { display: flex; gap: 0.5rem; flex-wrap: wrap; } </style>
You can specify snap points and how strong the snapping is for your knob. The knob will
automatically sort and insert 0 and 1 to your snap point list, so [0.6,0.3]
will
become [0.0,0.3,0.6,1.0]
.
When snapPoints are specified, arrow keys on the keyboard will make the knob jump between them. Pressing alt key will disable the snapping.
This concept will be importand later in the next example.
<script> import { SvgKnob } from 'svelte-knobs'; let value = $state(0.0); </script> <div> <SvgKnob bind:value snapPoints={[0.5]} /> <span>{value.toFixed(2)}</span> </div>
Enums, or in typescript realm readonly string[]
parameter are a special type of
parameter that don't denormalize into a number, instead into a string. EnumParam
class
comes with helpful properties for knob ui with already calcualted snap points and snap threshold
to make value changes 'instant'.
<script lang="ts"> import { BoolParam, EnumParam } from 'svelte-knobs/params'; import { SvgKnob } from '$lib'; let value = $state(0); const fruitParam = new EnumParam(['🍍', '🍉', '🍌', '🍋', '🍇'] as const); const filterTypeParam = new EnumParam([ 'Low pass', 'High pass', 'Low shelf', 'High shelf', 'Bell', 'Notch', 'Allpass' ] as const); const booleanParam = new BoolParam(); </script> <SvgKnob bind:value snapPoints={fruitParam.snapPoints} snapThreshold={fruitParam.snapThreshold} /> <p>{fruitParam.denormalize(value)}</p> <SvgKnob bind:value {...filterTypeParam.knobProps} /> <p>{filterTypeParam.denormalize(value)}</p> <SvgKnob bind:value {...booleanParam.knobProps} /> <p>{booleanParam.denormalize(value)}</p>