Wrapping BitmapData in Actionscript 3
![]() |
|
| Pattern | Flash Example (mouseclick then cursor keys) |
Sometimes you overlook the easiest solutions. I had implemented a wrapping bitmap in actionscript 2, by some complex copyPixels code, which would cut 1 to 4 pieces from the original image and put them together again, providing you with a bitmap that wraps.
Then I realized that there is a much easier solution, with more functionality as well (not only wrapping but tiling too). But surprised however that it performed much better too. Surprised because I would have thought that 4 copyPixel operations would have been faster than using the drawing API combined with beginBeginFill.
I’ve wrapped (no pun intended) the idea into two utility classes, the first WrappingBitmap is a simple sprite which takes a bitmapdata as source and creates a tiling wrapping display object that you can scroll.
The second is a WrappingBitmapData class which subclasses BitmapData and overrides the scroll method to wrap.
The demo is the pattern above, with the source image next to it. Click on the demo to give it focus and scroll using the cursor keys. You can see there is a quality difference, so you might want to change the bitmapfill smooth parameter to true.
You can download the example here: Wrappingbitmap (142).
{
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;
/**
* Implements a sprite that shows the source bitmap wrapped and allows you to scroll through it preserving the
* wrapping.
*
* @author JC Wichman
*/
public class WrappingBitmap extends Sprite
{
private var _bitmapdata:BitmapData = null;
private var _width:Number = 0;
private var _height:Number = 0;
private var _matrix:Matrix = null;
public function WrappingBitmap(pBitmapData:BitmapData, pWidth:Number = -1, pHeight:Number = -1, pOffset:Point = null)
{
_bitmapdata = pBitmapData;
_width = (pWidth > 0)?pWidth:pBitmapData.width;
_height =(pHeight> 0)?pHeight:pBitmapData.height;
_matrix = new Matrix();
if (pOffset != null) {
_matrix.tx = -pOffset.x;
_matrix.ty = -pOffset.y;
}
_paint();
}
private function _paint():void {
graphics.clear();
graphics.beginBitmapFill (_bitmapdata, _matrix, true, false);
graphics.drawRect (0, 0, _width, _height);
graphics.endFill();
}
public function scroll (dx:Number, dy:Number):void {
_matrix.tx += dx;
_matrix.ty += dy;
_paint();
}
public function scrollTo (x:Number, y:Number):void {
_matrix.tx = -x;
_matrix.ty = -y;
_paint();
}
public function grab(pDestination:BitmapData = null):BitmapData {
var lResult:BitmapData = pDestination || new BitmapData (_width, _height, _bitmapdata.transparent, 0);
lResult.draw (this);
return lResult;
}
}
}
{
import flash.display.BitmapData;
import flash.geom.Point;
/**
* Can be plugged in a bitmap, turning the bitmap into a wrapped scrolling bitmap, eg:
* bitmap.bitmapData = new WrappingBitmapData (bitmap.bitmapData);
*
* @author JC Wichman
*/
public class WrappingBitmapData extends BitmapData
{
private var _wrappingbitmap:WrappingBitmap = null;
public function WrappingBitmapData(pSource:BitmapData)
{
super (pSource.width, pSource.height, pSource.transparent, 0×0);
_wrappingbitmap = new WrappingBitmap (pSource);
_wrappingbitmap.grab (this);
}
override public function scroll (x:int, y:int) : void {
_wrappingbitmap.scroll (x, y);
_wrappingbitmap.grab(this);
}
}
}

July 30th, 2011 at 3:09 pm
Great info, thanks.
The one thing I found is that the graphics.clear() function doesn’t clear the beginBitmapFill() from the previous call.
If you have an image with sections that are totally transparent, they don’t get cleared out and you can see the old positions in the updated position (they bleed through).
Any thoughts? Thanks again.
July 30th, 2011 at 5:18 pm
I found the solution. In the ‘grab’ function of the WrappingBitmap, I needed this before the draw call:
lResult.fillRect(lResult.rect, 0×0);
Thanks again.
January 16th, 2012 at 11:59 pm
Thanks for this usefull class
!
However, I just added thoses lines in the paint method :
_matrix.tx = _matrix.tx % _width;
_matrix.ty = _matrix.ty % _height;
Indeed, there’s a really short limitation due to bitmapFill (i guess), if you go over something like 32.000, the scroll freezes. The matrix.tx value still grows but the scrolling is locked.
Adding those lines prevents from that easily
Thanks for this neat scrolling solution !