While working on my first collaborative game project with Plugin.IO, I was finding it frustrating that we are unable to do in Starling some of the clipping and scrolling features that Flash’s traditional DisplayObjects supports, in a user-friendly manner.

So, what did I do? Basically, I’ve popped the hood and verified how things worked inside (oh, and I’ve done this several times now!).

There is two very useful methods you can use on an Image’s protected mVertexData property, they are:

.setPosition(), and

Since that, in Starling, each Images is basically a Quad, you know there is a total of four (4) vertices you can manipulate. By changing each Vertices’s position and texture coordinates appropriately, we can bring back our beloved scrolling and clipping functionality!

Here is a class I put together that enables you to change the scroll and the clipping edges to your needs.

package starling.display {
	import flash.geom.Rectangle;
	import starling.textures.Texture;
	 * An Image class that supports Scrolling and Clipping effortlessly (Finally!)
	 * @author Pierre Chamberlain
	public class ScrollImage extends Image {
		private var _scrollX:Number = 0;
		private var _scrollY:Number = 0;
		private var _clipMask:Rectangle;
		public function ScrollImage(texture:Texture) {
			texture.repeat =	true;
			_clipMask =		new Rectangle(0, 0, width, height);
		public override function dispose():void {
			if (_clipMask) {
				_clipMask =		null;
		private function updateUVs():void {
			var ratioX:Number =	1 / texture.width;
			var ratioY:Number =	1 / texture.height;
			mVertexData.setPosition(0, _clipMask.left,;
			mVertexData.setPosition(1, _clipMask.right,;
			mVertexData.setPosition(2, _clipMask.left, _clipMask.bottom);
			mVertexData.setPosition(3, _clipMask.right, _clipMask.bottom);
			var scrollLeft:Number =		(_scrollX + _clipMask.left) * ratioX;
			var scrollTop:Number =		(_scrollY + * ratioY;
			var scrollRight:Number =	(_scrollX + _clipMask.right) * ratioX;
			var scrollBottom:Number =	(_scrollY + _clipMask.bottom) * ratioY;
			mVertexData.setTexCoords(0, scrollLeft, scrollTop);
			mVertexData.setTexCoords(1, scrollRight, scrollTop);
			mVertexData.setTexCoords(2, scrollLeft, scrollBottom);
			mVertexData.setTexCoords(3, scrollRight, scrollBottom);
		public function get scrollX():int { return _scrollX; }
		public function set scrollX(value:int):void {
			_scrollX = value % texture.width;
		public function get scrollY():int { return _scrollY; }
		public function set scrollY(value:int):void {
			_scrollY = value % texture.height;
		public function get clipMaskLeft():Number { return _clipMask.left; }
		public function set clipMaskLeft(n:Number):void {
			_clipMask.left = n;
		public function get clipMaskTop():Number { return; }
		public function set clipMaskTop(n:Number):void { = n;
		public function get clipMaskRight():Number { return _clipMask.right; }
		public function set clipMaskRight(n:Number):void {
			_clipMask.right = n;
		public function get clipMaskBottom():Number { return _clipMask.bottom; }
		public function set clipMaskBottom(n:Number):void {
			_clipMask.bottom = n;

How it works

In the picture above, you can see that by changing the clipMask side values, you can zero-in on just the portion of the image you wish to crop. Additionally, if you change the scrollX and scrollY, it will preserve everything else that you changed with the clipMask.

Neat eh?

Feel free to use this class (at your own risk! haha)