Tutorial Details
- Difficulty: Intermediate
- Program: Flash
Twice a month, we revisit some of our readers’ favorite posts from throughout the history of Activetuts+. This tutorial was first published in April, 2009.
In this tutorial we’ll create a magnifying glass effect, demonstrating use of the displacementMapFilter. The effect can be achieved in a relatively short space of time and with very little code.
Final Result Preview
Let’s take a look at what we’re aiming for:
Step 1: Brief Overview
We’re going to work with two layers, plus an additional optional layer. The first will hold an image which will contain the visual graphics, this can be anything. The second layer will be the color map which will control the pixel pushing. The third layer will hold the ActionScript.
An optional fourth layer will be an overlaying graphic acting as the frame or lens surround.
Lets look into it!
Step 2: Document Setup
First thing we need to do is make a new ActionScript 3.0 Flash file – make the document size 530px X 400px with a framerate of 30fps.

Step 3: Import Resources
Next we need to import an image that we can use for this effect – I found a cool, freely available desktop image at 1024px X 768px.
Import this to stage and name the layer "Image".

Now let’s scale the image down to 50% and center it.

Step 4: Scripting the Filter
Create a new layer on top and call it "Actions". Then let’s bring the actions panel out and start coding the effect. First we need the filter for the image so let’s create a new filter object and call it "dFilter". We’ll leave the filter free of parameters as there are quite a few to set.
var dFilter:DisplacementMapFilter = new DisplacementMapFilter ();
Next we need to set these filter parameters in listed view.
Step 5: Effect Scale
Let’s start with the easiest ones and set the scales to around 50. This is the amount to which the magnifier will zoom in. It can also be set to a negative value, but in this case we need it to zoom in, not out.
Additional lines: 3,4
var dFilter:DisplacementMapFilter = new DisplacementMapFilter (); dFilter.scaleX = 50 dFilter.scaleY = 50
Note: this is not the actual order in which the filter normally accepts the parameters. However, in this case we can add them as we wish because we’re using the listed view for a better overview.
Step 6: Color Channel Components
Next we’ll set the component color channels for X and Y – this dictates which colorchannels in the control map (which we’ll create in a second) the filter will listen to.
If you’re familiar with the RGB hex code #RRGGBB, we can choose from BitmapDataChannel.RED, BitmapDataChannel.GREEN and BitmapDataChannel.BLUE. To make it easier we can also just write 1 (red), 2 (green) or 4 (blue) – (and no I didn’t make a spelling mistake, the blue is 4; this is set from the actual channel position in the hex code). In this example we’ll just stick to red (1) and green (2)- but we’ll come back to more about this when we design the actual displacement map.
Additional lines: 5,6
var dFilter:DisplacementMapFilter = new DisplacementMapFilter (); dFilter.scaleX = 50 dFilter.scaleY = 50 dFilter.componentX = 1 dFilter.componentY = 2
Step 7: Displacement Mode
Next we need to set the mode to determine how the pixels will react if they are pushed further than the image boundaries. Here we can choose from:
DisplacementMapFilterMode.COLOR / DisplacementMapFilterMode.WRAP / DisplacementMapFilterMode.CLAMP / DisplacementMapFilterMode.IGNORE
Again we can simplify this by writing "color", "clamp", "wrap", "ignore". I won’t get any further into these in this tutorial, so lets just use “color” which works best in most cases.
Additional lines: 7
var dFilter:DisplacementMapFilter = new DisplacementMapFilter (); dFilter.scaleX = 50 dFilter.scaleY = 50 dFilter.componentX = 1 dFilter.componentY = 2 dFilter.mode = "color"
This mode allows pixels to continue beyond the image boundary (in case the filter pushes the pixels further than the edge of the image).
Step 8: Surrounding Color and Alpha
Now let’s set the surrounding color to 0×000000 and alpha to 0. This is 100% transparent, so nothing is displayed outside the image except the source pixels.
Additional lines: 8,9
var dFilter:DisplacementMapFilter = new DisplacementMapFilter (); dFilter.scaleX = 50 dFilter.scaleY = 50 dFilter.componentX = 1 dFilter.componentY = 2 dFilter.mode = "color" dFilter.color = 0x000000 dFilter.alpha = 0
Step 9: Filter Effect Position
Now we need to set the position where the filter will affect the image; our lens position. This has to be set as a Point object containing the x and y value. We’ll begin by creating the point object so it’s ready for use when we assign it to the displacementMapFilter. Let’s call it "dPoint" and set it to 0, 0 as initial values. We’ll come back to this in a moment when we need to instruct this point to follow the mouse.
Next we assign "dPoint" to the "dFilter’s" point position.
Additional lines: 1,11
var dPoint:Point = new Point(0, 0); var dFilter:DisplacementMapFilter = new DisplacementMapFilter (); dFilter.scaleX = 50 dFilter.scaleY = 50 dFilter.componentX = 1 dFilter.componentY = 2 dFilter.mode = "color" dFilter.color = 0x000000 dFilter.alpha = 0 dFilter.mapPoint = dPoint;
Step 10: BitmapData
Last but not least we need to assign the control map to the filter. This is the map which contains the colored pixels that the componentX and Y listen to.
Additional lines: 13
var dPoint:Point = new Point(0, 0); var dFilter:DisplacementMapFilter = new DisplacementMapFilter (); dFilter.scaleX = 50 dFilter.scaleY = 50 dFilter.componentX = 1 dFilter.componentY = 2 dFilter.mode = "color" dFilter.color = 0x000000 dFilter.alpha = 0 dFilter.mapPoint = dPoint; dFilter.mapBitmap =
Here we also need a BitmapData object to act as a data container for our color-map.
Step 11: Designing the Color Map
First we create a 100px X 100px, red to black, linear gradient square. This will take the current pixels and push them left and right as we set the componentX to red. Let’s make this a movieclip called "redMap"
Then we do the same again – but this time with a green to black linear gradient square, again 100px X 100px. This time we’ll also rotate it 90°. You might remember we set the component for the Y axis displacement as green (componentY = 2) so the gradient goes along the y axis. Once again we’ll convert it to a movieclip, this time calling it "greenMap"

