Skip to content

Instantly share code, notes, and snippets.

@ORBAT
Forked from PrimaryFeather/ClippedSprite.as
Last active December 22, 2015 00:39
Show Gist options
  • Save ORBAT/6390502 to your computer and use it in GitHub Desktop.
Save ORBAT/6390502 to your computer and use it in GitHub Desktop.
Starling ClippedSprite but with local coordinates for the clipRect;
package starling.extensions
{
import flash.display3D.Context3D;
import flash.geom.Point;
import flash.geom.Rectangle;
import starling.core.RenderSupport;
import starling.core.Starling;
import starling.display.DisplayObject;
import starling.display.Sprite;
import starling.errors.MissingContextError;
/**
* Extends Starling's <code>Sprite</code> class by adding a clipping rectangle. The clipping rectangle uses the local
* coordinate system, <i>not</i> the stage's.
*
* Based on https://gist.github.com/PrimaryFeather/2422317
*/
public class ClippedSprite extends Sprite
{
private var mClipRect:Rectangle = new Rectangle();
/**
* @private
* Temporary storage.
*/
private var mLocalXY:Point;
/**
* @private
* Temporary storage.
*/
private var mGlobalXY:Point = new Point();
/**
* @private
* Temporary storage.
* The <i>local</i> width is stored in the <code>x</code> field, height in <code>y</code>.
*/
private var mLocalWidthLength:Point;
/**
* @private
* Temporary storage.
* The <i>global</i> width is stored in the <code>x</code> field, height in <code>y</code>.
*/
private var mGlobalWidthLength:Point = new Point();
private var mTempGlobalPoint:Point = new Point();
/**
* Set a clipping rectangle to be used with this ClippedSprite. Uses the <i>local</i> coordinate system instead
* of stage coordinates.
* @param value
*/
public function set clipRect(value:Rectangle):void {
if(value == null) {
mClipRect = null;
return;
}
mLocalXY = value.topLeft;
mLocalWidthLength = value.size;
localToGlobal(mLocalXY, mGlobalXY);
localToGlobal(mLocalWidthLength, mGlobalWidthLength)
mClipRect.setTo(mGlobalXY.x, mGlobalXY.y,
mGlobalWidthLength.x, mGlobalWidthLength.y);
}
public override function render(support:RenderSupport, alpha:Number):void
{
if (mClipRect == null) super.render(support, alpha);
else
{
var context:Context3D = Starling.context;
if (context == null) throw new MissingContextError();
support.finishQuadBatch();
support.scissorRectangle = mClipRect;
super.render(support, alpha);
support.finishQuadBatch();
support.scissorRectangle = null;
}
}
public override function hitTest(localPoint:Point, forTouch:Boolean = false):DisplayObject {
// without a clip rect, the sprite should behave just like before
if(mClipRect == null) return super.hitTest(localPoint, forTouch);
// on a touch test, invisible or untouchable objects cause the test to fail
if(forTouch && (!visible || !touchable)) return null;
var scale:Number = Starling.current.contentScaleFactor;
localToGlobal(localPoint, mTempGlobalPoint);
if(mClipRect.contains(mTempGlobalPoint.x * scale, mTempGlobalPoint.y * scale))
return super.hitTest(localPoint, forTouch);
else
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment