AS3 – Amazing Map Function.

In: Actionscript|Classes and Functions|Flash|Source Code

9 May 2009

One of the things that makes the Flash community so strong, is the willingness of coders to share their work. I learned actionscript from people sharing code, and that’s what’s inspired me to start sharing some of the things I’ve been working on too. So I thought a good starting point would be to draw peoples attention to a few of the great Classes and Functions that I’ve found on blogs and messageboards, which I regularly use in my projects.

One brillaint function I’ve used in practically all of my projects since finding it, is Joel Gillman’s Map Function.

Joel’s Map function “Re-maps a number from one range to another“, which might sound like quite obscure functionality, but I use it for all sorts of different things. Let’s say you want a movieclip’s alpha to vary based on the user’s X mouse position and its rotation to vary based on the Y mouse position. Instead of writing lots of math, you can wrap it up in the map function.

Let’s take a look at the code -

?View Code ACTIONSCRIPT3
function map(v:Number, a:Number, b:Number, x:Number = 0, y:Number = 1):Number {
    return (v == a) ? x : (v - a) * (y - x) / (b - a) + x;
}

Now that might look pretty confusing – but it’s usage is actually really simple. The map parameters are structured like this – map(value, low1, high1, low2, high2);
So you feed in the value you’re altering (for example mouseX), the lowest that value can be, the highest that value can be, the lowest return value you want, and the highest return value.
Right, let’s take a look at this simple example –
[kml_flashembed fversion="9.0.0" movie="flash-content/MapClass/UsingMapCircleBlog.swf" targetclass="flashmovie" publishmethod="static" width="400" height="300"]

Get Adobe Flash player

[/kml_flashembed]

And the code that made it -

?View Code ACTIONSCRIPT3
var SW:Number = stage.stageWidth;
var SH:Number = stage.stageHeight;
 
var c:MovieClip = new MovieClip();
	c.graphics.beginFill(0xff0000,1);
	c.graphics.drawCircle(0,50,50);
	c.graphics.endFill();
	c.x = SW/2;
	c.y = SH/2;
	c.addEventListener(Event.ENTER_FRAME, circleEvents);
	addChild(c);	
 
function circleEvents(e:Event):void{
	trace(mouseX)
	e.currentTarget.alpha =    map(mouseX, 0, SW, 0, 1);
	e.currentTarget.rotation = map(mouseY, 0, SH, 0, 360);
}
 
function map(v:Number, a:Number, b:Number, x:Number = 0, y:Number = 1):Number {
    return (v == a) ? x : (v - a) * (y - x) / (b - a) + x;
}

So in that swf, the circle’s alpha varies between 0 and 1, based on the mouse’s X position, between 0 and the width of the stage. So, every frame I calculate the alpha using the map function. To set that up, I use the line -

?View Code ACTIONSCRIPT3
	e.currentTarget.alpha =    map(mouseX, 0, SW, 0, 1);

I’m monitoring the mouse’s X position, with a minimum value of 0, a maximum value of the stage width, and I want it to return a value between 0 and 1. Simple.
Similarly, the circle’s rotation ranges from 0 to 360, based on the mouse’s Y value – which ranges from 0 to the height of the stage. So -

?View Code ACTIONSCRIPT3
	e.currentTarget.rotation = map(mouseY, 0, SH, 0, 360);

I hope you find this great function as useful as I did.
Cheers.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • StumbleUpon
  • Tumblr
  • Twitter

16 Responses to AS3 – Amazing Map Function.

Avatar

Joel

May 10th, 2009 at 1:28 am

Glad you’ve enjoyed it!

Avatar

Freelance Flash Games

May 15th, 2009 at 1:34 am

Nice website Lawrie. I code in as2, but your tutorials look great.

Mapping seems like it could be useful. Was it used in your Super Letter Game?

Avatar

Lawrie

May 15th, 2009 at 9:04 am

Thanks, glad you like the site!
I didn’t use mapping in Super Letter Game, but only as I made it quite a while ago and it’s in AS2.
I could use it for setting the properties of the letters – relative to their perceived depth, something like –

clip.scaleX = clip.scaleY = Map(clip.depth,minDepth,maxDepth,minScale,maxScale);
clip.alpha = Map(clip.depth,minDepth,maxDepth,0,1);

Avatar

MichaelJW

May 17th, 2009 at 2:53 pm

