Simple Scroller Class AS2
This scroller was written for an emergency situation at my last job, our 3rd party scroller from Extend Studios had a bug in in that caused the newest version of the Flash player to instantly crash our sites. This was a major problem, as we had already implemented about 35 sites using this plugin!
My Job was to create a chuck of inline code, which followed the function signature of our 3rd party component, and which would work with the existing MovieClip assets embedded into each movie (scroll_knob, scroll_track, scroll_button).
The end result is a loadScroller function, which can take a direct reference to an on-Stage movieClip, or a string containing the Linkage Name, and will create a very nice, smooth scroll bar for that clip. It features auto-resizing so it works great with dynamic text, and it can also be called from any other movieclip in your site. So you set this up once, and then you can call it from anywhere to easily scroll any movieclip you wish!
Unfortunately I couldn’t find the very latest version of the scroller, so there are a couple small bugs in this code which I don’t have time to fix right now:
Known Bugs:
- Multiple mouse-wheel listeners are created when repeatedly instanciating scrollers. This cause the scroll amount of the mouse wheel to gradually increase.
- unload function need to be updated to remove the mask, and kill the mouse wheel listener
Requirements:
- Your movie must have 3 assets exported for actionscript: “btnl_up”, btnr_up”, “knob_up”, “track_up”
Example usage:
loadScroller(”mcContentText”, width, height, x, y);
Inline Script:
///////////////////////////////////////////////////////////////////////////////////////////
// Scroller - v1.1
// This can be called by passing a string reference to an embedded movieClip, or by directly passing an instance from the stage.
// The last parameter 'source_mc' is optional, to be used when loading a scroller from inside another movieClip.
//
// These references are created within the source movieclip:
// source_mc.scroller
// source_mc.scroller.scrollbar
// source_mc.scroller.content
//
// Scrolling can also be controlled using scroller.scrollTo(scrollOffset, easeIn). easeIn defaults to false.
// Remove scrollbar by calling scrollbar.unload()
//////////////////////////////////////////////////////////////////////////////////////////
import mx.transitions.easing.*;
import mx.transitions.Tween;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.display.BitmapData;
import flash.filters.GlowFilter;
//SETUP
var bottomPadding = 25; //Add a bit of extra space at the bottom of a clip
var easingLevel = 5; //Easing duration (in frames). 0 = none
var clickStep = 25; //Number of pixels to jump when mouse wheel, scroll track, or scroll buttons are pressed
var glowColor = 0xFFFFFF; //Color of mouse-over glow effect
var glowAlpha = 1; //Alpha level of glow-effect, between 0 - 1
var loadDelay = .35; //Time (in ms) to wait until checking the height of the target_mc
var mouseWheel = true; //Enable mouse wheel support
var autoResize = true; //Automatically adjust scroll bar onEnterFrame
var trackGlow = true; //Add glow effect to scroll track
var knobOffset:Number = 5; //Tiling offset when creating the scrollKnob, in pixels. The source MC should be taller than this*2
var skinPrefix = ""; //Prefix for skins movieclips
var debugTrace = false; //Throws a trace on scroll so you know you're using the new scroller (temp)
function loadScroller(instanceName, contentWidth, contentHeight, xPos, yPos, _source_mc){
//Support backwards compatability, if source_mc is "Stage" get the intended object
if (_source_mc == "Stage") instanceName = this[instanceName];
//For source_mc to be valid, it should have a parent. If not, it's invalid so use 'this' instead.
var source_mc = (_source_mc._parent) ? _source_mc : this;
//Remove any existing scroll areas
source_mc.scroller.removeMovieClip();
//Create new scroll container
var scroller = source_mc.createEmptyMovieClip("scroller",source_mc.getNextHighestDepth());
source_mc.scroller = scroller;
//If instance name has a parent, it must be on the stage...
if(instanceName._parent)
scroller.content = instanceName; //...create a reference to the source clip
//Otherwise it's a Linkage Name from the Library...
else
scroller.content = scroller.attachMovie(instanceName, "content", 1);
//Position and size
scroller.content._x = int(xPos);
scroller.content._y = int(yPos);
scroller.baseWidth = int(contentWidth);
scroller.baseHeight = int(contentHeight);
//Create Mask
createMask(scroller.content, int(contentWidth), int(contentHeight));
setTimeout(function(){
attachScrollbar(scroller, source_mc);
}, loadDelay);
}
function attachScrollbar(_scroller, _source_mc){
var source_mc = (_source_mc) ? _source_mc : this;
//Find scroll container
var scroller = _scroller;
var scrollTarget_mc = scroller.content;
//Create scroller container and position
scroller.scrollbar.removeMovieClip();
scrollbar = scroller.createEmptyMovieClip("scrollbar", scroller.getNextHighestDepth());
scrollbar._x = int(scrollTarget_mc._x + scroller.baseWidth);
//Save reference to scrollbar in source movieclip
scroller.scrollbar = scrollbar;
//Determine whether to hide or show the scrollbar
scroller.scrollbar._visible = (scroller.content._height > scroller.baseHeight) ? true : false;
//If a scrollbar has already been added...
if(scroller.targetMin != undefined){
//...save current y position of scrolled content
var currentOffset = scrollTarget_mc._y;
//Temporarily set content back to original position, to simplify calculations
scrollTarget_mc._y = scroller.targetMin;
}
scrollbar._y = int(scrollTarget_mc._y);
//Attach Buttons
track_mc = scrollbar.attachMovie(skinPrefix + "track_up", "track_mc", 0);
knobSource_mc = scrollbar.attachMovie(skinPrefix + "knob_up", "knobSource_mc", 1);
buttonUp_mc = scrollbar.attachMovie(skinPrefix + "btnr_up", "buttonUp_mc", 2);
buttonDown_mc = scrollbar.attachMovie(skinPrefix + "btnl_up", "buttonDown_mc", 3);
//Size track
track_mc._height = scroller.baseHeight;
//Position Top Button
buttonDown_mc._y = track_mc._height - buttonDown_mc._height;
//Determine final knobHeight
if(scrollTarget_mc._height < track_mc._height)
knobHeight = track_mc._height - buttonUp_mc._height * 2;
else {
knobHeight = track_mc._height / (scrollTarget_mc._height/(track_mc._height - buttonUp_mc._height * 2));
if(knobHeight < 20) knobHeight = 20;
}
//Create container for final Scroll Knob
var knob_mc = scrollbar.createEmptyMovieClip("knob_mc", scrollbar.getNextHighestDepth());
//Draw the Top 5px and add to knob_mc
var knobTop_mc = knob_mc.createEmptyMovieClip("knobTop_mc", knob_mc.getNextHighestDepth());
bmpData = new BitmapData(knobSource_mc._width, knobOffset, true, 0xFFFFFF);
bmpData.draw(knobSource_mc, new Matrix(), null, null, new Rectangle(0, 0, knobSource_mc._width, knobOffset));
knobTop_mc.attachBitmap(bmpData, knobTop_mc.getNextHighestDepth(), true, true);
//Draw the Middle and add to knob_mc
var knobMiddle_mc = knob_mc.createEmptyMovieClip("knobMiddle_mc", knob_mc.getNextHighestDepth());
bmpData = new BitmapData(knobSource_mc._width, knobSource_mc._height-(knobOffset*2), true, 0xFFFFFF);
bmpData.draw(knobSource_mc, new Matrix(1,0,0,1,0,-knobOffset), null, null, new Rectangle(0, 0, knobSource_mc._width, knobSource_mc._height-knobOffset*2),true);
knobMiddle_mc.attachBitmap(bmpData, knobMiddle_mc.getNextHighestDepth(), true, true);
knobMiddle_mc._y = knobOffset-1;
knobMiddle_mc._height = knobHeight - (knobOffset*2 - 1);
knobSource_mc._visible = false;
knob_mc._y = buttonUp_mc._height;
//Draw the bottom 5px and add to knob_mc
var knobBottom_mc = knob_mc.createEmptyMovieClip("knobBottom_mc", knob_mc.getNextHighestDepth());
bmpData = new BitmapData(knobSource_mc._width, knobOffset, true, 0xFFFFFF);
bmpData.draw(knobSource_mc, new Matrix(1,0,0,1,0,-knobSource_mc._height + knobOffset));
knobBottom_mc.attachBitmap(bmpData, knobBottom_mc.getNextHighestDepth(), true, true);
knobBottom_mc._y = knobHeight - (knobOffset + 1);
//Now draw a bitmap copy of the entire knob, and use that instead of the 3 seperate clips
//(looks better when scaling the movie)
var knobBitmap_mc = knob_mc.createEmptyMovieClip("knobBitmap_mc", knob_mc.getNextHighestDepth());
bmpData = new BitmapData(knob_mc._width, knob_mc._height, true, 0xFFFFFF);
bmpData.draw(knob_mc);
knobBitmap_mc.attachBitmap(bmpData, knobBitmap_mc.getNextHighestDepth(), true, true);
//Remove the 3 source clips
knobBottom_mc.removeMovieClip();
knobMiddle_mc.removeMovieClip();
knobTop_mc.removeMovieClip();
//Init scrolling vars, save them inside the scroller so they can be easily referenced
scroller.targetBaseY = scrollTarget_mc._y;
scroller.scrollMin = buttonUp_mc._height;
scroller.scrollMax = scrollbar._height - buttonUp_mc._height - knob_mc._height;
scroller.mouseIsDown = false;
scroller.dragOffset;
scroller.targetHeight = scrollTarget_mc._height;
scroller.targetMin = scrollTarget_mc._y;
scroller.targetMax = scrollTarget_mc._y - scroller.targetHeight + scroller.baseHeight - bottomPadding;
scroller.totalHeight = scroller.targetMin - scroller.targetMax;
scroller.trackRatio = scroller.totalHeight/track_mc._height;
//Check offset to see if the target need to be restored to it's original scroll position
if(currentOffset != undefined){
//Determing knob position
offsetHeight = scroller.totalHeight - (currentOffset - scroller.targetMax);
//Position knob and content
scroller.content._y = currentOffset;
knob_mc._y = scroller.scrollMin + (scroller.scrollMax-scroller.scrollMin) * (offsetHeight / scroller.totalHeight);
}
//Setup Scroll-Knob
knob_mc.onPress = function() {
scroller.mouseIsDown = true;
scroller.dragOffset = this._ymouse;
};
knob_mc.onRelease = knob_mc.onReleaseOutside=function () {
scroller.mouseIsDown = false;
};
knob_mc.onMouseMove = function() {
if (scroller.mouseIsDown) {
knob_mc._y += knob_mc._ymouse-scroller.dragOffset;
scroller.checkBounds();
updateAfterEvent();
if(debugTrace) trace("Sitewyze Scroller v.1.1"); //(temp)
}
};
knob_mc.onEnterFrame = function(){
targetY = (scroller.targetMax-scroller.targetMin)*((knob_mc._y-scroller.scrollMin)/(scroller.scrollMax-scroller.scrollMin))+scroller.targetMin;
if(!easingLevel)
scrollTarget_mc._y += targetY-scrollTarget_mc._y;
else
scrollTarget_mc._y += Math.ceil((targetY-scrollTarget_mc._y)/easingLevel);
if(scroller.content._height != scroller.targetHeight && autoResize == true){
attachScrollbar(scroller, _root.scrollSkin, scroller._parent);
updateAfterEvent();
}
};
//Create Glow RollOver Effect for Knob
knob_mc.onRollOver = knob_mc.onDragOver = function(){
dummyTween = new Tween({position:0}, "_alpha", Regular.easeOut, 0, 1, .35, true);
var thumb_mc = this;
dummyTween.onMotionChanged = function(){
thumb_mc.filters = [new GlowFilter(glowColor, this.position/2, 2, 2, glowAlpha, 3, false)];
}
}
knob_mc.onRollOut = knob_mc.onDragOut = function(){
dummyTween = new Tween({position:0}, "_alpha", Regular.easeOut, 1, 0, .35, true);
var thumb_mc = this;
dummyTween.onMotionChanged = function(){
thumb_mc.filters = [new GlowFilter(glowColor, this.position/2, 3, 3, glowAlpha, 3, false)];
}
}
//Apply same GlowEffect to the other buttons
if(trackGlow) track_mc.onRollOver = track_mc.onDragOver = knob_mc.onDragOver;
buttonUp_mc.onRollOver = buttonUp_mc.onDragOver = knob_mc.onDragOver;
buttonDown_mc.onRollOver = buttonDown_mc.onDragOver = knob_mc.onDragOver;
if(trackGlow) track_mc.onRollOut = track_mc.onDragOut = knob_mc.onRollOut;
buttonUp_mc.onRollOut = buttonUp_mc.onDragOut = knob_mc.onRollOut;
buttonDown_mc.onRollOut = buttonDown_mc.onDragOut = knob_mc.onRollOut;
//Handle Mouse-Wheel
mouseHandle = new Object();
if(mouseWheel){
mouseHandle.onMouseWheel = function(delta) {
if (scroller.content.hitTest(_root._xmouse, _root._ymouse)) {
knob_mc._y += (delta < 0) ? clickStep/scroller.trackRatio : -(clickStep/scroller.trackRatio); scroller.checkBounds(); updateAfterEvent(); } }; } Mouse.addListener(mouseHandle); //Handle Track Press track_mc.onPress = function(){ //If they clicked above the knob move content up, else move it down. scroller.scrollbar.knob_mc._y += (scroller.scrollbar._ymouse > scroller.scrollbar.knob_mc._y) ? clickStep/scroller.trackRatio : -(clickStep/scroller.trackRatio);
scroller.checkBounds();
updateAfterEvent();
};
buttonUp_mc.onPress = track_mc.onPress;
buttonDown_mc.onPress = track_mc.onPress;
//Function to checkBounds
scroller.checkBounds = function(){
if (this.scrollbar.knob_mc._y < this.scrollMin) this.scrollbar.knob_mc._y = this.scrollMin; else if (this.scrollbar.knob_mc._y > this.scrollMax)
this.scrollbar.knob_mc._y = this.scrollMax;
};
//Function to manually scroll
scroller.scrollTo = function(scrollToY, easeIn){
//Determing knob position
totalHeight = scroller.targetMin - scroller.targetMax;
offsetHeight = totalHeight - (-(scrollToY-scroller.targetMin) - scroller.targetMax);
//Position knob and content
knob_mc._y = scroller.scrollMin + (scroller.scrollMax-scroller.scrollMin) * (offsetHeight / totalHeight);
scroller.checkBounds();
if(!easeIn) scroller.content._y = -(scrollToY-scroller.targetMin);
};
scroller.unload = function() {
this.removeMovieClip();
}
}
//Simplified create mask function (temp)
function createMask(clip_mc, _maskWidth, _maskHeight){
mask_mc = clip_mc._parent.createEmptyMovieClip(clip_mc._name+"_mask",clip_mc._parent.getNextHighestDepth());
mask_mc._x = clip_mc._x;
mask_mc._y = clip_mc._y;
maskWidth = _maskWidth;
maskHeight = _maskHeight;
//Draw square equal to the size of the stage and fill it.
mask_mc.beginFill(0x000000, 100);
mask_mc.moveTo(-1,-1);
mask_mc.lineTo(maskWidth, -1);
mask_mc.lineTo(maskWidth, maskHeight);
mask_mc.lineTo(-1, maskHeight);
mask_mc.lineTo(-1, -1);
mask_mc.endFill(0xFF00FF, 0);
clip_mc.setMask(mask_mc);
}
///////////////////////////////////////////////////////////////////////////////////////////
// End Scroller
//////////////////////////////////////////////////////////////////////////////////////////
[...] Click here for more info… [...]
AS2 Inline Scroller at Shawnblais.com v2
19 Aug 09 at 12:44 pm