This is an effect that I have seen on some Flash sites so I thought I would deconstruct it. To be honest, I’m not sure I like the effect, but with some tweaking it could be useful. Basically you have a menu of images or icons that react to the proximity of the mouse. If the mouse is close enough to a particular menu item, that menu item will snap to the mouse and follow it. When the mouse gets too far away the item will snap back into its original position.
In this example I created a nice rollover effect using blend modes. You can see how I created it by looking at the FLA file. All the ActionScript code is located in an external Document Class for easy viewing. I was planing on doing a tutorial on this but have decided to instead work on a multi-part tutorial on using AMFPHP. Look for that very soon!
You can download a ZIP file containing the FLA and the external AS file. If you just want to see the ActionScript, then you can view it below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | package { // Import Flash classes import flash.display.*; import flash.events.*; public class ProximityMenu extends MovieClip { private var ia:Array; public function ProximityMenu():void { ia = [im1, im2, im3, im4]; for(var i:uint = 0; i < 4; i++) { ia[i].buttonMode = true; ia[i].ox = ia[i].x; ia[i].oy = ia[i].y; ia[i].tx = ia[i].ox; ia[i].ty = ia[i].oy; ia[i].addEventListener(MouseEvent.ROLL_OVER, onOver); } stage.addEventListener(Event.ENTER_FRAME, onMove); } private function onOver(e:MouseEvent):void { e.target.gotoAndPlay("over"); addChild(MovieClip(e.target)); } private function onMove(e:Event):void { for(var i:uint = 0; i < 4; i++) { var dist:Number = getDist(mouseX, mouseY, ia[i].ox, ia[i].oy); if(dist < 70) { ia[i].tx = mouseX; ia[i].ty = mouseY; } else { ia[i].tx = ia[i].ox; ia[i].ty = ia[i].oy; } ia[i].x += Math.round((ia[i].tx - ia[i].x) * 0.3); ia[i].y += Math.round((ia[i].ty - ia[i].y) * 0.3); } } private function getDist(x1:Number, y1:Number, x2:Number, y2:Number):Number { var dx:Number = x2 - x1; var dy:Number = y2 - y1; return Math.sqrt(dx*dx + dy*dy); } } } |
Hope you enjoy it!
Lee








Cool menu with even better content.
Very cool. Thanks Lee!
Now to find a place to use it. Shouldn’t be hard.
I’m not a big fan of it. I think it may confuse users. Though I like the shine effect you have on the pictures.
I look forward to your take on AMFPHP. I’ve used it extensively on my website http://www.cellpaint.com.
Yeah. Cool effect, really comes out and ‘grabs’ u, or the mouse I guess. Personally I think its a little kitchy. Might be cooler as some kind of informational node in some information-gathering-display type of thing. Hmm. Maybe implemented as some kind of item dock in an air app or something. Wheee. Ideas!!
Nice example!
Personally I had hoped you had coded the mouse over blending effect as well. I can understand why you didn’t, but I think that could have been a very interesting and reusable class.
Possibly better suited to a touch screen perhaps … I also like the shine effect more than the snap effrvt. As ever thanks for sharing
That would be snap “effect” not effrvt!
Thanks Lee.
Very cool and fantastic shine effect trick, thanks Lee.
Also a question: it’s necessary to call
addChild(MovieClip(e.target));
in the onOver function?
Thanks al lot!
If one moves the cursor slowly, in the current version, with one image/option ‘active’, it is possible to move to positions where the next image as moved to pointer-position the old one back to it’s resting place, but for the old one to remain the ‘active’ option.
I think it would feel better if the moment of the activation was brought forward with a tweak here and there.
Sorry, I’ve miss a part of my last message:
I’ve instead tried:
setChildIndex(MovieClip(e.target),numChildren-1);
:-[
It’s ok?
I particularly not like of these menus, but is a nice effect.
Unusual cool menu.I also look forward to your take on AMFPHP!.
Thanks Lee!
Nice photos by the way!
I did some timed comparisons of AMFPHP vs XML, and URLVariables, and Wade later asked whether I was using the C extension (or something unknown to myself), saying that it would dramatically improve the speed. I wasn’t to my knowledge. And I’ve also heard that even those you may specify AMF3 from Flash, AMFPHP doesn’t necessarily transfer with AMF3 protocol. Regardless AMFPHP was already faster than XML or URLVariables. As well I find it easier to consume and use the result data from AMFPHP than any other method. BlazeDS wasn’t available at the time, and I’ve not looked into using BlazeDS at all…
Here’s my speed comparisons: http://www.leefernandes.com/blog/blog/Entries/2007/10/17_E4X_XML_vs_URLVariables_vs_AMFPHP_1.9_beta2.html
I remember back in the days when Mjau-Mjau had their website built with the same effect, and that was about 4 years ago. What amazing time those were!
Good to see such a clean code released for such a great effect. Keep up the good work Lee, and remember to live!
I’m going to have to agree with the Will, it’s a nice effect but i’d never use it for any kind of navigation. The only thing I could see something like this being used for is previewing thumbnail images of a gallery or something. Rolling over would make the image bigger and optionally add some description or title to it.
Great shine effect. Yet another reason for me to get cracking on learning Actionscript 3 better.
@Beppino Yes you need to call that so the image pops in front of the others.
I like the shine also (simple technique, great effect), but the sticky proximity interaction ‘feels’ like a broken drag-n-drop thingie.
Maybe the proximity range is a bit to large, or maybe don’t move the thumbs at all but just make them bigger the closer the mouse comes.
Hi~
Which is the better for performance, addChild(MovieClip(e.target))
or setChildIndex(MovieClip(e.target),numChildren-1) ?
Thanks for the cool menu.
Hi Lee.
], I would have guessed that calling addChild() to add a child that is in fact already there, would just add it on top of the child that is already there or cause an error since its not dynamic. But in your example, it seems that Flash picks up on that your calling addChild() to a child that is already there, and therefore just places that child on top of the display list (depth). Am I right? Maybe you could elaborate a little on that (pretty please).
The addChild() issue that Beppino brought up I find interesting.. If I hadn’t seen this beautiful and clean example of yours [
Thanks.
@Christian Yes you are absolutely right. Calling addChild() on an item that is already on the list simply puts it at the top. I learned that from the Learning ActionScript 3 book.
those who find it lacking with functionality, you can always expand lee’s example… i dont think lee would provide you something you exactly need for your site…
Nice effect… Glad i’m not the only one who was confused with how exactly addChild() worked to bring the item to the top!
Great – I’ve swapped depths of several clips with a tedious function with swapChildren() before… silly me. Thanks a lot for clarifying.
Great effect, simply interesting!
Looking very much forward to the new tutorial.
I also like this class you’ve posted, looks very useful
best regards
Peter
AMFPHP…..thank you, thank you, thank you, Lee
Just excellent. Love the shine effect!
I try to understand the script:
One problem: Where “over” in gotoandplay(“over”) is defined ?
When i put anything at its place it continues working.
thanks to answer me.
The effect may seem superfluous in this demo but I can think of certain areas where it would benefit the UI.
For example, you could have an OS X dock style navigation menu. When not in use the menu could shrink down to a size where it’s both unobtrusive but also barely usable. The menu could then scale up in a predictive manner so by the time the mouse arrived at the menu it will have grown to the point where it’s usable. You could augment this further by predictively scaling the icon/menu entry you think the user is trying to hit (similar to the OS X dock effect except the scaling of an icon would be initiated before the users mouse was over the dock).
Dude, nice girl friend!
JC
Thanks for share, Lee.
but I have some question about it. When I apply to my own work, it isn’t run anymore. So, I used to learn the as 3.0, it should have to set var for call the .as file, right? But I don’t see that code in your work. Is that the point to make my work is not run?
Thanks for make inspiration for my work.
Tried to do something with this Class, but it gives me “Error #1010: A term is undefined and has no properties.” or other funny errors
.
sometimes, there are two movieclip is moving, so i modify the onMove function, search for the max index movieclip, then set the action to it only. thanks, very cool.
onMove function code:
private function onMove(e:Event):void
{
var idxArray:Array = new Array();
for(var i:uint = 0; i < 4; i++)
idxArray.push(getChildIndex(ia[i]));
idxArray.sort();
var mc:MovieClip = MovieClip(getChildAt(idxArray.pop()));
var dist:Number = getDist(mouseX, mouseY, mc.ox, mc.oy);
if(dist < 70)
{
mc.tx = mouseX;
mc.ty = mouseY;
}
else
{
mc.tx = mc.ox;
mc.ty = mc.oy;
}
mc.x += Math.round((mc.tx – mc.x) * 0.3);
mc.y += Math.round((mc.ty – mc.y) * 0.3);
}
Hey Lee, when I had seen this the first time, I thought it was really cool. I noticed you seemed to not think it would be very useful, though, if only for effect, but it gave me an idea. My sister has wanted a website for her photography for a while, and I thought of using those as links. I editted the idea a bit, but thought you might like to see the results.
http://www.dbinspiredarts.com/
Thanks for the inspiration! Look forward to being in your session at MAX!
Hi Lee, first of all thank you very much for all your dedication in these kind of examples and in the tutorials of gotoandlearn!
Here it’s my small problem, I’m just beginning working with Flash and tried to aply this great buttons into a fla with two scenes, the first one for preloader and the second one with the main stuff.
The problem appears when the init fuction of the ProximityMenu class tries to start working with the buttons before the second scene is loaded and this error appears:
Error #1009: Cannot access a property or method of a null object reference.
at ProximityMenu$iinit()
How should I fix this? sorry if it’s a stupid question… I’ll keep trying to fix it in the meantime
Thanks!
awesome!! especially for a noob like me!
THanks i simply love the effect, very subtle
This menu example worked great for my site. I am trying to use it as a sort of ‘easter egg.’ So when people are moving their mice around the screen, the pictures will snap to the mouse, hopefully grabbing their attention and making them feel like they’re interacting with the page. Thanks much for this example. But now to why I’m posting.
I am very new to Flash CS3 and I can’t seem to get this to work with the code already implemented in my site. I added it to the Document Class box in the Properties menu in my FLA, but when I compile it, the code I have in place breaks and I get this error “1046: Type was not found or was not a compile-time constant: URLRequest.” I’ve tried researching this error, but can’t seem to find a solution that fixes the issue.
I have code written into my FLA for buttons that link to various places on my site and if this .as is in the Document Class box, everything breaks down. I don’t have the foggiest clue as to how to fix it. Any help would be greatly appreciated.
Hi Lee.
This is not exactly regarding this thread, but more to a core functionality with this thread – downloading
Do you use a plugin, that enables visitors to download a zip from this blog?
And also do you use another plugin so you can make the javascript popup windows on the blog?
Best regards
Santiago
Hi,
You can use the static method “distance” of the Point class too ?
var dist:Number = Point.distance( new Point(x1,y1), new Point(x2,y2);
Is it less fast ?
Hi, who is the turorial? It´s time to make it
please ;.)
make this mc´s with a Kinematic-Bone?
sorry for my bad english. I´m german
Thanks,,,:)
i cant put link into the im1 im2 etc
i have put 5more photos
ia = [im1, im2, im3, im4, im5, im6, im7, im8];
for(var i:uint=0; i<8; i++)
i put 2 photos
ia = [im1, im2, im3, im4, im5, im6];
for(var i:uint=0; i<6; i++)
the result:
1120: Access of undefined property im5.
1120: Access of undefined property im6.
Plz someone help me
Hi there
Heeeelp pls!?!?!
I’d love to use this script on a website, but I’m new at AS3 and I’m struggling!
Everything works fine, but I don’t know how to add a click function on each of the movieclips – in other words, when you click either of the images, it plays another movieclip on another frame. Just not sure what code goes where…
Thanks in advance!