AS3: SliderUI v1.5
View Example
View Documentation
Download Class & Example Files
I've updated the SliderUI class to add some more features. There is now a custom SliderUIEvent being dispatched, a setter method for the currentValue and percent properties which automatically moves the sliders to their appropriate spots when these are set, and a precision parameter passed into the constructor which allows you to round the currentValue off to the nearest "nth".
-
package com.reintroducing.ui
-
{
-
import flash.display.Sprite;
-
import flash.display.Stage;
-
import flash.events.EventDispatcher;
-
import flash.events.MouseEvent;
-
import flash.events.TimerEvent;
-
import flash.geom.Rectangle;
-
import flash.utils.Timer;
-
import flash.utils.getQualifiedClassName;
-
-
import com.reintroducing.events.SliderUIEvent;
-
-
/**
-
* The SliderUI is a class that allows you to quickly create sliders with tracks without the need to use components.
-
* There is a "percent" and a "currentValue" property that you can tap into to see what position the slider is at on the track.
-
* The SliderUI dispatches a couple of custom events that also contain these values as well as the slider and track display objects.
-
* <ul>
-
* <li>SliderUIEvent.ON_PRESS - Dispatched when the slider is pressed</li>
-
* <li>SliderUIEvent.ON_RELEASE - Dispatched when the slider is released</li>
-
* <li>SliderUIEvent.ON_UPDATE - Dispatched while the slider is dragged</li>
-
* <li>SliderUIEvent.ON_ENABLED - Dispatched when the slider is enabled</li>
-
* <li>SliderUIEvent.ON_DISABLED - Dispatched when the slider is disabled</li>
-
* </ul>
-
* </ p>
-
* Please note that if you are using the SliderUI on the "y" axis your track's registration point needs to be on the
-
* bottom (NOT the top) and the slider will go up to raise the value and down to lower it. If you do not pay attention
-
* to this your slider will be "broken".
-
*
-
* @author Matt Przybylski [http://www.reintroducing.com]
-
* @version 1.5
-
*/
-
public class SliderUI extends EventDispatcher
-
{
-
//- PRIVATE & PROTECTED VARIABLES -------------------------------------------------------------------------
-
-
private var _stage:Stage;
-
private var _track:Sprite;
-
private var _slider:Sprite;
-
private var _timer:Timer;
-
private var _percent:Number;
-
private var _lowVal:Number;
-
private var _highVal:Number;
-
private var _startVal:Number;
-
private var _currentVal:Number;
-
private var _range:Number;
-
private var _axis:String;
-
private var _changeProp:String;
-
private var _precision:int;
-
-
//- PUBLIC & INTERNAL VARIABLES ---------------------------------------------------------------------------
-
-
-
-
//- CONSTRUCTOR -------------------------------------------------------------------------------------------
-
-
/**
-
* Creates an instance of the SliderUI with the given parameters. If the $startVal parameter is set to something
-
* higher than the $highVal or lower than the $lowVal parameter, the $startVal parameter is reset to one of those two values.
-
* If you do not set the $precision parameter, your current value will be rounded to the nearest whole number and the slider
-
* will snap into place at the appropriate position on the track.
-
*
-
* @param $stage The stage that the track and slider are sitting on
-
* @param $axis The axis that the slider will be used on
-
* @param $track The track to be used for the slider
-
* @param $slider The object that will function as the slider
-
* @param $lowVal A number representing the low value of the slider
-
* @param $highVal A number representing the high value of the slider
-
* @param $startVal A number representing the value the slider should start at (default: 0)
-
* @param $precision An integer representing the number of decimal places to round the current value to (default: 0)
-
*
-
* @return void
-
*/
-
public function SliderUI($stage:Stage, $axis:String, $track:Sprite, $slider:Sprite, $lowVal:Number, $highVal:Number, $startVal:Number = 0, $precision:int = 0):void
-
{
-
this._stage = $stage;
-
this._axis = $axis;
-
this._track = $track;
-
this._slider = $slider;
-
this._lowVal = $lowVal;
-
this._highVal = $highVal;
-
this._startVal = $startVal;
-
this._precision = $precision;
-
-
this._changeProp = (this._axis == "x") ? "width" : "height";
-
this._range = (Math.abs(this._lowVal) + this._highVal);
-
this._timer = new Timer(10);
-
-
if (this._startVal <this._lowVal) this._startVal = this._lowVal;
-
if (this._startVal> this._highVal) this._startVal = this._highVal;
-
-
this.manageRestingPosition(this._startVal);
-
this.initEvents();
-
}
-
-
//- PRIVATE & PROTECTED METHODS ---------------------------------------------------------------------------
-
-
// Initializes the slider and timer events.
-
private function initEvents():void
-
{
-
this._slider.buttonMode = true;
-
-
this._slider.addEventListener(MouseEvent.MOUSE_DOWN, handleMouseDown);
-
this._slider.addEventListener(MouseEvent.MOUSE_UP, handleMouseUp);
-
this._timer.addEventListener(TimerEvent.TIMER, updateInfo);
-
}
-
-
// manages the resting position depending on what value is passed in
-
private function manageRestingPosition($val:Number):void
-
{
-
if ($val <0)
-
{
-
this._percent = (Math.abs(this._lowVal + Math.abs($val)) / this._range);
-
}
-
else
-
{
-
this._percent = (Math.abs(this._lowVal - $val) / this._range);
-
}
-
-
this._currentVal = this.roundToPrecision((this._lowVal + (this._range * this._percent)), this._precision);
-
-
if (this._axis == "x")
-
{
-
this._slider[this._axis] = (this._track[this._axis] + (this._percent * this._track[this._changeProp]));
-
}
-
else
-
{
-
this._slider[this._axis] = (this._track[this._axis] - (this._percent * this._track[this._changeProp]));
-
}
-
}
-
-
//- PUBLIC & INTERNAL METHODS -----------------------------------------------------------------------------
-
-
/**
-
* Enables the controls of the SliderUI.
-
*
-
* @return void
-
*/
-
public function enable():void
-
{
-
this.initEvents();
-
-
this.dispatchEvent(new SliderUIEvent(SliderUIEvent.ON_ENABLED, this._percent, this._currentVal, this._slider, this._track));
-
}
-
-
/**
-
* Disables the controls of the SliderUI.
-
*
-
* @return void
-
*/
-
public function disable():void
-
{
-
this._slider.buttonMode = false;
-
-
this._slider.removeEventListener(MouseEvent.MOUSE_DOWN, handleMouseDown);
-
this._slider.removeEventListener(MouseEvent.MOUSE_UP, handleMouseUp);
-
this._timer.removeEventListener(TimerEvent.TIMER, updateInfo);
-
-
this.dispatchEvent(new SliderUIEvent(SliderUIEvent.ON_DISABLED, this._percent, this._currentVal, this._slider, this._track));
-
}
-
-
/**
-
* Cleans up the SliderUI for garbage collection.
-
*
-
* @return void
-
*/
-
public function destroy():void
-
{
-
this.disable();
-
-
this._timer = null;
-
}
-
-
//- EVENT HANDLERS ----------------------------------------------------------------------------------------
-
-
// Starts the dragging of the slider and starts the timer to dispatch percentage.
-
private function handleMouseDown($evt:MouseEvent):void
-
{
-
this.dispatchEvent(new SliderUIEvent(SliderUIEvent.ON_PRESS, this._percent, this._currentVal, this._slider, this._track));
-
-
if (this._axis == "x")
-
{
-
this._slider.startDrag(false, new Rectangle(this._track.x, this._slider.y, this._track.width, 0));
-
}
-
else
-
{
-
this._slider.startDrag(false, new Rectangle(this._slider.x, this._track.y, 0, -this._track.height));
-
}
-
-
this._timer.start();
-
this._stage.addEventListener(MouseEvent.MOUSE_UP, handleMouseUp, false, 0, true);
-
}
-
-
// Stops the slider dragging and timer.
-
private function handleMouseUp($evt:MouseEvent):void
-
{
-
this.dispatchEvent(new SliderUIEvent(SliderUIEvent.ON_RELEASE, this._percent, this._currentVal, this._slider, this._track));
-
-
this._slider.stopDrag();
-
this._timer.reset();
-
-
this.manageRestingPosition(this._currentVal);
-
-
this._stage.removeEventListener(MouseEvent.MOUSE_UP, handleMouseUp);
-
}
-
-
// Updates the info of the slider's position.
-
private function updateInfo($evt:TimerEvent):void
-
{
-
this._percent = Math.abs((this._slider[this._axis] - this._track[this._axis]) / this._track[this._changeProp]);
-
this._currentVal = this.roundToPrecision((this._lowVal + (this._range * this._percent)), this._precision);
-
-
this.dispatchEvent(new SliderUIEvent(SliderUIEvent.ON_UPDATE, this._percent, this._currentVal, this._slider, this._track));
-
}
-
-
//- GETTERS & SETTERS -------------------------------------------------------------------------------------
-
-
/**
-
* Returns the percentage of the slider's position on the track, between 0 and 1.
-
*
-
* @return Number
-
*/
-
public function get percent():Number
-
{
-
return this._percent;
-
}
-
-
/**
-
* Sets the slider's percentage according to the one provided and physically moves it to the corresponding position on the track.
-
*
-
* @param $val The value to set the percentage to.
-
*
-
* @return void
-
*/
-
public function set percent($val:Number):void
-
{
-
this._percent = $val;
-
-
this.manageRestingPosition(this._percent);
-
}
-
-
/**
-
* Returns the current value of the slider's position on the track.
-
*
-
* @return Number
-
*/
-
public function get currentValue():Number
-
{
-
return this._currentVal;
-
}
-
-
/**
-
* Sets the slider's current value according to the one provided and physically moves it to the corresponding position on the track.
-
*
-
* @param $val The value to set the currentValue to.
-
*
-
* @return void
-
*/
-
public function set currentValue($val:Number):void
-
{
-
this._currentVal = $val;
-
-
this.manageRestingPosition(this._currentVal);
-
}
-
-
//- HELPERS -----------------------------------------------------------------------------------------------
-
-
private function roundToPrecision($num:Number, $precision:int = 0):Number
-
{
-
var decimalPlaces:Number = Math.pow(10, $precision);
-
return (Math.round(decimalPlaces * $num) / decimalPlaces);
-
}
-
-
override public function toString():String
-
{
-
return getQualifiedClassName(this);
-
}
-
-
//- END CLASS ---------------------------------------------------------------------------------------------
-
}
-
}
I've updated the example as well to show the usage of the new events. Please view the documentation for details on all the changes.
If you found this post useful, please consider leaving a comment, subscribing to the feed, or making a small donation.
14 Comments
Simple, straightforward and small. It's sort of a code haiku.
I am considering setting up a snap-to-value option. I'll send you the code if I succeed.
mcubebrooklyn,
if i'm not mistaken, i think what you're trying to achieve is already implemented. it snaps to the value you put in with the precision param in the constructor.
Hey, great tool here, thanks for posting it. However, I have run into a small problem that I have searched and searched for but cannot solve.
It appears that when I create the slider sprites programmatically, the thumb sprite is movable beyond the boundary of the track. (By the height of the thumb sprite.) Here is my code:
-----------------------------------------------------
import com.reintroducing.ui.SliderUI;
import com.reintroducing.events.SliderUIEvent;
// SLIDER TRACK
var volTrack:Sprite = new Sprite();
volTrack.graphics.lineStyle(1,0xAAAAAA);
volTrack.graphics.beginFill(0x222222);
volTrack.graphics.drawRect(0,0,20,-100);
volTrack.graphics.endFill();
volTrack.x = stage.stageWidth / 2;
volTrack.y = stage.stageHeight / 2;
// SLIDER BOX
var volSlider:Sprite = new Sprite();
volSlider.graphics.beginFill(0xCCCCCC);
volSlider.graphics.drawRect(0,0,19,-10);
volSlider.graphics.endFill();
volSlider.x = (stage.stageWidth / 2) + 1;
//volSlider.y = (stage.stageHeight / 2) - 10;
addChild(volTrack);
addChild(volSlider);
// CONFIGURE SLIDERS
var volSliderObj:SliderUI = new SliderUI(stage, "y", volTrack, volSlider, 0, 100, 75);
--------------------------------------------------
Am I missing some obvious?
Thanks for any help!
@fodder: The SliderUI is designed to go from the middle of the slider, not an edge, on the track. therefore you'd want to move your y axis point in the drawRect function for volSlider up a bit, as shown here:
-
import com.reintroducing.ui.SliderUI;
-
import com.reintroducing.events.SliderUIEvent;
-
-
// SLIDER TRACK
-
var volTrack:Sprite = new Sprite();
-
volTrack.graphics.lineStyle(1,0xAAAAAA);
-
volTrack.graphics.beginFill(0x222222);
-
volTrack.graphics.drawRect(0,0,20,-100);
-
volTrack.graphics.endFill();
-
volTrack.x = stage.stageWidth * .5;
-
volTrack.y = stage.stageHeight * .5;
-
-
// SLIDER BOX
-
var volSlider:Sprite = new Sprite();
-
volSlider.graphics.beginFill(0xCCCCCC);
-
volSlider.graphics.drawRect(0,-5,19,10);
-
volSlider.graphics.endFill();
-
volSlider.x = (stage.stageWidth * .5) + 1;
-
volSlider.y = (stage.stageHeight * .5);
-
-
addChild(volTrack);
-
addChild(volSlider);
-
-
// CONFIGURE SLIDERS
-
var volSliderObj:SliderUI = new SliderUI(stage, "y", volTrack, volSlider, 0, 100, 75);
hope this helps.
@Matt:
Thanks so much for the help! I was assuming that I was just missing a way to specify padding or bounds on each slider.
Your explanation pointed me in the right direction and now I am just creating a separate track (set to alpha = 0) that I can adjust the dimensions to make the slider bounds fit inside my background.
Thanks again!
This class really is great. Thanks for creating it.
I am somewhat new to as3 so I apologize if this is a newb question, but I have an issue regarding the stage parameter.
I have a working volume slider using version 1.51.
When I load the swf with the slider into another, I get the "Cannot access a property or method of a null object reference" on the SliderUI/handleMouseDown() and SliderUI/handleMouseUp() methods.
Now the slider still seems to operate properly, but I was wondering if there was something other than 'stage' I should be sending into the constructor in these cases to avoid that output error.
Thanks again. Awesome class!
@Dan: It sounds like the stage is not yet initialized before creating your instance of the sliderUI. Make sure that wherever you're adding the instance, that class (if it extends a display object of some type) is being initialized on ADDED_TO_STAGE or something similar. hope that helps.
[...] Es gibt die Schieberegler-Klasse auch in der Version SliderUI v1.5. Die neue Version beinhaltet u.A. ein Flash-CustomEvent, was z.B. bei unserer Anwendung zum Einsatz [...]
Thanks for posting this! We adapted the SliderUI v1.51 to work within the GestureWorks AS3 framework for a multitouch application (see previous pingback post in German). Works great!













Thanks for posting this!