123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- package h2d;
- /**
- Restricts rendering area within the `[width, height]` rectangle.
- For more advanced masking, see `h2d.filter.AbstractMask`.
- Rotation of the mask does not rotate the masked area and instead causes it to cover the bounding box of the mask.
- The `Mask.maskWidth` and `Mask.unmask` can be used to mask out rendering area without direct usage of Mask instance in-between.
- **/
- class Mask extends Object {
- /**
- Masks render zone based off object position and given dimensions.
- Should call `Mask.unmask()` afterwards.
- @param ctx The render context to mask.
- @param object An Object which transform will be used as mask origin.
- @param width The width of the mask in scene coordinate space.
- @param height The height of the mask in scene coordinate space.
- @param scrollX Additional horizontal offset of the masked area.
- @param scrollY Additional vertical offset of the masked area.
- **/
- @:access(h2d.RenderContext)
- public static function maskWith( ctx : RenderContext, object : Object, width : Int, height : Int, scrollX : Float = 0, scrollY : Float = 0) {
- var x1 = object.absX + scrollX;
- var y1 = object.absY + scrollY;
- var x2 = width * object.matA + height * object.matC + x1;
- var y2 = width * object.matB + height * object.matD + y1;
- var tmp;
- if (x1 > x2) {
- tmp = x1;
- x1 = x2;
- x2 = tmp;
- }
- if (y1 > y2) {
- tmp = y1;
- y1 = y2;
- y2 = tmp;
- }
- ctx.flush();
- ctx.clipRenderZone(x1, y1, x2-x1, y2-y1);
- }
- /**
- Unmasks the previously masked area from `Mask.maskWith`.
- @param ctx The render context to unmask.
- **/
- public static function unmask( ctx : RenderContext ) {
- ctx.flush();
- ctx.popRenderZone();
- }
- /**
- The width of the masked area.
- **/
- public var width : Int;
- /**
- The height of the masked area.
- **/
- public var height : Int;
- /**
- Horizontal scroll offset of the Mask content in pixels. Can be clamped by `Mask.scrollBounds`.
- **/
- public var scrollX(default, set) : Float = 0;
- /**
- Vertical scroll offset of the Mask content in pixels. Can be clamped by `Mask.scrollBounds`.
- **/
- public var scrollY(default, set) : Float = 0;
- /**
- Optional scroll boundaries that prevent content from overscroll.
- **/
- public var scrollBounds : h2d.col.Bounds;
- /**
- Create a new Mask instance.
- @param width The width of the masked area.
- @param height The height of the masked area.
- @param parent An optional parent `h2d.Object` instance to which Mask adds itself if set.
- **/
- public function new(width, height, ?parent) {
- super(parent);
- this.width = width;
- this.height = height;
- }
- /**
- Scroll the Mask content to the specified offset.
- **/
- public function scrollTo( x : Float, y : Float ) {
- scrollX = x;
- scrollY = y;
- }
- /**
- Scroll the Mask content by the specified offset relative to the current scroll offset.
- **/
- public function scrollBy( x : Float, y : Float ) {
- scrollX += x;
- scrollY += y;
- }
- function set_scrollX( v : Float ) : Float {
- if ( scrollBounds != null ) v = hxd.Math.clamp(v, scrollBounds.xMin, scrollBounds.xMax - width);
- posChanged = true;
- return scrollX = v;
- }
- function set_scrollY( v : Float ) : Float {
- if ( scrollBounds != null ) v = hxd.Math.clamp(v, scrollBounds.yMin, scrollBounds.yMax - height);
- posChanged = true;
- return scrollY = v;
- }
- override function calcAbsPos() {
- super.calcAbsPos();
- absX -= scrollX;
- absY -= scrollY;
- }
- override function getBoundsRec( relativeTo, out:h2d.col.Bounds, forSize ) {
- var xMin = out.xMin, yMin = out.yMin, xMax = out.xMax, yMax = out.yMax;
- out.empty();
- if( posChanged ) {
- calcAbsPos();
- for( c in children )
- c.posChanged = true;
- posChanged = false;
- }
- addBounds(relativeTo, out, scrollX, scrollY, width, height);
- var bxMin = out.xMin, byMin = out.yMin, bxMax = out.xMax, byMax = out.yMax;
- out.xMin = xMin;
- out.xMax = xMax;
- out.yMin = yMin;
- out.yMax = yMax;
- super.getBoundsRec(relativeTo, out, forSize);
- if( out.xMin < bxMin ) out.xMin = hxd.Math.min(xMin, bxMin);
- if( out.yMin < byMin ) out.yMin = hxd.Math.min(yMin, byMin);
- if( out.xMax > bxMax ) out.xMax = hxd.Math.max(xMax, bxMax);
- if( out.yMax > byMax ) out.yMax = hxd.Math.max(yMax, byMax);
- }
- override function drawRec( ctx : h2d.RenderContext ) @:privateAccess {
- maskWith(ctx, this, width, height, scrollX, scrollY);
- super.drawRec(ctx);
- unmask(ctx);
- }
- }
|