The objective: Create a slider that, when displaced from the center, increases-decreases the value of another variable at a rate proportional to the displacement.

So, I create a slider that automatically comes back to the center

Slider[Dynamic[var, {(var = #) &, (var = 0.) &}], {-1, 1}]

Now I want a second variable to be dynamically increased/decreased when var!=0.

My ideas are:

  1. insert in the previous dynamic, something that does the updating
  2. use an animator with its speed set by var when var!=0. that updates the value

Problems with the above:

  1. How to control the speed of the updating given that I can't know for sure the intervals in which val will be updated, and UpdateIntervals sets an upper bound?
  2. How to make it work without it showing in the screen?

Any other alternatives are welcome (ideally I'd like an elegant solution).

  • $\begingroup$ @R.M, hope this pings you. Heike's answer shows my intentions clearly. Now that Dynamic[y, {y=g[x]}] I wasn't aware of. I thought the second argument was supposed to be a function and that they only made sense when the dynamic was "being set by a control". What does it do? $\endgroup$ – Rojo Jun 3 '12 at 19:04

Maybe you could do something like this,

var = 0.; p = 0.; interval = .2;
task = RunScheduledTask[p += var, interval];
{Slider[Dynamic[var, {(var = #) &, (var = 0.) &}], {-1, 1}], Dynamic[p]}

The downside is that rather than increasing p by a fixed amount at variable time intervals, this increases p by a variable amount at a fixed frequency. Also, you need to remember to remove task (using RemoveScheduledTask) once you're done with it.

| improve this answer | |
  • $\begingroup$ I think this is probably a good-enough approach. +1, thanks. I'll be waiting for other options for a while to accept. One could add the run and remove scheduled tasks in the second argument of the slider's dynamic, right? So that only when dragged the task exists $\endgroup$ – Rojo Jun 3 '12 at 19:02
  • $\begingroup$ You could also create it once and use StartScheduledTask and StopScheduledTask in the second argument of Dynamic to start and stop it. $\endgroup$ – Heike Jun 3 '12 at 19:14
  • $\begingroup$ Makes sense. Create it in Initialization and remove it in Deinitialization $\endgroup$ – Rojo Jun 3 '12 at 19:15

Here's another way using Refresh that's perhaps a bit cleaner:

DynamicModule[{x = 0, y = 0},
    {Slider[Dynamic[x, {(x = #) &, (x = 0.) &}], {-1, 1}], 
     Dynamic[Refresh[y += x, TrackedSymbols :> {}, UpdateInterval -> 0.1]]}
| improve this answer | |
  • $\begingroup$ +1. I took it and turned the second dynamic into the second argument of a DynamicWrapper so it becomes what I wanted: just a slider that does the updating. DynamicWrapper[Slider..., Refresh[...]] $\endgroup$ – Rojo Jun 3 '12 at 19:57
  • $\begingroup$ This is way neater, but for some reason I don't understand, Heike's solution allows me to put lower update intervals before it gets way slower than it should $\endgroup$ – Rojo Jun 3 '12 at 20:01
  • $\begingroup$ Interesting... didn't notice that $\endgroup$ – rm -rf Jun 3 '12 at 20:12
  • $\begingroup$ @Rojo, R.M: This is beautiful and elegant, nice use of Refresh & DynamicWrapper! $\endgroup$ – István Zachar Jun 4 '12 at 11:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.