Artists' Meter for I/O

© 2012, Martin Rinehart

Recommended display device: content creation, 700+ pixel width preferred.

You may recognize the meters on the left from the Meter UI page. This time they have handles as they are input meters. If you haven't tried them yet, slide their handles up and down. The horizontal output meters to their right have been connected to show the values you select.

On the right, a horizontal meter shows that you can also use horizontal meters for user input. Slide its handle and the vertical meter to its right shows your selection with its crosshair handle. (This also shows that a handle can be used as a pointer on an output meter.)

These are samples of our Meter UI used behind our own meters. If you are not using a meter-enabled library, ours has a very low byte cost.


Frontend Engineers Notes

We try to provide optional defaults at every step of the meter construction process. For example:

var my_meter = new Meter();

That gets a plain meter in ghostly light colors, at 0, 0. It is 300 pixels wide, 50 tall. We provide this starter so that you have some feedback during development. Next we add our first property, a Rect object that specifies position (left, top) and size (width, height). You now have a Meter that you can see, hopefully showing in your page where you want.

You then style your meter (borders, backgrounds and such) to your liking (or your design specs or, if your designer is working with you, to his or her requests). Any CSS, including CSS3 is fine. (We do code, not miracles. IE8 still can't do borderRadius.)

Continue to add and style a specific bar in the meter's center, end caps for the bar if you like, tic marks, and so on. Now you want to convert your meter UI into an actual output meter, showing a split bar. You add this to your specs object:

    split_bar: {
        color_low: '#a0a0a0',
        color_high: 'white'
    },

Voila! You now have a progress-type meter, gray on the left and white on the right. You give it a data array:

data: [ min, max, value ]

Unless, as always, you like the default ([ 0, 100, 50]). In your JavaScript you find your source for this meter's values and you connect it with: my_meter.set_value( new_value );.

For a draggable handle on an input meter, you specify handle: true, in your specs object. That gets you a default handle. To get a mouse listener that will take care of moving the handle when the visitor drags it, you need a listener: listener: true,. If you don't want the default handle (which will, after all, look like every other default handle) you can specify a custom Handle object (size, colors) and pick one of our drawing functions, or write your own custom draw function.

The mouse listener calls a callback function as the handle is dragged. The default callback just takes care of moving the handle. You can provide your own. Note: the listener calls the callback with a simplified, cross-browser-ized mouse event object. Here is the custom callback that hooks our top-left vertical meter to h1, the horizontal output meter to its right:

callback: function ( event ) {
	this.handle.move_to(
		event.x, event.y );
	h1.set_value(
		this.event_2_value(event) );
},

(Yes, the Meter object provides the event_2_value() method for you.)

We can't claim that there's no learning curve, but at every step of the way there's a constructor that is happy to provide you with what you need. Time for tic marks? Add a TicSet. Time for major and minor tics? Add a second TicSet. If you look closely at that meter in the lower-left, you'll see major, minor and tertiary tic marks. As you might guess, all it takes is adding a third TicSet.

Do you want to label the major tics? Add an optional true argument to the TicSet constructor. Want to style the labels and add a decimal place? There's a LabelSpecs object for that. (Look at the thermometer on the Meters UI page. It's got Celsius added on the left.).

So, there's no reason to wait for HTML5, which may not be a full solution for many years. Input and output meters are here today.


Feedback: MartinRinehart at gmail dot com

# # #