Oi, isto ñ é bem o local para colocar isto mas talvez onde mais se adapta.
Recentemente escrevi uma classe para um projecto que gera uma scrollbar dinamicamente para um dado movieclip.
A intenção deste post é que a possam experimentar, dar o vosso feedback e contributo para a melhorar.
Existem algumas coisas que gostava de acrescentar, como utilizar a roda do rato,etc.
Aqui fica então.
/**
* ::Scroll Bar Class v0.2:: by Nuno Rosa (17, July, 2007) (nuno.rosa gmail com)
*
*Use this class to create a scroll bar from a given movieclip, the mask pane is created dynamically.
*There are some costumizations that you could make via setters methods.
*USAGE:
import com.yarcub.ui.ScrollBar;
var s:ScrollBar = new ScrollBar(this,myMc);
s.height = 200; //Mask&Scroll height
s.barWidth = 10; //Scroll bar width
s.blur = 0.5; //BlurY factor
s.speed = 0.8; //Speed factor
s.offset = 20; //Distance between scroll pane and scroll bar
s.color1 = 0xFFFF66; //Primary Color
s.color2 = 0xFF0000; //Secundary Color
s.onChange = function(mc:MovieClip){
trace(mc+" content changed.");
}
s.create(); //Create the gfx
//use the s.render() if the content dimension change.
*/
import mx.utils.Delegate;
import flash.filters.BlurFilter;
class com.yarcub.ui.ScrollBar{
//Config
private var __target:Object;
private var __height:Number;
private var __swidth:Number;
private var __blur:Number;
private var __color1:Number;
private var __color2:Number;
private var __offset:Number;
private var __speed:Number;
//this array keeps track of every ScrollBar instance created
static public var __instances:Array;
static private var __mouseLstnr:Object;
//internal
private var __width:Number;
private var __ref:Object;
private var __mask:MovieClip;
private var __holder:MovieClip;
private var __line:MovieClip;
private var __bar:MovieClip;
private var __scrollFactor:Number;
private var __yFactor:Number;
private var __yStart:Number;
private var __yFinal:Number;
private var __maxDist:Number;
//Callbacks
public var onInit:Function;
public var onChange:Function;
/**
*Class Constructor
* @param ref where the target is located
* @param target reference of the MovieClip/TextField we want to attach the scrollbar
*/
function ScrollBar(ref:Object, target:Object){
__target = target;
__ref = ref;
__width = __target._width;
__yStart = __target._y;
if(__target==undefined || __ref==undefined){
trace("Error: You need to pass the target and stage reference in the contructor");
}else{
init();
}
}
/**
* Attach the scrollbar to the content.
* Just need to call it once.
*/
public function create():Void{
if(__holder!=undefined){
trace("Grafic instances already exist, use the render() to update grafics");
return;
}
__scrollFactor = Math.ceil((__height/(__target._height))*100)/100;
__maxDist = (__height - __height*__scrollFactor);
var i:Number = __ref.getNextHighestDepth();
__holder = __ref.createEmptyMovieClip("holder"+i,i);
__holder._x = __target._x + __width+__offset;
__holder._y = __yStart;
if(__scrollFactor>=1){
__holder._visible = false;
}else{
__holder._visible = true;
}
drawMask();
drawLine();
drawBar();
}
/*Render the scroll bar
* If the content we're scrolling changes their width/height use this method
* to re-render the scrollbar gfx
* @return nothing
*/
public function render():Void{
__scrollFactor = Math.ceil((__height/(__target._height))*100)/100;
__maxDist = (__height - __height*__scrollFactor);
__yFactor = (__target._height-__height)/__maxDist;
if(__scrollFactor>=1){
__holder._visible = false;
}else{
__holder._visible = true;
__bar.clear();
__bar.lineStyle(1, __color2);
__bar.beginFill(__color1);
__bar.lineTo(__swidth,0);
__bar.lineTo(__swidth,__scrollFactor*__height);
__bar.lineTo(0,__scrollFactor*__height);
__bar.lineTo(0,0);
__bar.endFill();
}
this.onChange(__target); //Content changed Callback;
}
/********************************************************
* Getters/Setters
* *******************************************************/
/**
* @param h height of the scroll pane (Default:100)
*/
public function set height(h:Number):Void{
__height = h;
}
/**
* @param w width of the scroll bar (Default:20)
*/
public function set barWidth(w:Number):Void{
__swidth = w;
}
/**
* @param b blur distance factor (Default:1)
*/
public function set blur(b:Number):Void{
__blur = b/10;
}
/**
* @param o distance between scroll pane and scroll bar (Default:20)
*/
public function set offset(o:Number):Void{
__offset = o;
}
/**
* @param c primary color (Default:0x000000)
*/
public function set color1(c:Number):Void{
__color1 = c;
}
/**
* @param c secondary color (Default:0xFFFFFF)
*/
public function set color2(c:Number):Void{
__color2 = c;
}
/**
* @param s spped (Default:0.4)
*/
public function set speed(s:Number):Void{
__speed = s;
}
/********************************************************
* Mouse Handlers
* *******************************************************/
private function press():Void{
startDrag(__bar,false,0,0,0,__maxDist);
__bar.onMouseMove = Delegate.create(this,updateFinalPosition);
}
private function release():Void{
delete __bar.onMouseMove;
stopDrag();
}
private function pressLine():Void{
var newY:Number = __holder._ymouse
//see if we click upper or downer the handler
var orientation:Number = __bar._y-newY
if(orientation>0){
__bar._y = newY;
}else{
__bar._y = newY - __bar._height;
}
updateFinalPosition();
}
private function updateFinalPosition():Void{
__yFinal = __yStart - __bar._y*__yFactor;
updateAfterEvent();
}
/********************************************************
* Private Methods
* *******************************************************/
private function init():Void{
//Set the Default Propertie Values
__height = 100;
__swidth = 20;
__blur = 0.1;
__offset = 20;
__color1 = 0x000000;
__color2 = 0xFFFFFF;
__speed = 0.4;
}
private function drawMask():Void{
var i:Number = __ref.getNextHighestDepth();
__mask = __ref.createEmptyMovieClip("mask"+i, i);
__mask._y = __target._y; __mask._x = __target._x;
__mask.beginFill(0x000000, 100);
__mask.lineTo(__width, 0);
__mask.lineTo(__width, __height);
__mask.lineTo(0, __height);
__mask.lineTo(0, 0);
__mask.endFill();
__target.setMask(__mask);
}
private function drawLine():Void{
var i:Number = __holder.getNextHighestDepth();
__line = __holder.createEmptyMovieClip("line"+i,i);
__line.lineStyle(1, __color1);
__line.beginFill(__color2)
__line.lineTo(__swidth,0);
__line.lineTo(__swidth, __height);
__line.lineTo(0, __height);
__line.lineTo(0, 0);
__line.endFill();
}
private function drawBar():Void{
var i:Number = __holder.getNextHighestDepth();
__bar = __holder.createEmptyMovieClip("bar"+i,i);
__yFactor = (__target._height-__height)/__maxDist;
__bar.lineStyle(1, __color2);
__bar.beginFill(__color1);
__bar.lineTo(__swidth,0);
__bar.lineTo(__swidth,__scrollFactor*__height);
__bar.lineTo(0,__scrollFactor*__height);
__bar.lineTo(0,0);
__bar.endFill();
__bar.onPress = Delegate.create(this,press);
__bar.onRelease = Delegate.create(this,release);
__bar.onReleaseOutside = Delegate.create(this,release);
__bar.onEnterFrame = Delegate.create(this,updatePosition);
__line.onPress = Delegate.create(this,pressLine);
createMouseListener();
this.onInit(__target); //trigger the callback
}
private function createMouseListener():Void{
//Fill the instances array with relevant data to the mousewheel function
if(__instances==undefined) __instances = [];
__instances.push(this);
//See if already exists a mouse listener object and create one
if(__mouseLstnr==undefined){
__mouseLstnr = {};
setWheelHandler();
}
}
private function updatePosition():Void{
var dy:Number = __yFinal-__target._y;
var blurX:Number = 0;
var blurY:Number = __blur*Math.abs(dy);
var quality:Number = 3;
var filter:BlurFilter = new BlurFilter(blurX, blurY, quality);
var filterArray:Array = new Array();
filterArray.push(filter);
__target.filters = filterArray;
__target._y +=__speed*dy;
}
static private function setWheelHandler():Void{
__mouseLstnr.onMouseWheel = function(d:Number, mc:MovieClip):Void{
for(var i=0; i<__instances.length; i++){
//Check if the saved instance is the same where the mouse is over
if(__instances[i].__target.hitTest(_xmouse,_ymouse,false)){
var newY:Number =__instances[i].__bar._y - d;
if(newY>0 && newY<__instances[i].__maxDist){
__instances[i].__bar._y = newY;
}else if(newY<=0){
__instances[i].__bar._y = 0;
}else{
__instances[i].__bar._y = __instances[i].__maxDist;
}
__instances[i].updateFinalPosition();
}
}
}
Mouse.addListener(__mouseLstnr);
}
}
Edit:
(17/07/2007)
-permite mais do que uma instância simultaneamente no mesmo espaço
-método que permite fazer o update da barra de scroll se o conteudo for alterado (myScrollBar.render()
(19/07/2007)
-Scroll com a mouse wheel
-actualizar a posição da barra clicando na "pista"