Step 12: Preparing the Map for Capture Phase
We now have two separate color images; we need just one, so set the blendmode of the greenMap to "screen". Every color from the greenMap will then shine through on the redMap. Place the greenMap on top of the redMap and make sure they align correctly.
Select both movieclips by clicking on the layer "Map" and convert the two into one movieclip called "colorMap". Then set the instance name to "colorMap_mc".

Step 13: Map Container
Now let’s return to the code and continue by capturing the colorMap movieclip in a bitmapData.
Go to the top of the code and create a new BitmapData object. Let’s call it "dMap" and set the size of it to match the size of our colorMap (in this case 100px X 100px, but this can be almost anything). We’ll set transparent to "true" and color to 0×808080. This ensures that any remaining pixels in the bitmapData are neutral.
Additional lines: 3
var dPoint:Point = new Point(0, 0); var dMap:BitmapData = new BitmapData(colorMap_mc.width, colorMap_mc.height, true, 0x808080) var dFilter:DisplacementMapFilter = new DisplacementMapFilter (); dFilter.scaleX = 50 dFilter.scaleY = 50 dFilter.componentX = 1 dFilter.componentY = 2 dFilter.mode = "color" dFilter.color = 0x000000 dFilter.alpha = 0 dFilter.mapPoint = dPoint; dFilter.mapBitmap =
Step 14: Capture Phase
We need to draw the colorMap’s content into the bitmapData. Once that’s done, we’ll be able to use script to delete the colorMap from the stage. This is possible as the colorMap image will be contained within the bitmapData code.
Additional lines: 5, 7
var dPoint:Point = new Point(0, 0); var dMap:BitmapData = new BitmapData(colorMap_mc.width, colorMap_mc.height, true, 0x808080) dMap.draw(colorMap_mc) removeChild(colorMap_mc) var dFilter:DisplacementMapFilter = new DisplacementMapFilter (); dFilter.scaleX = 50 dFilter.scaleY = 50 dFilter.componentX = 1 dFilter.componentY = 2 dFilter.mode = "color" dFilter.color = 0x000000 dFilter.alpha = 0 dFilter.mapPoint = dPoint; dFilter.mapBitmap =
Step 15: Assigning the Map to the Filter
Add the bitmapData dMap to the displacementMapFilter by setting the last parameter in the list (mapBitmap) to "dMap".
Modified lines: 19
var dPoint:Point = new Point(0, 0); var dMap:BitmapData = new BitmapData(colorMap_mc.width, colorMap_mc.height, true, 0x808080) dMap.draw(colorMap_mc) removeChild(colorMap_mc) var dFilter:DisplacementMapFilter = new DisplacementMapFilter (); dFilter.scaleX = 50 dFilter.scaleY = 50 dFilter.componentX = 1 dFilter.componentY = 2 dFilter.mode = "color" dFilter.color = 0x000000 dFilter.alpha = 0 dFilter.mapPoint = dPoint dFilter.mapBitmap = dMap
Step 16: Add Filter to Image
The filter is complete! We now need to add it to the image, so select the image and make sure it has an instance name – lets call it "Image_mc". That done, we’re able to set the filter on the image. We do this at the end of the code by setting the Image filters parameter as an array like this:
Image_mc.filters = [dFilter]
Additional lines: 21
var dPoint:Point = new Point(0, 0); var dMap:BitmapData = new BitmapData(colorMap_mc.width, colorMap_mc.height, true, 0x808080) dMap.draw(colorMap_mc) removeChild(colorMap_mc) var dFilter:DisplacementMapFilter = new DisplacementMapFilter (); dFilter.scaleX = 50 dFilter.scaleY = 50 dFilter.componentX = 1 dFilter.componentY = 2 dFilter.mode = "color" dFilter.color = 0x000000 dFilter.alpha = 0 dFilter.mapPoint = dPoint dFilter.mapBitmap = dMap Image_mc.filters = [dFilter]
OK, let’s export the movie and see how the filter is affecting the image. It should look something like this:
Step 17: Interactivity
What we have so far isn’t very exciting, so let’s try to make the lens follow the mouse.
First we add the "enterFrame" loop code like this:
Additional lines: 23,25,27
var dPoint:Point = new Point(0, 0);
var dMap:BitmapData = new BitmapData(colorMap_mc.width, colorMap_mc.height, true, 0x808080)
dMap.draw(colorMap_mc)
removeChild(colorMap_mc)
var dFilter:DisplacementMapFilter = new DisplacementMapFilter ();
dFilter.scaleX = 50
dFilter.scaleY = 50
dFilter.componentX = 1
dFilter.componentY = 2
dFilter.mode = "color"
dFilter.color = 0x000000
dFilter.alpha = 0
dFilter.mapPoint = dPoint
dFilter.mapBitmap = dMap
Image_mc.filters = [dFilter]
Image_mc.addEventListener(Event.ENTER_FRAME, onFrame)
function onFrame(e:Event){
}
Step 18: Follow the Mouse
Next we set the values of our dPoint’s X and Y to follow the mouse. Additionally, we’ll reassign the newly changed dPoint to the dFilter again and reassign the filter to the image.
Additional lines: 26,27,28,29
var dPoint:Point = new Point(0, 0);
var dMap:BitmapData = new BitmapData(colorMap_mc.width, colorMap_mc.height, true, 0x808080)
dMap.draw(colorMap_mc)
removeChild(colorMap_mc)
var dFilter:DisplacementMapFilter = new DisplacementMapFilter ();
dFilter.scaleX = 50
dFilter.scaleY = 50
dFilter.componentX = 1
dFilter.componentY = 2
dFilter.mode = "color"
dFilter.color = 0x000000
dFilter.alpha = 0
dFilter.mapPoint = dPoint
dFilter.mapBitmap = dMap
Image_mc.filters = [dFilter]
Image_mc.addEventListener(Event.ENTER_FRAME, onFrame)
function onFrame(e:Event){
dPoint.x = mouseX
dPoint.y = mouseY
dFilter.mapPoint = dPoint
Image_mc.filters = [dFilter]
}
Lets test it again. It should look like this:
Step 19: Finalizing
It’s still not exactly how we want it, so lets make the center of the displacement follow the mouse and also add a small easing to the movement. To do that we change the following code:
dPoint.x = mouseXdPoint.y = mouseY
Modified lines: 26,27
var dPoint:Point = new Point(0, 0);
var dMap:BitmapData = new BitmapData(colorMap_mc.width, colorMap_mc.height, true, 0x808080)
dMap.draw(colorMap_mc)
removeChild(colorMap_mc)
var dFilter:DisplacementMapFilter = new DisplacementMapFilter ();
dFilter.scaleX = 50
dFilter.scaleY = 50
dFilter.componentX = 1
dFilter.componentY = 2
dFilter.mode = "color"
dFilter.color = 0x000000
dFilter.alpha = 0
dFilter.mapPoint = dPoint
dFilter.mapBitmap = dMap
Image_mc.filters = [dFilter]
Image_mc.addEventListener(Event.ENTER_FRAME, onFrame)
function onFrame(e:Event){
dPoint.x += ((mouseX-colorMap_mc.width/2)-dPoint.x)*0.3
dPoint.y += ((mouseY-colorMap_mc.height/2)-dPoint.y)*0.3
dFilter.mapPoint = dPoint
Image_mc.filters = [dFilter]
}
To sum up: we subtract half the size of the map from the map position, so it centers. Then we add a basic tweening function, which can be written like this:
this += (that-this)*speed
Step 20: Adding Custom Graphics
To top it off, I added a magnifying glass graphic that I prepared in photoshop. I converted it into a movieclip, gave it an instance name and made it follow the point that we use for the displacemenMapFilter.

