Skip to content

Instantly share code, notes, and snippets.

@bedekelly
Created November 5, 2020 13:26
Show Gist options
  • Save bedekelly/f4ddb1d5075dbb2585b5e49b9ffb517c to your computer and use it in GitHub Desktop.
Save bedekelly/f4ddb1d5075dbb2585b5e49b9ffb517c to your computer and use it in GitHub Desktop.
Svelte implementation of a 2-way-binding knob control
<!-- App.svelte -->
<script>
import Knob from './Knob.svelte';
let value = 0;
const reset = () => { value = 50 };
</script>
<Knob bind:value={value} max={100} min={0} pixelRange={200}/>
<p>
{value.toFixed(0)}%
</p>
<button on:click={reset}>
Set to 50%
</button>
<!-- Knob.svelte -->
<div class="knob" style="--rotation: {rotation}" on:pointerdown={pointerDown}>
</div>
<script>
export let value, min, max;
export let rotRange = 2 * Math.PI * 0.8;
export let pixelRange = 200;
export let startRotation = -Math.PI*0.8;
let startY, startValue;
$: valueRange = max - min;
$: rotation = startRotation + (value - min) / valueRange * rotRange;
function clamp(num, min, max) {
return Math.max(min, Math.min(num, max));
}
function pointerMove({ clientY }) {
const valueDiff = valueRange * (clientY - startY) / pixelRange;
value = clamp(startValue - valueDiff, min, max)
}
function pointerDown({ clientY }) {
startY = clientY;
startValue = value;
window.addEventListener('pointermove', pointerMove);
window.addEventListener('pointerup', pointerUp);
}
function pointerUp() {
window.removeEventListener('pointermove', pointerMove);
window.removeEventListener('pointerup', pointerUp);
}
</script>
<style>
.knob {
background: conic-gradient(white 0%, white 2%, black 2%, black 98%, white 98%);
width: 100px;
user-select: none;
height: 100px;
border-radius: 50%;
transform: rotate(calc(var(--rotation) * 1rad));
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment