Back to the index of articles and examples
The following examples of the ProgressBar show several of its features.
The Animation utility has been loaded so all bars move smoothly, otherwise they would respond
immediately to changes in value. The values set in the floating box to the left will
affect all of the bars below. All bars have the properties minValue
and maxValue
left at their default of 0 and 100. Values outside of this range will be ignored.
This is the most plain ProgressBar, it has been created by the following code:
pb = new Y.ProgressBar({contentBox:'#pb',height:'30px', width: 300, barColor:'green', backColor:'orange',border:'thin solid black'}); pb.render();
The contentBox
property tells where to render it.
Size attributes can be given as strings with units specified or numbers which will be interpreted as pixel sizes.
Color attributes can be anything that a CSS color definition would take.
This is a more elaborate version. It was created by the following statements:
pbplain = new Y.ProgressBar({contentBox:'#pbplain'}); pbplain.render();
The shape and colors are the result of style definitions which use the #pbplain
as part of their selector.
#pbplain.yui-progressbar-content { height:25px; } #pbplain .yui-progressbar-mask td { /* if you don't provide a mask, the bar will be a completely rectangular thing with no borders */ background-image: url(mask.gif); } #pbplain .yui-progressbar-bar { /* if you omit the image of the bar, it will be shown as a flat thing of the color given in attribute 'barColor' */ background-image:url(bar.gif); } #pbplain.yui-progressbar-content .yui-progressbar-anim { /* if you omit the image of the bar, it will be shown as a flat thing of the color given in attribute 'barColor' */ background-image:url(animbar.gif); }
In the first one I'm changing the default height, leaving the width to the internal default (200px).
The second definition sets the image that provides the rounded corners to contain the bar.
This image can be stretched and shrunk as needed.
The actual mask.gif
image is 400*32px but here it is shown in 200*25px.
The third definition provides the image to be used for the bar.
It will be tiled to fit the space needed so it needs to be designed with a repeating tileable pattern.
Finally, the last definition provides an image that will be displayed alternatively when the bar
is moving.
The Progress Bar also fires some events when it changes values and also while it changes. Below, you can see the value of the bar above, updated while it is being changed.
This is done with the following code:
var settingEl = Y.get('#setting'); // This one shows it while moving pb.on('changingEvent',function (value) { settingEl.set('innerHTML',value + ' ... moving ...'); }); // This will show at the end (even if there is no animation at all) pb.on('completeEvent',function (value) { settingEl.set('innerHTML', value); });
The bar itself is always a rectangle. To give it different shapes and borders, a mask is used. The mask should be a GIF or PNG file with transparency where you want the bar to show through. The mask can be opaque in the corners and transparent in the center, as in the previous example or you can also play with transparency and opaqueness anywhere in the graphics like the bar above.
The ProgressBar cuts the given mask vertically and horizontally right through the center of it and uses each corner separately. These four sectors slide to and from the center lines. If the mask has a repeating pattern, as this one has, you have to make sure that the width and height given are integer multiples of the basic pattern, otherwise it will not tile correctly. In this example, I have made the width and height one pixel wider and higher than it should have been. If you look at the center, you will see that the holes in the grid on the vertical and horizontal lines coming out from it are different in size from the others
This bar uses a mask that is not symmetrical in any way. It cannot be scaled. If you try to make it any different width, the ruler at the bottom will either have no 5 or have two of them if you shrink it further the 4 and 6 will disappear and so on. The bar, which looks like a wedge, is actually rectangular as it always is. The mask has a wedge-shaped opaque area in the upper-left corner, which is the same color as the page background. The bar is not tiling. The bar is a single image, the bar shows whatever needs of it. Here you have them both over a light gray background with blue borders around the two images:
The mask for this bar has some fancy caps at both top and bottom ends, those blue rounded things at each side.
The bar cannot go from edge to edge of the ProgressBar container because it would hide behind the areas taken
by those caps at the ends. To reserve space for them, we use the margin
CSS attribute given along the image
to be used for the bar, in this case, we are leaving 10 pixels at the left and right ends of the bar:
#pbthin .yui-progressbar-bar { background-image: url(thinbar.gif); margin: 0 10px; }
The bottom of the empty area of the bar is the same silver background as the rest of the area around it, it simply looks deeper than the rest because of the inset shading of the mask.
ProgressBars can grow in any direction, as set by the direction
attribute (case insensitive),
which can take values 'lr'
(left to right, the default), 'rl'
, 'tb'
(top to bottom) or 'bt'
, as in this sample.
If the Animation utility is available, ProgressBar will use it.
The instance of Animation in use is available in the anim
attribute.
You can set the attributes of the animation like duration
or easing
.
This is the code for this bar:
pbcopper = new Y.ProgressBar({contentBox:'#pbcopper',direction:'bt'}); pbcopper.set('anim',{ duration:3, easing:Y.Easing.bounceBoth }); pbcopper.render();
These setting make the bar grow from bottom to top, to last 3 seconds to make any changes and
use the bounceBoth
easing method
The space left blank by the bar is not transparent as in the previous examples. I have set a further background which shows in the 'empty' area. This was set through the following style:
#pbcopper.yui-progressbar-content { background-image:url(copperbackV.gif); }
So, in the end, we have three layered levels in the ProgressBar, assuming we have a ProgressBar with an
id
of pbcopper
as in these case, the CSS selectors for each of the layers,
from bottom up, are:
#pbcopper.yui-progressbar-content
/* The area within the transparent section of the mask not covered by the bar */#pbcopper .yui-progressbar-bar
/* The bar itself */#pbcopper .yui-progressbar-mask td
/* The mask that will let the bar be seen through its transparencies */#pbcopper.yui-progressbar-content .yui-progressbar-anim
The selectors to be used for each of the characteristics of the ProgressBar seem quite random but, actually, have been forced by the way the widget is drawn. Many alternatives to make them as easy as possible have been explored, these are the best choices found.
The ProgressBar supports WAI-ARIA as specified for the "progressbar" role, see: W3C spec.
The ProgressBar container has tabIndex="1"
and has role
and role-specific settings as described in the document.
Since the ProgressBar cannot know what concept the value corresponds to, it cannot, on its own, provide a meaningful aria-valuetext
text. The ariaText
setting allows the implementer to set a text to be used for that setting. The value set should contain a
vertical bar character (|) which will be replaced by the actual value
The ProgressBar has no public properties, all settings are handled through methods get
and set
contentBox
value
minValue
value
below this will be ignoredmaxValue
value
above this will be ignoredbarColor
backColor
border
width
and height
direction
anim
Animation
utility that this ProgressBar uses.
The duration
and easing
setting are the most important to use.barEl
and maskEl
ariaText
aria-valuetext
attribute.
It should contain a vertical bar to be replaced by the current value of the controlrender()
redraw()
destroy()
To make it easy to draw the most basic ProgressBar a few settings relating to presentation are provided. However, the code and presentation of the widget have been kept separate as much as possible. The programmer can write the code independently of the graphics designer. Once a ProgressBar instance is created, the programmer just needs to set the value, all other aspects of the presentation (except direction) can be handled through CSS styles
Selector | Attribute | Description |
---|---|---|
.yui-progressbar-content | width height | overall size of the ProgressBar. Can be set via the width and height configuration settings |
.yui-progressbar-content | background | background to be used on the area the bar is not covering |
.yui-progressbar-bar | background-image background-color | Image or color to use for the bar |
.yui-progressbar-bar | margin | offset from the edge of the ProgressBar to where the mask transparency starts. If the bar goes into this area, it would be hidden behind the mask. |
.yui-progressbar-content .yui-progressbar-anim | background-image background-color | Image or color to use for the bar while it is changing |
.yui-progressbar-mask td | background-image | mask with transparencies to allow the bar to show through |
The diagram to the left shows the layers of the ProgressBar.
The green rectangle is the container which is the base for the whole control. It has the className .yui-progressbar-content
.
The red rectangle is the bar itself, which occupies just part of the container and has className yui-progressbar-bar
.
The blue area is the mask which has a transparent hole that allows the lower layers to be seen and has className yui-progressbar-mask
.
The red bar does not start at the very edge of the container, because it would otherwise be hidden under the borders of the mask. The black vertical lines in between the top and bottom layers show these two do match while the red bar is offset by as much as set in its margin.
The blue mask is not a continuous image but it is made of four sections shown cut by the yellow lines.
This set of diagrams show how the mask image is used. The blue sections enclosed in red at the top two images show a couple of masks of very different sizes, both made of the very same base image, which is shown below.
The red line outlines the table used to hold the mask which is of the same size as the overall ProgressBar. The table is divided in four cells of 50% width and height, marked by the yellow lines.
The same mask image is set as the background for each of the four individual cells but instead of letting it tile normally, we use the background-position CSS attribute so each is aligned to its own corner. The blue area shows the corner section of the mask image that is visible in each cell, enclosed in between the table edge in red and the cell dividers in yellow, the light blue areas are the parts of the same image that fall outside of the cells and are invisible.
If the top ProgressBar were to be stretched a little more, the now invisible edges opposite each visible corner would start to show. On the other hand, if the lower ProgressBar were to be reduced, the yellow lines would start eating into the rounded inner corners and the inner contour would not blend but meet at an angle.
If we call A the length of the straight section of each edge and B the length of the section from the edge until the rounded inner corner meets the straight section so that the width of the original mask is A + 2 * B, we can use that image as a mask for any ProgressBar that is at least 2 * B on the side (no straight section visible) to 2 * A + 2 * B (the straight sections are seen twice, once in each contiguous cell).
Placing the mask in a regular <img> tag would allow for unbound stretching and shrinking by using the width and height attributes. The problem with this approach is that the definition and general appearance of the base image might be altered drastically. Lines 1px wide might become too wide or completely disappear, rounded corners will turn elliptical if stretched unevenly and generally, the image will loose resolution and become distorted.