MooTools Image Viewer with Zoom Functions

Description

This image viewer script is developed using MooTools 1.2. It can be used if you want to have a closer look on small details of one or more images, but you don't have enough space to display it in full size. With the MooTools image viewer you can zoom in and out using the mousewheel or by clicking on the corresponding control elements. The zoomed image can be moved inside the container to view different regions. The script uses dynamic loading for the image files as the images have to be downloaded in full resolution to see the details. That means the images are only requested from the server if needed. This will reduce the server load. After loading the image it is scaled to fit inside the image viewer.

Demo

See it in action on our WikiFood website.

HTML

The HTML code is quite simple. You need a container for the image viewer enclosing the image (here “zoom_container” and “zoom_image”). Then you add your control elements for the zoom functionalities and for selecting the image. The images you want to display with the image viewer must be included as a tags inside a div element with the ID=“images”.

<!-- Image Viewer-->
<div id="zoom_container">
   <img id="zoom_image" src="/wikifood/media/spacer.png" alt="product picture"/>
</div>
 
<!-- control elements -->
<img src="/icons/viewmag+.png" height="16" width="16" id="zoomIn" class="zoomControl" title="zoom in" alt="+" />
<img src="/icons/media/viewmag-.png" height="16" width="16" id="zoomOut" class="zoomControl" title="zoom out" alt="-" />
<img src="/icons/reset.png" height="16" width="16" id="reset" class="zoomControl" title="Reset" alt="Reset" />
<a id="fullScreen" href=""><img src="/icons/zoom100percent.png" height="16" width="16" title="1:1" alt="1:1" /></a>
 
<table style="border-bottom: 2px solid #ffa743; clear: left; table-layout: fixed; width: 100%">
   <colgroup>
      <col width="10px;"/>
      <col width="auto;"/>
      <col width="10px;"/>
   </colgroup>
 
   <tr>
      <td><img src="/icons/left.png" height="11" width="10" id="previous" class="zoomControl" alt="&lt;" /></td>
      <td style="text-align: center" id="label"></td>
      <td><img src="/icons/right.png" height="11" width="10" id="next" class="zoomControl" alt="&gt;" /></td>
   </tr>
</table>
 
<!-- images to display -->
<div id="images" style="display: none;">
   <a href="/images/image_a.jpg"></a>
   <a href="/images/image_b.jpg"></a>
   <a href="/images/image_c.jpg"></a>
</div>
 
<script src="/scripts/ImageZoomSlideshow.js" type="text/javascript"></script>
<script type="text/javascript">
	window.addEvent('domready', function() {		
		var imageZoomer = new ImageZoom(
			'zoom_image', 'zoom_container',
			new Array('zoomIn', 'zoomOut', 'reset', 'next', 'previous', 'fullScreen'));
	});
</script>

CSS

Here you can find the CSS declarations:

#zoom_container {
   margin: 2px;
   float: left;
   height: 200px;
   width: 150px; 
   position: relative;
   overflow: hidden;
   border: 1px solid gray;
   background: black url(/images/spinner.gif) center no-repeat;
}
 
#zoom_container.ready {
   background: black;
}
 
#zoom_image {
   position: absolute;
   top: auto;
   left: auto;
   cursor: move;
}

You can adapt the size of the zoom container to any dimension you need.

JavaScript

To use the MooTools image viewer you need MooTools 1.2 Core and More.

/**
 * Image Viewer with Zoom
 *
 *
 * @version		1.0
 *
 * @license		MIT-style license
 * @author		Ralf Herbst
 * @copyright		Ralf Herbst, CR SANTEC, Centre de Recherche Public Henri Tudor, Luxembourg (2010)
 */
 
