Easy pinch zoom for ImageView

As part of my Meetup for BlackBerry 10 app, I provide the photo albums for the user’s groups.  With the list of albums, the user can drill down to see a list of the images and then click on the individual image. The image is loaded into the ImageView component from a url on Meetup.com.  Due the obvious screen size difference between the files upload and a phone, the image is re-sized to fit on the available screen.  Regardless if the screen is the 1:1 Q5/10 or the 16:8/9 Z10/30, the user will need to zoom in on the picture and the scroll the image to see the areas larger than the screen.

When I was searching for a solution for this, I found examples using the gesture handlers to catch the pinch action and do something based on that action.  While that seemed to work for making the image larger, however, it wasn’t working well for making the image smaller.  The method for making the image larger was to increase the ScaleX and ScaleY values.  Also, I wasn’t able to move the image around to see the other parts of the zoomed image.  The gesture handler was attached to the ImageView component which was inside a ScrollView component.  I started focusing on the ScrollView and happened upon the basic settings that would make the pinchToZoom functionality of the ScrollView control the child ImageView.

ScrollView {
	id: gestureContainer
	scrollViewProperties {
		scrollMode: ScrollMode.Both
	}
	scrollRole: ScrollRole.Main
	scrollViewProperties.minContentScale: 1.0
	scrollViewProperties.maxContentScale: 8.0
	scrollViewProperties.pinchToZoomEnabled: true
	scrollViewProperties.overScrollEffectMode: OverScrollEffectMode.Default

	WebImageView {
		id: singleImg
		url: ListItemData.photo_link
	}
}

The key is to set the ScrollRole to Main, enable the pinchToZoom and set the overScrollEffectMode to Default. With all of these together, the image can be pinch to zoomed in and out.  And the image can be moved around without it snapping back to the middle when the touch event ends.  I set the limit of the scale to 8 times normal size, because it is pretty much pointless above that due to the resolution of the images loaded.

The one issue was, that the last zoom level carried over to any other image selected.  What I needed it to do is reset itself back to the initial zoom.  After attempting to reset the scale values, I found that you have to reset the viewableArea.


onSelectPhotoURLChanged: {
	gestureContainer.resetViewableArea();
	singleImg.url = selectPhotoURL;
	console.debug("on selectPhotoURL: " + selectPhotoURL);
}

Since I check for the image URL change, I put the resetViewableArea before it loads the image. This does allow for the same image to be viewed at the previous zoom level, which isn’t a problem.  I think I would have made myself crazy trying to get the gesture handler to work both ways.  Too bad the documentation doesn’t have this simple solution.

About DeanLogic
Dean has been playing around with programming ever since his family got an IBM PC back in the early 80's. Things have changed since BASICA and Dean has dabbled in HTML, JavaScript, Action Script, Flex, Flash, PHP, C#, C++, J2ME and SQL. On this site Dean likes to share his adventures in coding. And since programming isn't enough of a time killer, Dean has also picked up the hobby of short film creation.

About DeanLogic

Dean has been playing around with programming ever since his family got an IBM PC back in the early 80's. Things have changed since BASICA and Dean has dabbled in HTML, JavaScript, Action Script, Flex, Flash, PHP, C#, C++, J2ME and SQL. On this site Dean likes to share his adventures in coding. And since programming isn't enough of a time killer, Dean has also picked up the hobby of short film creation.