The first step was to find a good mockup for the Knob. I found it here:
UIParade. I could not find
the psd for the image, so I just copied the image.
The next step was to remove the arrow on the image, since the position of the
arrow depends on the value of the knob. So I opened the image in Gimp and used
the clone tool to remove the arrow. In the component, am creating the arrow
using pure css. Also, there is a lot of empty space on the left and right side
of the knob image, so I croped it and made it smaller. The final image looked
like this:
Next, I need to put this in a html page. So the basic strucure I decided to use
is 3 div stacked on top of each other. The bottom most div will have the knob
image as background-image. The middle div will be a transparent div with just
the arrow. And a third empty div which will simply server the purpose of
receiving input(mouse and wheel).
Now, when you want to change the position of the arrow, you simply use
css transform: rotate on div2. I decided that the knob component will
always return value in the range 0 - 1, just like Math.random. This
reduces calculation complexity of the component and is still generic enough
to be used with any number range.
If you look at the image, at the max, you can turn the knob to about 270 degrees.
This means, any value between 0-1 needs to be mapped to 0-270 degrees. The
formula is simple:
degrees = value * 270
So, say the value is 0.5, we put transform: rotate(135deg) css on Div2. To
make the rotation a smooth animation, we simply add transition: transform 0.25s
css on it. These steps happen when we set the value of the knob programatically.
The knob value setter implements this code. The code looks like this:
Now comes the tricky part, when user changes values of the knob using mouse.
The user will hold the arrow and drag it in a circlular motion. As it turns out,
this is really very simple with some basic geometry. This is where Div3 comes
into the picture. I have setup the mousedown, mousemove and mouseup on
div3. Whenever the user clicks and drags the mouse, we simply need to measure
the angle the mouse makes with the x-axis. The x-axis is at the center of div3.
Refer the image below:
Creating the Knob component
The working example can be seen here
The first step was to find a good mockup for the Knob. I found it here: UIParade. I could not find the psd for the image, so I just copied the image.
The next step was to remove the arrow on the image, since the position of the arrow depends on the value of the knob. So I opened the image in Gimp and used the clone tool to remove the arrow. In the component, am creating the arrow using pure css. Also, there is a lot of empty space on the left and right side of the knob image, so I croped it and made it smaller. The final image looked like this:
Next, I need to put this in a html page. So the basic strucure I decided to use is 3
div
stacked on top of each other. The bottom most div will have the knob image asbackground-image
. The middle div will be a transparent div with just the arrow. And a third empty div which will simply server the purpose of receiving input(mouse and wheel).Now, when you want to change the position of the arrow, you simply use css
transform: rotate
ondiv2
. I decided that the knob component will always return value in the range 0 - 1, just likeMath.random
. This reduces calculation complexity of the component and is still generic enough to be used with any number range.If you look at the image, at the max, you can turn the knob to about 270 degrees. This means, any value between 0-1 needs to be mapped to 0-270 degrees. The formula is simple:
So, say the value is 0.5, we put
transform: rotate(135deg)
css on Div2. To make the rotation a smooth animation, we simply addtransition: transform 0.25s
css on it. These steps happen when we set the value of the knob programatically. The knobvalue
setter implements this code. The code looks like this:Now comes the tricky part, when user changes values of the knob using mouse. The user will hold the arrow and drag it in a circlular motion. As it turns out, this is really very simple with some basic geometry. This is where Div3 comes into the picture. I have setup the
mousedown
,mousemove
andmouseup
on div3. Whenever the user clicks and drags the mouse, we simply need to measure the angle the mouse makes with the x-axis. The x-axis is at the center of div3. Refer the image below:The angle (theta) is calculate as:
Once we get the angle, converting it to value is trivial using the formula we described earlier.
Once we get the value, we simple call the knob
value
setter which in turn rotates div2. This completes the illusion of rotating the Knob.The entire code can be see here.