search

Class myphysicslab.lab.controls.SliderControl

Provided By
All Implemented Interfaces

Creates a 'slider plus textbox' control that displays and modifies the given ParameterNumber. Consists of a label plus a slider and textbox which show the value of the ParameterNumber. Modifying the slider changes the value of the ParameterNumber, as does editting the number in the textbox.

The HTML elements created are wrapped in a DIV. The slider has a classname of 'slider' for CSS scripting. The label is just text within the DIV.

SliderControl takes on discrete values. The value of the SliderControl may only roughly match the value of the ParameterNumber because it can only take on discrete values. In the following sliderIndex means the value of the HTML range element, which is an integer from 0 to increments.

SliderControl can multiply or add a factor to get between increments. If it adds, the relationships are:

delta = (maximum - minimum)/increments
value = minimum + delta*sliderIndex
sliderIndex = Math.floor((value - minimum)/delta)

If it multiplies, the relationships are:

delta = exp((ln(maximum) - ln(minimum)) / increments)
value = minimum * (delta^sliderIndex)
ln(value) = ln(minimum) + sliderIndex*ln(delta)
sliderIndex = (ln(value) - ln(minimum)) / ln(delta)

How It Works

SliderControl takes on discrete values, so what happens when the value it is tracking is between those discrete values? The answer is that SliderControl moves its slider to the nearest position to that value, but does not force the value to match the corresponding discrete value. It is important that when the ParameterNumber is modified by some other entity, the SliderControl does not force the ParameterNumber value to become one of the discrete values it can represent.

There are 3 entities to coordinate: ParameterNumber, textbox, slider. Each has its own notion of the current value; changes can come from any of the 3 entities. The textbox and slider are limited in the values they can represent because of rounding in textbox or increments in slider. Essentially we need to:

  • Distinguish between a genuine change vs. events coming thru as a result of updating a control or ParameterNumber in response to a genuine change (we can call these 'echo events').

  • when a genuine change occurs, update all 3 entities.

The ParameterNumber, and the textbox can take on any value allowed by the ParameterNumber, which are limited by the ParameterNumber's upper and lower limits. If the ParameterNumber takes on a value outside the range of the slider, then the slider will be at its min or max position.

Odd Behavior in Browsers

** Firefox:** In all browsers, clicking in the slider area moves the thumb to that position. In Safari and Chrome, clicking on the thumb does not change the value. But in Safari, clicking on the thumb does 'move to that position' which results in the value changing unexpectedly.

** Chrome:** Does not keep the thumb visually highlighted after clicking it (see doClick2 where we call focus() method on the slider). Other browsers (Safari, Firefox) do keep the thumb highlighted. But it seems the slider still has focus because you can use arrow keys in Chrome, after which the thumb is highlighted. There is a bug about this from 2011: Issue 89698: input type=range should allow keyboard control by default

History

In an earlier version the slider and text box were both contained in a LABEL element. This caused confusion because click events would be passed to the 'for' control. The 'for' control of the LABEL seems to be the first control unless it is explicitly specified. The solution is to not use LABEL for grouping the slider elements, but use a DIV instead.

new SliderControl( parameter, min, max, multiply, increments )

Parameters
parametermyphysicslab.lab.util.ParameterNumber

the ParameterNumber to display and control

minnumber

the minimum value that the parameter can take on

maxnumber

the maximum value that the parameter can take on

multiply(boolean|undefined)

whether the slider increases by multiplying or adding the delta for each step; default is false meaning 'add'

increments(number|undefined)

the number of increments, between max and min, that the value can take on

Instance Methods