This is achieved by setting the new lens_frame_image X and Y position equal to the dPoint position. Then subtract the offset for the graphics edge, so that it aligns perfectly with the filter effect.
Additional lines: 4,5
function onFrame(e:Event){
dPoint.x += ((mouseX-colorMap_mc.width/2)-dPoint.x)*0.3
dPoint.y += ((mouseY-colorMap_mc.height/2)-dPoint.y)*0.3
lens_mc.x = dPoint.x-8
lens_mc.y = dPoint.y-8
dFilter.mapPoint = dPoint
Image_mc.filters = [dFilter]
}
Now our result should look like this:
Conclusion
When you have learned to create this effect yourself it shouldn’t take more than 15 minutes to set up. Remember; if you forget what the parameters for the displacementMapFilter are you can always look them up on "help". There you will get the listed order and what each parameter does.
For quick experimentation you can go to my website and look in the "flash" section under "test / labs" – I have a bunch of displacementMapFilter test environments you can try out.
I hope you can find use for this filter in your creative work!

did they make this with flash cs4?
this was introduced in flash player 8 as a part of the BitmapData package in action script 2
very good,thanks
hmmmmm
gr8 tutorial simply hats off………………………..
That is very cool, thanks for sharing
very good
add a hide mouse to make it better so the glass will be your new mouse
How do you add a new filter object? Sorry i’m new to flash.
Very nice program. I try it out and the effect is superb. Can i ask you 1 question? what if i do not want the magnifying glass to appear at the start , it will only be visible when i press a button for example zoom in button?
just hide the frame graphics with visible false or removeChild() and set filters = []
then to turn on set the frame to visible true and set filters = [dFilter]
Philip
Is there a way to change the magnifying glass’ location from starting point in the upper left corner. I tried changing the “var dPoint:Point = new Point(0, 0);”. Still the magnifying glass’ location wont change. Is there a way?
Thank you
var offsetX:Number = 50
var offsetY:Number = 50
function onFrame(e:Event){
dPoint.x += (((mouseX+offsetX)-colorMap_mc.width/2)-dPoint.x)*0.3
dPoint.y += (((mouseY+offsetY)-colorMap_mc.height/2)-dPoint.y)*0.3
lens_mc.x = dPoint.x-8
lens_mc.y = dPoint.y-8
dFilter.mapPoint = dPoint
Image_mc.filters = [dFilter]
}
I really like it! Thanks a lot. The only thing that I would like is for the cursor to hide.
Very good work… thanks!
thank you. good.
Hi great tutorial, Im trying to make it possible to turn the filter on and off when a button is clicked. So far I have tried removing it from the background layer with Image_mc.filters = [] but didnt work. Any pointers would be very helpful.
Thanks Nick
the filters = [] should work – else set the displacementFilter.scaleX and scaleY to 0
sorry, I don’t see any realistic, complex displacement effect.. only a simple zoom.
( which can be easily done without using any bitmap or displacement filters )
why use filters when there are no complex distortions (refraction effect) ?
consider this tutorial a introduction to displacementmap filter – it was my intention to make a displacementMap part 2 with some of the effects you can see at http://thonbo.com.
active tuts renamed the tutorial from “introduction to displacementmap filter” to “magnifying glass effect”
nice!
What a beautiful view ! I liked very much !!!
Thanks Philip, I learnt how to use displacement in my animations.
Wow, looks amazing, just what I’ve been looking for! Will this work with AS 2.0?
Will this work with Actionscript 3.0?
wow it’s long but amazing
thanks very much
Very Thans.
What a great tutorial, a really helpful piece. I’d love to be able to create a circular filter, but no matter how I try the basic displacement is happening in a square area with the displacement map having it’s desired effect where it should. The result is unsightly square corners (displaced pixels) on a circular “magnified” area.
Anyone know how a circular filter could be applied?
use #808080 as masking – using this color in mix with the colormap creates the magic – els try creating the Colormap in photoshop and distort it
RE:
“use #808080 as masking”
I changed the magnifying glass to a round one….
but I am getting that annoying square edge…
I have tried all kinds of things none of which worked….
Can you elaborate on how to make that disappear.
Never mind I figured it out..
Once again I was missing one tiny detail…
Nice….
Thanks for this its a great tutorial
why when I start my application, I have a double square (one inside the other and one more small then the other) and the zoom effect is so bad?
Sorry for my bad english, I’m Italian.
Tnx P.
Marshall
This is so awesome dude…i’ll try to do this imediatlly and i hope it will work … i’m a beginer in flash … but i’d like to learn more , cause html , css i allready know ;)) thx again man :> !!!
Nice job man,…
your portfolio-site rocks!!!
keep on going…
thx dude… it is abit old…
thank you, i’m a beginner in flash, i will learn a lot from your works
hey very good
hay admin thanks very beatiful
Thanks for this its a great tutorial
Hey, wow dude that is just awesome, to some ppl having trouble, resulting in more than one square or no zoom at all, the solution is to make sure when creating redMap, greenMap and colorMap the register is set to the left upper corner, also when creating colorMap try not to make any modifications to greenMap and redMap regarding its position inside the movieclip “colorMap”, finally if you want to hide the mouse just add “Mouse.hide();” at the start of the script.
Cheers and again awesome work!.
thamk you admin
this is goog
wow wow wow !
wow, amazing ,wondergful
I keep getting two squares inside the box. One is zooming nicely but the other is normal and so the view is distorted. Please help :-) thanks.
Also, the mouse cursor is not following the lens…
wow good..
thanks for sharing :)
GR8 tutorial…..thanks for sharing with everybody……keep the good work going.
A good tut and a nice, painless intro to the brain-bangling world of displacement maps. My only beef is that this approach (at least as it is now, in this tut) doesn’t allow for a high-res zoom. Nonetheless, it is a great post.
We are using your magnifier for a school project but am running into a snag. We are loading the magnifier swf into a larger stage area using x and y coordinates and we can’t seem to figure out how to constrain the movement of the magnifier to the loaded swf file. We have a larger stage area of 1000 x 700 and the loaded swf is 736 x 460. Any direction on this would be appreciated.
Hello! I have a problem at the 16 th step…You say to select the image and change the instance name of the image…but how do I do that?Sorry, I’m really new in flash and I searched online, but I only found how to change instance name of symbols, but I couldn’t find how to change the instance name of a bitmap?Do I have to change the bitmap into a symbol or what?Can anyone help me pls?:D
Just make convert the image(background) into a movie clip and name the instance name on properties.
Hi,
So far I am really getting a lot out of this tutorial. However, I have hit a snag. I agree with Sika — do I first convert the image to a symbol and then give it an instance name or …what? I am also relatively new to flash.
Thanks.
i like……………..
god bless you
hi!
absolutely great tutorial! I love it!
I hawe just one question;
is it possible to make this work if the image underneath isn’t a movieclip? I have imported a vector image file from illustrator (swf-file) so, basically I’m making a arrow follow a motion path and leaving a colored path behind it. I want to zoom in on this at the “picture” as the animation plays. any clue? :)
have a nice day:)
Thanks for this its a great tutorial
Hi,
I rushed on your code, and discovered that it does only zoom your actual displayed object, rather than zooming the actua
sorry for my previous post… i pressed return too fast !!!!
so, i begin again ! i rushed on your code, and found your sample magnifier nice and tidy.
However, it appears to zoom the actual displayobject in a (fake) manner…leading to pixellisation for any higher than 1x zoom factor.
To me, your source sample image being 1024 x 768 pixels (and movieclip adjusted to 530 x 400 pixels), that makes a 2x factor zoom indeed possible with nearly no pixellisation.
I cannot figure out how to adapt your piece of code for this behavior to happen… would you have a clue ?
Many thanks in advance.
Marc (Paris)
try using a much larger image – and leave it at its normal size – and then put all of this into another movieclip and scale it down – so you have the effect in a large version but scaled down all in all – this would show the displacement in better way
does anyone know how to get rid of the little square inside of the bigger square zoom bug?
good tutorial