Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Rolf

Problem when calling TransformAroundPoint

Recommended Posts

Hi 

I'm trying to scale a bitmap with TransformAroundPoint. When I call TransformAroundPoint multible times it seems to move the bitmap away from the original position. 

 

I've made an example that shows the problem: 

A semi transparent red square is scaled up and down 80 % a 100 times and when completed it's scaled back to 100% again. 

In the background a square is illustrating the original position. When the scaling is completed the two squares should be on top of each other .. but they aren't?

 

I hope you can help figure out what the problem is. 

package {
	import com.greensock.TweenMax;
	import com.greensock.plugins.TransformAroundCenterPlugin;
	import com.greensock.plugins.TransformAroundPointPlugin;
	import com.greensock.plugins.TweenPlugin;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.geom.Point;
	
	public class Dev extends MovieClip {
		private var boxBmp:Bitmap; 
		private var centerPoint:Point; 
		private var count:int = 0; 
		private var bgBoxBmp:Bitmap;
		
		public function Dev() {
			
			TweenPlugin.activate([TransformAroundPointPlugin]);
			TweenPlugin.activate([TransformAroundCenterPlugin]);
			
			centerPoint = new Point(1024/2, 768/2);
			
			var bgBmd:BitmapData = new BitmapData(100,100, false, 0xCCCCCC);
			bgBoxBmp = new Bitmap(bgBmd);
			this.addChild(bgBoxBmp);
			
			var boxBmd:BitmapData = new BitmapData(100,100, false, 0xFF0000);
			 
			boxBmp = new Bitmap(boxBmd);
			boxBmp.alpha = 0.5;
			
			this.addChild(boxBmp);
			
			// center on screen (1024 x 768)
			
			bgBoxBmp.x = centerPoint.x - bgBoxBmp.width/2; 
			bgBoxBmp.y = centerPoint.y - bgBoxBmp.height/2;
			
			boxBmp.x = centerPoint.x - boxBmp.width/2; 
			boxBmp.y = centerPoint.y - boxBmp.height/2;
			
			trace("start position boxBmp.x=" + boxBmp.x);
			trace("start position boxBmp.y=" + boxBmp.y);
			
			
			nextTween(0.8);
			
		}
		
		private function nextTween(_scalePct:Number ):void {
			count++; 			
			var scaleTo:Number = 1+_scalePct;
			
			TweenMax.killTweensOf(boxBmp);
			
			if(count <= 100) {
				TweenMax.to(boxBmp, 0.25, {transformAroundPoint:{point:centerPoint, scaleX:scaleTo, scaleY:scaleTo}, onComplete:nextTween, onCompleteParams:[_scalePct*-1]});
			} else {
				TweenMax.to(boxBmp, 0.25, {transformAroundPoint:{point:centerPoint, scaleX:1, scaleY:1}, onComplete:tweenComplete});
			} 
		}
		
		private function tweenComplete( ):void {
			trace("tweenComplete");
			trace("tweenComplete position boxBmp.x=" + boxBmp.x);
			trace("tweenComplete position boxBmp.y=" + boxBmp.y);
		}
	}
}

You can see the swf here: http://boostmode.com/dev/transformAroundCenter/dev.html

 

Thanks

 

 

 

Rolf 

Link to comment
Share on other sites

Ah yes, this is an accumulation of rounding issues related to how Flash reports x/y values. I implemented a fix and uploaded a new version. Please snag it from your Account Dashboard and let me know if that works well for you. Thanks for putting together the simplified demo - very helpful. Great job. 

  • Like 1
Link to comment
Share on other sites

Perfekt, thank you so much, Jack! 
 
That solves a lot of the problems I've been having with a small game I'm working on. 
 
In my game I sometimes need to Kill the TransformAroundPoint tween. And then start a new tween and scale the bitmap from it's current scale to a new scale. 
In this case the bitmap would still end up moving away from it's original position.  When called multiple times it 'travels' quite far. 
 
I've changed the demo to so that it simulates the problem. I call nextTween from a delayedCall, instead of onComplete, to interrupt the Tween before it's finished.
 
I did however make a quick fix for this by calling a 'reset' function that resets the scale and position and uses TransformAroundPoint to instantly set the scale. I out commented the calls to the reset function in the demo. 
 
