Skip to content

Commit

Permalink
Imported ElegantKnob from Fazeoid, needs cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
neonfuz committed Sep 5, 2022
1 parent d9e578b commit e8b24b3
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 10 deletions.
109 changes: 109 additions & 0 deletions src/lib/ElegantKnob.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<script lang="ts">
import knobdrag, { makeValueStore } from '$lib/knobdrag';
import Input from '$lib/Input.svelte';
// Parameters
export let min = 0;
export let max = 100;
export let step = (max - min) / 100;
export let value = (min + max) / 2;
const valueStore = makeValueStore(value, newValue => value = newValue);
$: valueStore.set(value);
let inputElem: Element;
$: knobParams = { min, max, step, valueStore, inputElem };
// Aesthetic
export let size = '5rem';
export let fgColor = '#ffffff';
export let bgColor = '#000000';
export let valueColor = '#ffffff';
export let label: string | undefined = undefined;
export let numTicks = 6;
// Visual math functions
const visualRange = 270;
const visualStartPoint = 135;
const normalizeValue = (value: number) => (value - min) / (max - min);
const angleOnKnob = (normValue: number) => normValue * visualRange + visualStartPoint;
const valueOnKnob = (value: number) => angleOnKnob(normalizeValue(value));
$: ticks = Array(numTicks).fill(0).map((_, i) => ({
angle: angleOnKnob(numTicks === 1 ? 0.5 : i / (numTicks-1)),
}));
</script>

<div class="ElegantKnob" style:width="{size}">
<div class="value" style:font-size="calc({size} / 5)">
<Input
bind:value
bind:inputElem
color={fgColor}
/>
</div>
<svg
viewBox="0 0 10 8.6"
version="1.1"
xmlns="http://www.w3.org/2000/svg">
<path
class="background"
style:fill="{bgColor}"
use:knobdrag="{knobParams}"
d="M 8.5,8.6 A 5,5 0 1 0 1.5,8.6"
/>
{#if value >= min && value <= max}
<path
class="pointer"
style:fill="{valueColor}"
transform="rotate({valueOnKnob(value)}, 5, 5)"
d="M 9.5640408,5.0000863 8.8569772,5.7071499 c -0.3904906,0.3904906 -1.0236127,0.3904669 -1.4141272,2e-7 -0.3904668,-0.3905145 -0.3904667,-1.0236129 1e-7,-1.4141273 0.3905144,-0.3904667 1.0236366,-0.3904906 1.4141272,0 z" />
{/if}
<g class="ticks" >
{#each ticks as {angle}}
<path
stroke="{fgColor}"
d="M 8.5,5 9,5"
transform="rotate({angle}, 5, 5)" />
{/each}
</g>
</svg>
{#if label}
<div style:font-size="calc({size} / 8)">
{label}
</div>
{/if}
</div>

<style>
.ElegantKnob {
display: inline-grid;
grid-auto-flow: row;
place-items: center;
pointer-events: none;
}
.background {
opacity: 0.7;
pointer-events: all;
cursor: pointer;
}
.background:hover {
opacity: 1;
}
svg, .value {
grid-area: 1/1;
}
.value {
position: relative;
top: 6.5%;
width: 50%;
}
.value :global(input) {
padding: 0;
font-size: 100%;
}
.ticks {
stroke-width: 0.2px;
stroke-linecap: round;
vector-effect: non-scaling-stroke;
opacity: 0.5;
}
</style>
4 changes: 2 additions & 2 deletions src/lib/MinimalKnob.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
export let size = '5rem';
export let strokeWidth = 8;
export let bgColor = '#fff';
export let fgColor = '#7f9fff';
export let valueColor = '#7f9fff';
export let label: string | undefined = undefined;
</script>
Expand All @@ -31,7 +31,7 @@
use:knobdrag="{knobParams}"
/>
<circle class="knobFg" cx="0" cy="0" r="20" transform="rotate({90} 0 0)"
style:stroke="{fgColor}"
style:stroke="{valueColor}"
style:stroke-width="{strokeWidth*0.8}"
style:stroke-dashoffset="{40*Math.PI - 40 * Math.PI * (value - min) / (max - min)}"
style:stroke-dasharray="{40 * Math.PI}"
Expand Down
19 changes: 11 additions & 8 deletions src/routes/index.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script>
import MinimalKnob from '$lib/MinimalKnob.svelte';
import Knob from '$lib/ElegantKnob.svelte';
import Options from '$lib/Options.svelte';
import Color from 'colorjs.io';
import {browser} from '$app/env';
Expand All @@ -12,11 +12,13 @@
let value = writable(0);
let darkMode = true;
let color = 'rebeccapurple';
let fontColor = '#fff';
let textColor = '#fff';
let inverseTextColor = '#000';
value.subscribe($value => {
color = gradient($value / 100);
darkMode = $value < 66;
fontColor = darkMode ? '#fff' : '#000';
textColor = darkMode ? '#fff' : '#000';
inverseTextColor = darkMode ? '#000' : '#fff';
if (browser)
document.body.style.background = color;
});
Expand All @@ -30,22 +32,23 @@
</script>


<div class="flex-v" style:color="{fontColor}">
<div class="flex-v" style:color="{textColor}">
<div class="flex-h">
<MinimalKnob
<Knob
label="svelte-dj-knob"
size="10rem"
min="{0}" max="{100}"
bind:value="{$value}"
bgColor="{fontColor}"
fgColor="{knobColor(color)}"
bgColor="{textColor}"
fgColor="{inverseTextColor}"
valueColor="{knobColor(color)}"
/>
</div>
<p>
A knob with usable controls
similar to those in DJ software
</p>
<section style:border-color="{fontColor}">
<section style:border-color="{textColor}">
<heading>Options</heading>
<Options />
</section>
Expand Down

0 comments on commit e8b24b3

Please sign in to comment.