var ImageZoom = new Class({
 
	initialize: function(zoomImage, container, buttons) {
 
	// set zoom image into class context
 
	this.images = $('images').getElements('a');
	this.currentIndex = -1;
 
	this.zoomImage = $(zoomImage);
 
        this.container = $(container);
        this.containerHeight = $(container).getStyle('height').toInt();
        this.containerWidth = $(container).getStyle('width').toInt();             			
 
		// add mousewheel event to current image to zoom in and out.
		$(zoomImage).addEvent('mousewheel', function(e) {
			e.stop(); // prevent the mousewheel from scrolling the page.
 
			// wheel down
			if(e.wheel < 0) {
				this.zoomIn();
			}
			// wheel up
			else {
				this.zoomOut();
			}
		}.bind(this));
 
		// add handler for buttons
		$(buttons[0]).addEvent('click', this.zoomIn.bind(this)); // zoom in
		$(buttons[1]).addEvent('click', this.zoomOut.bind(this)); // zoom out
		$(buttons[2]).addEvent('click', this.reset.bind(this)); // reset
		$(buttons[3]).addEvent('click', this.next.bind(this)); // next image
		$(buttons[4]).addEvent('click', this.previous.bind(this)); // previous image
 
		this.next();
 
		// make current image dragable
		this.zoomImageDrag = new Drag(this.zoomImage, {
			grid: 1,
		//	limit: $('zoom_big_container'),
	     	onDrag: function(elem){
				var pos = elem.getPosition(this.container);
 
				var left = pos.x;
				var top = pos.y;
 
				this.setPosition('zoom_image',left,top);
 
			}.bind(this)
		});
	},
 
	zoomIn: function() {
		// assign new size
		newWidth = this.width * 2;
		newHeight = this.height * 2;
 
		// limit zoom
		if(newWidth <= 4048 && newHeight < 4048) {
			this.width = newWidth;
			this.height = newHeight;
 
			this.zoomImage.set('width', this.width);
			this.zoomImage.set('height', this.height);
 
			// assign new position 
			var pos = $('zoom_image').getPosition(this.container);
			var left = pos.x * 2;
			var top = pos.y * 2;
 
			// set new position
			this.setPosition('zoom_image',left,top);
		}
	},
 
	zoomOut: function() {
		// assign new size
		newWidth = this.width / 2;
		newHeight = this.height / 2;
 
		// image can not be smaller than the container
		if(newWidth >= this.containerWidth || newHeight >= this.containerHeight) {
			this.width = newWidth;
			this.height = newHeight;
 
			this.zoomImage.set('width', this.width);
			this.zoomImage.set('height', this.height);
 
			// assign new position
			var pos = $('zoom_image').getPosition(this.container);
			var left = pos.x / 2;
			var top = pos.y / 2;
 
			// set new position
			this.setPosition('zoom_image',left,top);
		}
	},
 
	/*
	 * fit current image to container
	 */
	reset: function() {
		yFactor = this.imageHeight / this.containerHeight;
        xFactor = this.imageWidth / this.containerWidth;
 
		if(xFactor > yFactor) {             
        	yFactor = xFactor;
		}
 
		this.width =  this.imageWidth / yFactor
		this.height =  this.imageHeight / yFactor
 
		this.zoomImage.set('width', this.width);
		this.zoomImage.set('height', this.height);
		this.setPosition('zoom_image',0,0);
	},
 
	getWidth: function() {
		return this.zoomImage.getProperty('width');
	},
 
	getHeight: function() {
		return this.zoomImage.getProperty('height');
	},
 
	setPosition: function(element,left,top){
 
		// check position if it is outside boundaries
		if(left > 0) left = 0;
		if(top > 0) top = 0;
		if(-left > this.zoomImage.width - this.containerWidth) {
			left = -1 * (this.zoomImage.width -this.containerWidth);
		}
		if(-top > this.zoomImage.height - this.containerHeight) {
			top = -1 * (this.zoomImage.height - this.containerHeight);
		}
 
		// apply new position
		$(element).set({
			styles:{
				'left': left,
				'top':top
			}
		})
	},
 
        // select next image
	next: function() {
		this.container.erase('class');
		this.currentIndex++;
		if(this.currentIndex >= this.images.length) {
			this.currentIndex = 0;
		}
 
		$('label').set('text', (this.currentIndex + 1) + "/" + this.images.length);
 
		this.zoomImage.fade('out');
		var preloadImg = new Asset.image(this.images[this.currentIndex].get('href'), {onload: function() {
			this.imageHeight = preloadImg.get('height');
	        this.imageWidth = preloadImg.get('width');
 
			this.height = this.imageHeight;
	        this.width = this.imageWidth;
 
			this.reset();
			this.container.set('class', 'ready');
			this.zoomImage.set('src', this.images[this.currentIndex].get('href'));
			$('fullScreen').set('href', this.images[this.currentIndex].get('href'));
			this.zoomImage.fade('in');
		}.bind(this),
		onstart: function() {
			alert("next");
		}.bind(this)
 
		});
	},
 
        // select previous image
	previous: function(){
		this.container.erase('class');
		this.currentIndex--;
		if(this.currentIndex < 0) {
			this.currentIndex = this.images.length -1;
		}
 
		$('label').set('text', (this.currentIndex + 1) + "/" + this.images.length);
 
		var preloadImg = new Asset.image(this.images[this.currentIndex].get('href'), {onload: function() {
			this.imageHeight = preloadImg.get('height');
	        this.imageWidth = preloadImg.get('width');
 
			this.height = this.imageHeight;
	        this.width = this.imageWidth;
 
			this.reset();
			this.container.set('class', 'ready');
			this.zoomImage.set('src', this.images[this.currentIndex].get('href'));
			$('fullScreen').set('href', this.images[this.currentIndex].get('href'));
		}.bind(this)});
	}
});

Download

team/herbst/mootools_image_viewer_with_zoom_functions.txt · Last modified: 2010/08/24 10:16 by Ralf Herbst
© Centre de Recherche Public Henri Tudor | Legal Notice