| 1 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
|---|
| 2 |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
|---|
| 3 |
|
|---|
| 4 |
<html> |
|---|
| 5 |
<head> |
|---|
| 6 |
<title>Slider (WebFX)</title> |
|---|
| 7 |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
|---|
| 8 |
<script type="text/javascript" src="local/webfxlayout.js"></script> |
|---|
| 9 |
|
|---|
| 10 |
<script type="text/javascript" src="js/range.js"></script> |
|---|
| 11 |
<script type="text/javascript" src="js/timer.js"></script> |
|---|
| 12 |
<script type="text/javascript" src="js/slider.js"></script> |
|---|
| 13 |
<link type="text/css" rel="StyleSheet" href="css/bluecurve/bluecurve.css" /> |
|---|
| 14 |
|
|---|
| 15 |
</head> |
|---|
| 16 |
<body> |
|---|
| 17 |
<!-- WebFX Layout Include --> |
|---|
| 18 |
<script type="text/javascript"> |
|---|
| 19 |
|
|---|
| 20 |
var articleMenu= new WebFXMenu; |
|---|
| 21 |
articleMenu.left = 384; |
|---|
| 22 |
articleMenu.top = 86; |
|---|
| 23 |
articleMenu.width = 140; |
|---|
| 24 |
articleMenu.add(new WebFXMenuItem("Slider", "slider.html")); |
|---|
| 25 |
articleMenu.add(new WebFXMenuItem("Implementation", "implementation.html")); |
|---|
| 26 |
articleMenu.add(new WebFXMenuItem("API", "api.html")); |
|---|
| 27 |
articleMenu.add(new WebFXMenuItem("Demo", "demo.html")); |
|---|
| 28 |
articleMenu.add(new WebFXMenuSeparator); |
|---|
| 29 |
articleMenu.add(new WebFXMenuItem("Download", "http://webfx.eae.net/download/slider102.zip")); |
|---|
| 30 |
webfxMenuBar.add(new WebFXMenuButton("Article Menu", null, null, articleMenu)); |
|---|
| 31 |
|
|---|
| 32 |
webfxLayout.writeTitle("Slider"); |
|---|
| 33 |
webfxLayout.writeMenu(); |
|---|
| 34 |
webfxLayout.writeDesignedByEdger(); |
|---|
| 35 |
|
|---|
| 36 |
</script> |
|---|
| 37 |
<div class="webfx-main-body"> |
|---|
| 38 |
<!-- end WebFX Layout Includes --> |
|---|
| 39 |
|
|---|
| 40 |
<h2>Implementation</h2> |
|---|
| 41 |
|
|---|
| 42 |
<p>The slider implementation mostly consists of lots of event handlers that |
|---|
| 43 |
sets the value depending on the event arguments.</p> |
|---|
| 44 |
|
|---|
| 45 |
<h3>Range</h3> |
|---|
| 46 |
|
|---|
| 47 |
<p>The data model is handled by a class called Range (also known as BoundedRangeModel). |
|---|
| 48 |
This class has a few properties that fits perfectly with sliders, scrollbars and |
|---|
| 49 |
progress bars. A range has a minimum value, a value, an extent and a maximum value. |
|---|
| 50 |
The following is always true for a range object.</p> |
|---|
| 51 |
|
|---|
| 52 |
<pre> |
|---|
| 53 |
minimum < value < value + extent < maximum |
|---|
| 54 |
</pre> |
|---|
| 55 |
|
|---|
| 56 |
<p>In the case of a slider the extent is always zero. Using a range for the data |
|---|
| 57 |
model allows the implementation of the slider to concentrate on other things than |
|---|
| 58 |
ensuring that the data model is valid.</p> |
|---|
| 59 |
|
|---|
| 60 |
<h3>Timer</h3> |
|---|
| 61 |
|
|---|
| 62 |
<p>For this implementation of the slider I decided to use an object oriented |
|---|
| 63 |
abstraction of <code>window.setTimeout</code>. A timer from the <code>Timer</code> |
|---|
| 64 |
class can be started and stopped and it fires a pseudo event called <code>ontimer</code> |
|---|
| 65 |
a certain amount of milliseconds after the timer is started.</p> |
|---|
| 66 |
|
|---|
| 67 |
<pre> |
|---|
| 68 |
Timer.prototype.start = function () { |
|---|
| 69 |
if (this.isStarted()) |
|---|
| 70 |
this.stop(); |
|---|
| 71 |
var oThis = this; |
|---|
| 72 |
this._timer = window.setTimeout(function () { |
|---|
| 73 |
if (typeof oThis.ontimer == "function") |
|---|
| 74 |
oThis.ontimer(); |
|---|
| 75 |
}, this._pauseTime); |
|---|
| 76 |
this._isStarted = false; |
|---|
| 77 |
}; |
|---|
| 78 |
|
|---|
| 79 |
Timer.prototype.stop = function () { |
|---|
| 80 |
if (this._timer != null) |
|---|
| 81 |
window.clearTimeout(this._timer); |
|---|
| 82 |
this._isStarted = false; |
|---|
| 83 |
}; |
|---|
| 84 |
</pre> |
|---|
| 85 |
|
|---|
| 86 |
<h3>Slider</h3> |
|---|
| 87 |
|
|---|
| 88 |
<p>The slider consists of a line element and a handle element. The line is only |
|---|
| 89 |
there for the visual effect. The handle on the other hand can be dragged and |
|---|
| 90 |
thereby changing the value. When dragging the handle the position of the mouse |
|---|
| 91 |
is used to calculate a new value for the data model. Once the value is changed |
|---|
| 92 |
the layout for the slider is recalculated.</p> |
|---|
| 93 |
|
|---|
| 94 |
<p>When the user holds down the mouse on the slider, but not on the handle, a |
|---|
| 95 |
timer is started and every time the timer triggers the <code>timer</code> event |
|---|
| 96 |
the value is changed by the <code>blockIncrement</code> towards the mouse |
|---|
| 97 |
pointer.</p> |
|---|
| 98 |
|
|---|
| 99 |
<p>The slider also allows the user to use the keyboard to change the value. This |
|---|
| 100 |
is done by listening to the <code>keydown</code> (and <code>keypress</code>) |
|---|
| 101 |
events. In the <code>keydown</code> handler the key is checked and the value for |
|---|
| 102 |
the data model is updated accordingly. The reason for the <code>keypress</code> |
|---|
| 103 |
handler is to disable the default actions in the browser.</p> |
|---|
| 104 |
|
|---|
| 105 |
<p> |
|---|
| 106 |
<a href="slider.html">Slider</a><br /> |
|---|
| 107 |
<a href="implementation.html">Implementation</a><br /> |
|---|
| 108 |
<a href="api.html">API</a><br /> |
|---|
| 109 |
<a href="demo.html">Demo</a><br /> |
|---|
| 110 |
<a href="http://webfx.eae.net/download/slider102.zip">Download</a> |
|---|
| 111 |
</p> |
|---|
| 112 |
|
|---|
| 113 |
<p class="author">Author: Erik Arvidsson</p> |
|---|
| 114 |
|
|---|
| 115 |
<!-- end webfx-main-body --> |
|---|
| 116 |
</div> |
|---|
| 117 |
|
|---|
| 118 |
</body> |
|---|
| 119 |
</html> |
|---|