Could you please take a look at the code below and let me know if you think there's a better fix?
 
package {
	import com.greensock.TweenMax;
	import com.greensock.plugins.TransformAroundCenterPlugin;
	import com.greensock.plugins.TransformAroundPointPlugin;
	import com.greensock.plugins.TweenPlugin;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.geom.Point;
	
	public class Dev extends MovieClip {
		private var boxBmp:Bitmap; 
		private var centerPoint:Point; 
		private var count:int = 0; 
		private var bgBoxBmp:Bitmap;
		
		public function Dev() {
			
			TweenPlugin.activate([TransformAroundPointPlugin]);
			TweenPlugin.activate([TransformAroundCenterPlugin]);
			
			centerPoint = new Point(1024/2, 768/2);
			
			var bgBmd:BitmapData = new BitmapData(100,100, false, 0xCCCCCC);
			bgBoxBmp = new Bitmap(bgBmd);
			this.addChild(bgBoxBmp);
			
			var boxBmd:BitmapData = new BitmapData(100,100, false, 0xFF0000);
			 
			boxBmp = new Bitmap(boxBmd);
			boxBmp.alpha = 0.5;
			
			this.addChild(boxBmp);
			
			// center on screen (1024 x 768)
			
			bgBoxBmp.x = centerPoint.x - bgBoxBmp.width/2; 
			bgBoxBmp.y = centerPoint.y - bgBoxBmp.height/2;
			
			boxBmp.x = centerPoint.x - boxBmp.width/2; 
			boxBmp.y = centerPoint.y - boxBmp.height/2;
			
			trace("start position boxBmp.x=" + boxBmp.x);
			trace("start position boxBmp.y=" + boxBmp.y);
			
			
			nextTween(0.8);
			
		}
		
		private function nextTween(_scalePct:Number ):void {
			count++; 			
			var scaleTo:Number = 1+_scalePct;
			
			TweenMax.killTweensOf(boxBmp);
			
			//reset();
			
			if(count <= 100) {
			// 	TweenMax.to(boxBmp, 0.25, {transformAroundPoint:{point:centerPoint, scaleX:scaleTo, scaleY:scaleTo}, onComplete:nextTween, onCompleteParams:[_scalePct*-1]});
					
				TweenMax.to(boxBmp, 0.25, {transformAroundPoint:{point:centerPoint, scaleX:scaleTo, scaleY:scaleTo}});
				TweenMax.delayedCall(0.15, nextTween, [_scalePct*-1]);
			} else {
				TweenMax.to(boxBmp, 0.25, {transformAroundPoint:{point:centerPoint, scaleX:1, scaleY:1}, onComplete:tweenComplete});
			} 
		}
		
		private function reset():void {
			var prevScaleX:Number = boxBmp.scaleX;
			var prevScaleY:Number = boxBmp.scaleY;
			boxBmp.scaleX = 1;
			boxBmp.scaleY = 1; 
			boxBmp.x = centerPoint.x - boxBmp.width/2; 
			boxBmp.y = centerPoint.y - boxBmp.height/2;
			
			TweenMax.to(boxBmp, 0, {transformAroundPoint:{point:centerPoint, scaleX:prevScaleX, scaleY:prevScaleY}});
			
		}
		
		private function tweenComplete( ):void {
			// reset();
			trace("tweenComplete");
			trace("tweenComplete position boxBmp.x=" + boxBmp.x);
			trace("tweenComplete position boxBmp.y=" + boxBmp.y);
		}
	}
}

Link to the new demo: http://boostmode.com/dev/transformAroundCenter/v2/dev.html

 

Again, thanks a lot for your quick response and for fixing the problem! 
 
Rolf 
Link to comment
Share on other sites

Thanks again for the demo. It looks like Flash won't handle it properly unless we round to the closest 0.5 pixel (in the last version, I was rounding to the closest 0.1). I updated the file, so you can snag it from your account. It seemed to work perfectly in your demo, but let me know if you have any other issues. 

Link to comment
Share on other sites

It works perfectly now. That's incredible good service!

 

Thanks a lot, I really appreciate it. 

 

Rolf

  • Like 1
Link to comment
Share on other sites

Excellent. Thanks for letting us know.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×