Wow, this is brilliant! So simple, and yet so powerful. Thanks for sharing it :)

Avatar

Henner

May 25th, 2009 at 10:05 pm

Nice function! Thanks for sharing!

Avatar

LnddMiles

July 21st, 2009 at 9:44 pm

Great post! I’ll subscribe right now wth my feedreader software!

Avatar

JB

July 24th, 2009 at 11:42 pm

Saw the example on wonderfl. Thats going to come in handy. Nice one!
ps
If you have the time, post an example on the PV3D fourm.
cheers

Avatar

Lawrie

July 27th, 2009 at 12:16 pm

Glad you like it John, it’s a great time saver. Hopefully I’ll get the time to write up a PV3d example tonight.

Avatar

Rodrigo

October 28th, 2009 at 12:48 pm

Thanks! works perfect :)

Avatar

Davo

October 31st, 2010 at 6:20 am

Amazing indeed. Really helpful and timesaver.

Best from Argentina!

Avatar

Anonymous

September 26th, 2011 at 4:13 pm

I’m trying to map mouseY to -100 and 100. Doesn’t work.

The first value is ok: -100 when mouseY is 0.

But is 588.4 when mouseY is 550 (the stageHeight)?

Any ideas?

Avatar

Lawrie

September 26th, 2011 at 4:20 pm

It works for me, using the following demo AS –

this.addEventListener(Event.ENTER_FRAME, mapMouse);

function mapMouse(e:Event):void{
trace(map(mouseY,0,stage.stageHeight,-100,100));
}

function map(v:Number, a:Number, b:Number, x:Number = 0, y:Number = 1):Number {
return (v == a) ? x : (v – a) * (y – x) / (b – a) + x;
}

Are you sure 550 is your stage height? It’s the default flash stage width which might be throwing you off?

Avatar

Anonymous

September 26th, 2011 at 9:41 pm

Yeah, the 550 is the default. I’ve changed it for a ‘bigger’ project.

I can get it to work in a clean fla. But not in the project I’m working on.

Basically I’m moving a navigation based on the mouseY, and I’m using the script in attempt to add a bit of top- and bottom margin to the navigation. So I’m calling:

private function navigationHandler(event:Event):void
{
trace(mouseY, map(mouseY, 0, stage.stageHeight, -100, 100));
var _offstage = height / stage.stageHeight;
var _ypos = -((_offstage * stage.mouseY) – (stage.mouseY – (map(mouseY, 0, stage.stageHeight, -100, 100))));
TweenLite.to(this, .5, {y: _ypos});
}

private function map(v:Number, a1:Number, b1:Number, a2:Number = 0, b2:Number = 1):Number
{
return (v == a1) ? a2 : (v – a1) * (b2 – a2) / (b1 – a1) + a2;
}

But it simply return an odd value. And by the way it’s 500, not 550 as stated. But that seems not to be of any point; as it should return 100.

Avatar

Anonymous

September 26th, 2011 at 9:50 pm

It’s a Gaia project, and I can see now that I’m getting the mouseY based on the child, and not the stage as I thought i was.

Have to figure out how to get the mouseY from the stage and not the child. So there’s a reason it »didn’t work«.

Avatar

Anonymous

September 26th, 2011 at 9:57 pm

Yeah, had to do this first:

var mc:MovieClip = MovieClip(this.parent);
trace(map(mc.mouseY, 0, stage.stageHeight, -100, 100));

Working great, thanks.

Avatar

Lawrie

September 26th, 2011 at 10:05 pm

Glad you got it working :)

Comment Form

About this blog

This is the blog of Lawrie Cape, an interactive developer from Leeds, England.

Photostream

  • COne
  • CTwo
  • CThree
  • CFour
  • Lawrie: Hi Dinaz, I'm not sure what's happening on your system I'm afraid. When you run the FlashMidiServer [...]
  • Dinaz Kardooni: Hi, I am having trouble with the Flash Midi Server. I downloaded it and it says it is connected, but [...]
  • It’s Movember again! - The Lawrie Cape Blog: [...] was a great project to work on and I wrote a blog post about it here. We had a nice surprise t [...]
  • Lawrie: Glad you got it working :) [...]
  • Anonymous: Yeah, had to do this first: var mc:MovieClip = MovieClip(this.parent); trace(map(mc.mouseY, 0, s [...]

Donate

Found any helpful code? Why not donate a quid or two. Cheers!