BlitMask – Scroll up to 1000% faster
- Version: 0.6, Updated 2012-01-20
A BlitMask is basically a rectangular Sprite that acts as a high-performance mask for a DisplayObject by caching a bitmap version of it and blitting only the pixels that should be visible at any given time, although its bitmapMode can be turned off to restore interactivity in the DisplayObject whenever you want. When scrolling very large images or text blocks, BlitMask can greatly improve performance, especially on mobile devices that have weaker processors. (UPDATE: a Flex-friendly version of BlitMask called FlexBlitMask was added in version 0.44)
Think of it like a window through which you see the object.
Interactive example
Over 1000% performance improvement?
When a simple tween of a large TextField was tested on an iPhone 3GS, the frame rate jumped from 3fps using a regular mask to 55fps using BlitMask. On the iPad, we signifcantly increased the scrolling area so that more pixels needed to be rendered on each frame, but there was still a massive increase in the frame rate from 3fps to almost 29fps. See the video below (special thanks to Jonah Simon for the video).
On an Android-based phone (Droid 2) the fps jumped from 6.5 to 46.5. The improvements are less dramatic on regular computers because they have much beefier processors, but I ran a slightly different test with a heavier load on an Intel Core i3 computer and had the fps jump from 5fps with a regular mask to 59fps with BlitMask, so the 1000% improvement can still happen on regular computers in certain scenarios.
Of course your mileage will vary – the bigger, more complex your object (especially if it has text and vectors), the bigger the improvement you’ll see with BlitMask. And keep in mind that you’ll only see a speed improvement when bitmapMode is on. When it’s off, BlitMask just acts like a standard mask in Flash. The benefit of turning bitmapMode off is that your object (the target DisplayObject that’s being masked) will have its interactivity restored, meaning MouseEvents can be triggered inside that target like rollovers, clicks, etc. A common technique would be to turn bitmapMode on while you’re scrolling/animating the object (to maximize performance), and then turn it back off afterwards. There’s even convenient enableBitmapMode() and disableBitmapMode() methods that you can connect to your tweens like
var myBlitMask:BlitMask = new BlitMask(mc, 50, 50, 200, 200);
TweenLite.to(mc, 2, {x:100, y:200, onStart:myBlitMask.enableBitmapMode, onUpdate:myBlitMask.update, onComplete:myBlitMask.disableBitmapMode});
Features
- Excellent scrolling performance
- You don’t need to do anything special with your target DisplayObject – move/scale/rotate it however you please and then update() the BlitMask and it syncs the pixels. The BlitMask basically sits on top of the DisplayObject in the display list and you can move it independently too if you want.
- Use the BlitMask’s scrollX and scrollY properties to move the target DisplayObject inside the masked area. For example, to scroll from top to bottom over the course of 2 seconds, simply do:
myBlitMask.scrollY = 0; TweenLite.to(myBlitMask, 2, {scrollY:1}); - BlitMask accommodates rotated and scaled content whereas scrollRect doesn’t (well, it does, but as you can see in the example above, the rectangular masked area rotates with the target and scaling affects it too).
- Use the wrap property to make the bitmap wrap around to the opposite side when it scrolls off one of the edges (only in bitmapMode of course), as though the BlitMask is filled with a grid of bitmap copies of the target.
- Turn smoothing on to enable sub-pixel rendering (better quality in most situations) or turn it off for maximum performance.
- You can toggle the bitmapMode to get either maximum performance or interactivity in the target DisplayObject anytime. (some other solutions out there are only viable for non-interactive content)
- MouseEvents are dispatched by the BlitMask, so you can listen for clicks, rollovers, rollouts, etc.
How exactly does it work?
One of the most processor-intensive tasks for the Flash Player is calculating which pixels need to change on the screen and then rendering them. So let’s say you’ve got a TextField that’s 2,500 pixels wide and 2,500 pixels tall (that’s a lotta text). Whenever you move it even one pixel, Flash must process all 6,250,000 pixels and figure out where they’d be on the new frame (even the ones that are off screen) and then display them appropriately. That requires tons of work, most of which is totally unnecessary when you’re only wanting to display a small fraction of those pixels inside a masked area. BlitMask allows Flash to just worry about the pixels inside the masked area.
When in bitmapMode, the BlitMask sets the target’s visible property to false so that Flash doesn’t need to worry about rendering its pixels. It takes a bitmap capture of the target and copies only the necessary pixels onto the rectangular area of its (the BlitMask’s) graphics layer. You can move the target wherever you want and then simply call the BlitMask’s update() method to have it look at where the target is and copy the necessary pixels into itself (refreshing the display to synchronize with the target’s position). When the target changes its rotation or scale, the internal bitmap must be recaptured (try to avoid this if possible because it degrades performance). BlitMask will automatically check to see if the scale or rotation changed since the last update() and if so, it’ll recapture the bitmap. You can force a recapture using the 2nd parameter of the update() method, like update(null, true).
When bitmapMode is set to false, BlitMask automatically turns on the target’s visible property and sets its mask property to the BlitMask. Consequently, performance degrades but interactivity is restored to the target. Visually things should be relatively seamless.
Documentation
View the full ASDocs here.
Sample AS3 code
import com.greensock.*;
//create a 200x200 BlitMask positioned at x:20, y:50 to mask our "mc" object and turn smoothing on:
var blitMask:BlitMask = new BlitMask(mc, 20, 50, 200, 200, true);
//animate mc and make sure the BlitMask updates
TweenLite.to(mc, 5, {x:-300, y:50, onUpdate:blitMask.update});
//or position mc at the top left of the BlitMask using the scrollX and scrollY properties
blitMask.scrollX = 0;
blitMask.scrollY = 0;
//tween the scrollY to make mc scroll to the bottom over the course of 3 seconds and then turn off bitmapMode so that mc becomes interactive:
TweenLite.to(blitMask, 3, {scrollY:1, onComplete:blitMask.disableBitmapMode});
//or simply position mc manually and then call update() to sync the display:
mc.x = 350;
blitMask.update();
Video tutorial
Check out Carl Schooff’s video tutorial covering BlitMask. It’s a great starting point.
Hidden benefit: objects with filters tween smoother
Smooth animation isn’t just about reducing the load on the CPU. Without BlitMask, if you apply a filter (i.e. GlowFilter, DropShadowFilter, etc.) to an object and then tween its coordinates slowly, you’ll notice jerky movement because Flash only allows the object to render on whole pixel coordinates. However, with BlitMask and its smoothing feature, sub-pixel rendering is possible, making these types of animations significantly smoother visually. See the example below:
FAQ
- When should I NOT use BlitMask?
It doesn’t make much sense to use BlitMask when the target is smaller than the BlitMask or if you must maintain interactivity in child DisplayObjects even during scrolling/animation. While animating the scale or rotation of the target, there isn’t benefit in using bitmapMode either because the internal bitmap would need to keep getting recaptured on each frame/render. - Can I use BlitMask with ThrowPropsPlugin for better flick-scrolling performance?
Absolutely. See the ThrowPropsPlugin page for more information about flick-scrolling. The interactive example there has been updated to use BlitMask. - Can I use BlitMask in Flex?
Sure, a Flex-friendly version of BlitMask is now available called FlexBlitMask that extends UIComponent instead of Sprite in order to be…well…Flex-friendly. See the ASDocs here. - Can I animate the BlitMask itself?
Definitely, but you shouldn’t alter its rotation. Feel free to tween its x, y, width, and height properties. Doing so will automatically update() the BlitMask too. - Wait, I thought Flash didn’t work on iPads or iPhones – how did you do that?
You can publish apps for iOS devices with Flash (which is what we did here for the tests) but you still can’t view .swf files on web pages. - I’m animating my target but it doesn’t seem to be working. What’s wrong?
I bet you forgot to call update() each time you moved the target. For a tween, use the onUpdate like//don't forget the onUpdate TweenLite.to(mc, 3, {x:100, y:200, onUpdate:myBlitMask.update}); - Can’t I just set the target DisplayObject’s cacheAsBitmap property to true and get the same result? Why use BlitMask?
If you set a DisplayObject’s cacheAsBitmap property to true, Flash takes a bitmap capture of that object so that when you move it (only altering the x and/or y properties), the text and vectors don’t need to be re-rasterized again before being rendered to the screen. However, Flash would still need to concern itself with extra pixels on every frame if you’re masking them to only show a small portion of the area. BlitMask, however, only cares about that smaller masked area (after the initial capture of course) which alleviates Flash from having to even think about the extra pixels. - Is the API locked-down or might it change?
No changes are planned to the API right now, but this is a brand new tool and I’d consider it somewhat experimental at this point. I’m committed to making improvements and enhancements if the need arises as it gets out into the wild and folks provide feedback. So yes, there could definitely be some changes down the road. Please feel free to submit your feedback and suggestions. - Do I have to purchase a license to use this code? Can I use it in commercial projects?
You may use the code at no charge in commercial or non-commercial web sites, games, components, applications, and other software as long as end users are not charged a fee of any kind to use your product or gain access to it. If your client pays you a one-time fee to create the site/product, that’s perfectly fine and qualifies under the “no charge” license. If multiple end users are charged a usage/access/license fee of any kind, please simply sign up for a corporate Club GreenSock membership which comes with a special commercial license granting you permission to do so. Click here for details. Club GreenSock members get several useful bonus plugins, classes, update notifications, SVN access, and more. Please see the licensing page for details on licensing.
Need help?
Feel free to post your question on the forums. You’ll increase your chances of getting a prompt answer if you provide a brief explanation and include a simplified FLA file (and any class files) that clearly demonstrates the problem.
Comments (47)

