Sticky Button class for Flash Actionscript 3
Enjoy this old, but still nice mjau-mjau.com sticky buttons script for AS3. Couldn't find it anywhere for AS2 or AS3 so i rewrote it for AS3; Feel free to use anywhere...
StickyButton Class for AS 3.0
There are very many ways you can use or adopt this class. Here is one of the simplest ways by specifying MovieClip base class in Library:
Download example (Flash CS3 .FLA file)
package { import flash.display.MovieClip; import flash.events.Event; import flash.events.MouseEvent; /** * @author - darklow, First Intelligence www.first.lv (rewriting from AS 1.0 to AS 3.0) * @author - www.mjau-mjau.vom (original AS 1.0 code author) */ public class StickyButton extends MovieClip { private var accel:Number = .6; private var convert:Number = .7; private var r:Number = 3; private var xstart:Number; private var ystart:Number; private var targetx:Number; private var targety:Number; private var t:Number; private var xpos:Number = 0; private var ypos:Number = 0; private var drag:Number = 0; private var drag_this:Boolean = false; private var mouseOnStage:Boolean = false; public function StickyButton() { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); var iterations:Number = 5; xstart = x; ystart = y; targetx = xstart; targety = ystart; var xx:Number = (2 * Math.PI) * (1 / iterations); t = Math.tan(xx); addEventListener(Event.ENTER_FRAME, checkFrame); stage.addEventListener(MouseEvent.MOUSE_MOVE, function(event:MouseEvent):void { mouseOnStage = true; }); stage.addEventListener(Event.MOUSE_LEAVE, function(event:Event):void { mouseOnStage = false; }); } private function checkFrame(e:Event):void { if (this.hitTestPoint(root.mouseX, root.mouseY, true) && mouseOnStage) { var deltax:Number = parent.mouseX - xstart; var deltay:Number = parent.mouseY - ystart; targetx = (parent.mouseX - deltax / r); targety = (parent.mouseY - deltay / r); if (!drag_this) { drag_this = true; drag++; } } else { targetx = xstart; targety = ystart; if (drag_this) { drag_this = false; drag--; } } xpos = xpos * accel + (targetx - x) * convert; x += xpos; ypos = ypos * accel + (targety - y) * convert; y += ypos; } } }
December 9th, 2009
once I save this as *.AS file, how do you use it on a button? thanks for help….
December 9th, 2009
There are very many ways you can use or adopt this class. Here is one of the simplest ways by specifying MovieClip base class in Library. I updated post with .FLA example
December 9th, 2009
Thanks so much for the sample files. I get it now
What is the best way to add an event to recenter the image once the mouse leaves a certain area? I notice the image gets stuck when leaving the stage, but I would like it to return once a certain limit is reached within the stage.
addEventListener(Event.MOUSE_LEAVE, recenter);
private function recenter(e:Event):void
xpos = 100;
ypos = 200;
December 9th, 2009
In that case we need to use Event.MOUSE_LEAVE and also MouseEvent.MOUSE_MOVE events and track if mouse is on the stage at all. I updated examples
December 9th, 2009
Wow you are pro at this. Instead of detect if mouse left stage, how to detect if mouse has gone out of defined zone or for example 100 x or y from start?
December 10th, 2009
You can create transparent shape under the buttons in wanted size and track if mouse leaves or are over this area.
1) Define private var mouseOnArea:Boolean = false;
2) Create transparent shape under the buttons in desired size
3) After shape is created, add listeners to it:
shape.addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
mouseOnArea = true;
}
shape.addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
mouseOnArea = false;
}
4) Change this line:
if (this.hitTestPoint(root.mouseX, root.mouseY, true) && mouseOnStage) {
to:
if (this.hitTestPoint(root.mouseX, root.mouseY, true) && mouseOnStage && mouseOnArea) {
Should work
December 13th, 2009
If you create an hidden shape under the area, do you have to name the instance?
December 14th, 2009
Yes you have to use instance name, but access to this shape is a bit different, because button (StickyButton class object) and background shape are children of same parent, you must access it through parent:
Give your shape some instance name, for exameple: area
and you can access to it using:
var area:MovieClip = (this.parent as MovieClip).getChildByName(’area’) as MovieClip;
trace(area);
February 2nd, 2010
Love the code!, thank you for sharing.
April 9th, 2010
How can I get this script to work if the button registration point is 0,0 ?
April 9th, 2010
The solution is to update these lines:
targetx = (parent.mouseX – deltax / r) – (width / r);
targety = (parent.mouseY – deltay / r) – (height / r);
April 11th, 2011
p0rh9Z Good point. I hadn’t thought about it quite that way.
April 22nd, 2011
MiiATb ogbrvylxdoti