Closed ecstrema closed 4 months ago
Hey thanks and good question!
There's some discussion of this in the Tweakpane repo here and here... the author suggests writing a Tweakpane plugin as the only way to accomplish this "properly".
I'd be happy to add a Tweakpane Plugin that accomplishes this to the Svelte TweakpaneUI library, but I don't think anyone's implemented it yet.
You can get kind of close in Svelte Tweakpane UI be combining a Svelte reactive value with the Slider
component's format
prop to keep the slider's label in sync with the log value, something like this:
<script lang="ts">
import { Slider } from 'svelte-tweakpane-ui';
function logScale(x: number) {
return Math.log10(1 + 99 * x) / Math.log10(100);
}
let linearValue = 1;
$: logValue = logScale(linearValue);
</script>
<Slider
bind:value={linearValue}
min={0}
max={1}
format={(v) => logScale(v).toFixed(2)}
/>
<pre>
{logValue}
</pre>
Example: https://stackblitz.com/edit/vitejs-vite-x6nku5?file=src%2FApp.svelte
But the problem here is that format
only affects the view of the display text input field, not the underlying value, so a number entered directly in the text field will be remapped from a linear to log scale, and appear to change, which feels weird.
The Wheel
and Ring
components have a wide
prop that lets you turn off the text input field, so there's nothing (visible) to keep in sync inside the Tweakpane control itself... but this might only really make sense if you want an exponential scale or something.
(This makes me think that a similar wide
option for the Slider
and IntervalSlider
components might be nice...)
So because of how the slider handle and text input field are coupled inside Tweakpane itself, there's not a great way to completely change the value scale that I can think of, sorry. Let me know if you end up finding an approach that works.
Thanks for the answer! Your solution perfectly fits my case, so I just modified it a bit and ended up with:
<script lang="ts">
let frequencyExponent = 6;
$: frequency = Math.pow(10, frequencyExponent);
</script>
<Slider bind:value={frequencyExponent} label="Frequency" min={0} max={7} format={(value) => Math.pow(10, value).toExponential(1)}/>
And I'm using frequency elsewhere in the app. It works very well, and it's small enough not to require a change in tweakpane or in this repo I believe.
Hey! Awesome library!
I was looking into how to use a logarithmic scale for a slider, and realized it was more involved than listening to on:change and updating the value accordingly.
Do you have any pointers on how to do it?