Bläddra i källkod

Implement Mask.scroll (#744)

Pavel Alexandrov 5 år sedan
förälder
incheckning
bae8089083
2 ändrade filer med 72 tillägg och 5 borttagningar
  1. 54 4
      h2d/Mask.hx
  2. 18 1
      samples/Mask.hx

+ 54 - 4
h2d/Mask.hx

@@ -6,12 +6,43 @@ class Mask extends Object {
 	public var height : Int;
 	var parentMask : Mask;
 
+	/**
+		Horizontal scroll offset of the Mask content in pixels. Can be clamped by `scrollBounds`.
+	**/
+	public var scrollX(default, set) : Float = 0;
+	/**
+		Vertical scroll offset of the Mask content in pixels. Can be clamped by `scrollBounds`.
+
+	**/
+	public var scrollY(default, set) : Float = 0;
+
+	/**
+		Optional scroll boundaries that prevent content from overscroll.
+	**/
+	public var scrollBounds : h2d.col.Bounds;
+
 	public function new(width, height, ?parent) {
 		super(parent);
 		this.width = width;
 		this.height = height;
 	}
 
+	/**
+		Scroll Mask content to specified offset.
+	**/
+	public function scrollTo( x : Float, y : Float ) {
+		scrollX = x;
+		scrollY = y;
+	}
+
+	/**
+		Scroll Mask content by specified offset relative to current scroll offset.
+	**/
+	public function scrollBy( x : Float, y : Float ) {
+		scrollX += x;
+		scrollY += y;
+	}
+
 	override private function onHierarchyMoved(parentChanged:Bool) {
 		super.onHierarchyMoved(parentChanged);
 		if ( parentChanged )
@@ -36,6 +67,25 @@ class Mask extends Object {
 		}
 	}
 
+	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();
@@ -59,11 +109,11 @@ class Mask extends Object {
 	}
 
 	override function drawRec( ctx : h2d.RenderContext ) @:privateAccess {
-		var x1 = absX;
-		var y1 = absY;
+		var x1 = absX + scrollX;
+		var y1 = absY + scrollY;
 
-		var x2 = width * matA + height * matC + absX;
-		var y2 = width * matB + height * matD + absY;
+		var x2 = width * matA + height * matC + x1;
+		var y2 = width * matB + height * matD + y1;
 
 		var tmp;
 		if (x1 > x2) {

+ 18 - 1
samples/Mask.hx

@@ -1,12 +1,20 @@
 class Mask extends hxd.App {
 
 	var obj : h2d.Object;
+	var mask : h2d.Mask;
 	var time : Float = 0.;
 
 	override function init() {
-		var mask = new h2d.Mask(160, 160, s2d);
+		mask = new h2d.Mask(160, 160, s2d);
 		mask.x = 200;
 		mask.y = 150;
+
+		// Mask-sized rectangle to display mask boundaries
+		// and make scroll movement more apparent.
+		new h2d.Bitmap(h2d.Tile.fromColor(0x222222, mask.width, mask.height), mask);
+		// Limit scroll
+		mask.scrollBounds = h2d.col.Bounds.fromValues(-mask.width/2, -mask.height/2,mask.width*2, mask.height*2);
+
 		obj = new h2d.Object(mask);
 		obj.x = obj.y = 80;
 		for( i in 0...10 ) {
@@ -15,11 +23,20 @@ class Mask extends hxd.App {
 			b.x = Std.random(200) - 100;
 			b.y = Std.random(200) - 100;
 		}
+		var info = new h2d.Text(hxd.res.DefaultFont.get(), s2d);
+		info.setPosition(5, 5);
+		info.text = "Arrows: move scrollX/Y\nSpace: reset scroll to 0,0";
+
 	}
 
 	override function update(dt:Float) {
 		time += dt;
 		obj.rotation += 0.6 * dt;
+		if (hxd.Key.isDown(hxd.Key.LEFT)) mask.scrollX -= 100 * dt;
+		if (hxd.Key.isDown(hxd.Key.RIGHT)) mask.scrollX += 100 * dt;
+		if (hxd.Key.isDown(hxd.Key.UP)) mask.scrollY -= 100 * dt;
+		if (hxd.Key.isDown(hxd.Key.DOWN)) mask.scrollY += 100 * dt;
+		if (hxd.Key.isReleased(hxd.Key.SPACE)) mask.scrollTo(0, 0);
 	}
 
 	static function main() {