Highly impressive results, Jack. I can see this coming in very handy in the near future!
A big thank you for your continuing additions to Greensock, just completely awesome!
Best Wishes
Merrick
You made it again, Jack. Kudos to you! I’ve been looking for such a solution for weeks.
Wow, no more slow flash scrolling
*Jack earn 1000 exp points*
*Jack levels up*
Nice! This will make me experiment with Flash in iPad again
Thanks Jack
Exactly what I was needing 2 weeks ago !
I did the blit with “my hand”
So many thanks guys and very good job !
New tech!! You know we love new tech. This is soo awesome, and in perfect time for a new project too. Cheers again Jack!
Very clever solution.
Congratulations. Very good job as usual.
Thank you Jack.
COOL man!!!
How do u make it???
Thanks Jack. Looks good!
Great findings Jack!
I am actually quite surprised how scrollRect with cacheAsBitmap set performs so slow. I’ve experimented with cached Bitmap and scrollRect (as did Jackson http://jacksondunstan.com/articles/629) and it was the fastest method (no need to use copyPixels or anything) regardless of the source bitmapData size. Have you tried that?
Uh. This is great but I’m sorry, I am apparently living under a rock. I thought Flash didn’t work on an iPad.
This is brilliant, just like everything else you create. I’m actually somewhat shocked at the results, I knew Flash’s masking was bad, but I didn’t realize it was that bad… which makes your solution even better.
Well played sir.
Really great!
That’s so useful for mobile development. Adobe guys should hire you for Flash CS6.
Great work as usual. I have a project I can implement this in right now to improve text scrolling performance.
Really useful!! thanks!! =)
Very cool! Thanks Jack!
As always, you rock!
Very excited about this! Fantastic work as always, Jack!
Ok this is the best thing since Bacon and sliced bread! Thanks Jack.
Ok now I have to make a retro side scroller shoot em up.
Simply amazing! Thanks Jack
Thx a lot, it will be really usefull
Og2t, scrollRect is certainly faster than a regular mask, but it’s still not quite as fast as BlitMask in most situations and there are several liabilities of using scrollRect:
It only allows whole pixel values. No sub-pixel rendering (smoothing).
You can’t rotate the content within the masked area (the whole mask rotates with the content)
I think most developers find working with scrollRect to be cumbersome and confusing.
You can’t easily scale the content inside the mask (well, you could but you’d have to counteract the scale by adjusting the scrollRect in the opposite direction at the same time to make it look like the mask was stationary)
But if you don’t have a scaled or rotated target and you don’t need smoothing, scrollRect is perfectly acceptable. TweenLite’s ScrollRectPlugin makes tweening it pretty simple too. Plus it maintains interactivity inside the target.
Otto, you’re not the only one to ask about that. I just added the answer in the FAQ section above. iOS devices don’t technically run Flash as a plugin, but you can publish native iOS apps using Flash which is what we did for the tests I mentioned above.
THANKS GOD WE HAVE JACK!
Really great work, perfect!
Very good! Excelent work and just the right timing – I think many of us guys will give it a go on mobile devices.
And who knows, maybe one day we will find a full blitting engine here too
Heys, this is pretty sweet, keep it up, love your work!
The time you have saved me Jack…Cheers!
Question: without using BlitMask, If a MovieClip’s visibility is set to false, does Flash still think about it?
Ex: If I have 10,000 boxes moving around and set the visibility to false on the boxes outside of the stage’s view, will it perform better than just leaving all of them with visible = true?
I guess I could just try it myself but I would also like to know WHY or WHY NOT?
Yes, Colin, when you set a DisplayObject’s “visible” property to false, Flash basically ignores it when running through its graphics rendering routines. If you’ve got 10,000 boxes moving around and they all have visible set to false, it saves Flash from having to even think about rendering them. If you are tweening their properties, though, it still takes some time to set/apply those values (not much).
Please Jack .. a Flex version .. please .. just like your other products like FlexTransformManager , please !
[...] do justice to all the robust features of the BlitMask in a single post so please read The Official BlitMask Information Page and the BlitMask [...]
Is There Any Chance Getting This Result On Flex
Sure, Synxmax, your wish is my command
There’s now a FlexBlitMask class in the downloads that’s identical to BlitMask, but it extends UIComponent instead of Sprite and implements a few other necessities in order to be Flex-friendly. Enjoy!
Your Are The Man , Thank You Jack
Soon I Am One Of Your Club Member
And It’s All My Pleasure
Thank You Again
Thanks mate, I’m making a musical scorewriting program which involves thousands of bars of music being on display at once so this was absolutely invaluable, and surprisingly even faster than adding and removing display objects as they come into view
Kudos!
Its great to have awesome contributors like you in this world.
How about some stage3D versions.
How come you are moving a bitmap underneath a mask? Are there significant performance differences compared to the copyPixels technique, and drawing it into BitmapData?
Cheers,
Rory
Rory, I’m not quite sure what you’re referring to – BlitMask does use copyPixels and a BitmapData. When you turn its bitmapMode off, however, it switches to be a regular mask of the target which has the [very important] benefit of allowing interactivity inside the target. So ultimately BlitMask delivers a lot of flexibility and performance with options for various scenarios.
Awesome! Just tested on ipad. Bitmap is quite fast.
1. casheAsBitmap didn’t helped for my SWFLoader content. But your component really works.
2. I noticed app crash on ipad 1 when scaling content too much. I guess it is related to bitmap size limitation.
3. I do use bitmapMode=true/false when mouseMove started/finished. Setting bitmapMode to true makes performance hit. Is there way make it smoother? I think it’s possible by keeping updating bitmap at the background (or not recreating it).
Thanks a lot!
The only reason I can think of that you’d experience a performance hit when bitmapMode is true is if you’re scaling or rotating the target which forces the BlitMask to recapture the entire bitmap. Otherwise, you should see a nice performance improvement.
Can i move textFields using BlitMask, or only movieClips?
Sure, BlitMask works for ANY DisplayObject including TextFields.
Hello, great man!
I really appreciate all the efforts for BlitMask!
I only want a clarification about this statement:
“You may use the code at no charge in commercial or non-commercial web sites, games, components, applications, and other software as long as end users are not charged a fee of any kind to use your product or gain access to it.”
But, if it is a commercial game (in this case, a product), how could I sell it, regaining money from my efforts making the game and all the developers also involved on it? If the game is provided free of charge, it loses the commercial purpose, thus being a free game.
Thanks!
Fair question, Ivan – what we meant was that you could create a one-off game for a client where you get paid a one-time fee for it by a single client who then distributes it for free to their audience. Technically there’s a commercial component of that equation because you got paid, but since money only changed hands once and end users aren’t paying any fees, it’s covered under the standard “no charge” license. If you’d like to create a game that gets resold, all you need to do is sign up for the appropriate “Business Green” Club GreenSock membership at http://www.greensock.com/club/ which gets you the commercial license and a bunch of other benefits.
Thanks for asking!
Great stuff, but if rotation (and 3D rotations are) supported, it will be great. Do you have any plan to implement this feature?
Thanks!
Jon, I can’t see how that would be possible to do – it would completely defeat the purpose (performance). Feel free to let us know if you’ve got any specific ideas about how it could be accomplished.




















Download zip