Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Adobe AIR Development

Reply
Contributor
Posts: 22
Registered: ‎01-14-2011
My Device: Blackberry Storm

Pinch Zoom + Pan Image Viewer

Hi everyone, I've made a picture/image viewer that can be inserted into any app. It attempts to work similarly to the Pictures app that comes on the playbook by default. This includes:

  • One finger drag
  • Snap back to within bounds
  • Two finger pinch zooming
  • multiple setImage calls (for animation or whatever)

 TODO: Double tap zooming in/out

 

package
{
	import caurina.transitions.Tweener;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.TouchEvent;
	import flash.events.TransformGestureEvent;
	import flash.geom.Matrix;
	import flash.geom.Transform;
	
	import qnx.ui.core.UIComponent;
	import qnx.ui.display.Image;
	
	public class ImageView extends Sprite
	{
		public var mData:BitmapData = null;
		private var mDefaultMatrix:Matrix;
		private var mCanvasWidth:int = 0;
		private var mCanvasHeight:int = 0;
		private var mCanvas:Sprite;
		private var mTouchCount:int = 0;
		private var mTouchX:Number = -1;
		private var mTouchY:Number = -1;
		
		public function ImageView()
		{
			super();
			mData = null;
			
			this.addEventListener(TransformGestureEvent.GESTURE_ZOOM, onZoom);
			this.addEventListener(MouseEvent.MOUSE_OUT, onMouseUp);
			this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			this.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			mCanvas = new Sprite();
			addChild(mCanvas);
		}
		
		public function setSize(width:int, height:int):void
		{
			mCanvasWidth = width;
			mCanvasHeight = height;
			
			if(mData != null)
			{
				mCanvas.scaleX = mCanvasWidth / mData.width;
				mCanvas.scaleY = mCanvasHeight / mData.height;
				mCanvas.x = 0;
				mCanvas.y = 0;
			}
		}
		
		public function setImage(bd:BitmapData):void
		{
			if(bd != null)
			{
				mCanvas.graphics.beginBitmapFill(bd,null,false,true);
				mCanvas.graphics.drawRect(0,0,bd.width, bd.height);
				mCanvas.graphics.endFill();

				if(mData == null)
				{
					mDefaultMatrix = new Matrix();
					mDefaultMatrix.a = mCanvasWidth/bd.width;
					mDefaultMatrix.d = mCanvasHeight/bd.height;

					mCanvas.scaleX = mDefaultMatrix.a;
					mCanvas.scaleY = mDefaultMatrix.d;
					mCanvas.x = mDefaultMatrix.tx;
					mCanvas.y = mDefaultMatrix.ty;
				}
				else
				{
					mData.dispose();
				}
				mData = bd;
			}
			else
			{
				mCanvas.graphics.clear();
				if(mData != null)
				{
					mData.dispose();
					mData = null;
				}
			}
		}
		
		private function onMouseDown(e:MouseEvent):void
		{
			mTouchCount++;
			Tweener.removeAllTweens();
			mTouchX = e.stageX;
			mTouchY = e.stageY;
		}
		
		private function onMouseUp(e:MouseEvent):void
		{
			mTouchCount--;
			
			mTouchX = -1;
			mTouchY = -1;
			
			var width:int = mCanvas.scaleX * mData.width;
			var height:int = mCanvas.scaleY * mData.height;
			if(mCanvas.y > 0)
			{
				Tweener.addTween(mCanvas, {y:0, time:0.5, transition:"easeOutQuart"});
			}
			else if(mCanvas.y + height < mCanvasHeight)
			{
				Tweener.addTween(mCanvas, {y:mCanvasHeight - height, time:0.5, transition:"easeOutQuart"});
			}
			if(mCanvas.x > 0)
			{
				Tweener.addTween(mCanvas, {x:0, time:0.5, transition:"easeOutQuart"});
			}
			else if(mCanvas.x + width < mCanvasWidth)
			{
				Tweener.addTween(mCanvas, {x:mCanvasWidth - width, time:0.5, transition:"easeOutQuart"});
			}
			
			if(mCanvas.scaleX < mDefaultMatrix.a)
			{
				Tweener.addTween(mCanvas, {scaleX:mDefaultMatrix.a, time:0.5, transition:"easeOutQuart"});
			}
			if(mCanvas.scaleY < mDefaultMatrix.d)
			{
				Tweener.addTween(mCanvas, {scaleY:mDefaultMatrix.d, time:0.5, transition:"easeOutQuart"});
			}

		}
		
		private function onMouseMove(e:MouseEvent):void
		{
			if(mTouchX != -1 && mTouchY != -1) 
			{
				var dx:Number = e.stageX - mTouchX;
				var dy:Number =  e.stageY - mTouchY;
				mTouchX = e.stageX;
				mTouchY = e.stageY;
				
				var affineTransform:Matrix = mCanvas.transform.matrix;
				
				// move the object to (0/0) relative to the origin
				affineTransform.translate( dx, dy );
				
				// apply the new transformation to the object
				mCanvas.transform.matrix = affineTransform;
				

			}
		}
		
		private function onZoom(e:TransformGestureEvent):void
		{
			e.stopImmediatePropagation();
			
			
			var affineTransform:Matrix = mCanvas.transform.matrix;
			
			// move the object to (0/0) relative to the origin
			affineTransform.translate( -e.stageX, -e.stageY );
			
			// scale
			affineTransform.scale(e.scaleX, e.scaleY );
			
			// move the object back to its original position
			affineTransform.translate( e.stageX, e.stageY );
			
			// apply the new transformation to the object
			mCanvas.transform.matrix = affineTransform;
		}
	}
}

 If you have any suggestions or improvements to be made, please let me know!