Rotate and zoom images with Javascript

17 11 2008

A Javascript script to rotate and zoom images using the canvas element.

Installation

in the BODY of your html page insert the commands which will trigger the transformations and the image you want to rotate, embedded in a canvas element:

<body onload="CanvasOnload()">
<h1>Image rotate and zoom</h1>
    <span style="text-align: center; width: 65px">
        <a href="javascript: location.href = 'index.html'" style="text-decoration: none">
            <img src="reset.png" alt="Reset the image" border="0" />
        </a>
    </span>

<p>
	rotate:
	<input type="button" value="0°" onclick="rotate(0);">
	<input type="button" value="90°" onclick="rotate(90);">
	<input type="button" value="180°" onclick="rotate(180);">
	<input type="button" value="-90°" onclick="rotate(-90);">
</p>

<div>
    <span style="text-align: center; width: 65px">
        <a href="#"
           onmousedown="mousedown = true; ZoomOut(document.getElementById('myimage'))"
           onmouseout="mousedown = false"
           onmouseup="mousedown = false"
           style="text-decoration: none">
            <img src="minus.jpg" alt="Zoom out" border="0" />
        </a>
    </span>
    <span style="text-align: center; width: 65px">
        <a href="#"
           onmousedown="mousedown = true; ZoomIn(document.getElementById('myimage'))"
           onmouseup="mousedown = false"
           onmouseout="mousedown = false"
           style="text-decoration: none">
            <img src="plus.jpg" alt="Zoom in" border="0" />
        </a>
    </span>
</div>

<canvas id="ff_canvas" width="159" height="198">
    <img src="/js-tests/rotateImage/fashionable.jpg"
         alt="Zend"
         width="159"
         height="198"
         id="myimage"
         style="margin-left: 50px; position: absolute; top: 110px; left: 250px; cursor: hand" />
</canvas>
</body>

In the HEAD of your html page, you need to insert the references to your scripts:

<script type="text/javascript" src="imgRotateCanvas.js"></script>
<script language="javascript" src="imgZoomCanvas.js"></script>

This is the code in “imgRotateCanvas.js”:

/*Author: Val Cartei,  val.cartei@gmail.com.
Year:2008
Description: rotates an image embedded in a canvas element.

This script is an adaptation of a script by: Benoit Asselin | http://www.ab-d.fr. The original script can be found at:
The JavaScript Source!! http://javascript.internet.com
*/

/**
*function: rotate
* @param int p_deg - the degrees of the rotation (e.g. -90,180,270,0).
*/
function rotate(p_deg) {
	if(document.getElementById('ff_canvas')) {
		/*
		Ok!: Firefox 2, Safari 3, Opera 9.5b2
		No: Opera 9.27
		*/
		var image = document.getElementById('myimage');
		var canvas = document.getElementById('ff_canvas');
		var canvasContext = canvas.getContext('2d');

		switch(p_deg) {
			default :
			case 0 :
				canvas.setAttribute('width', image.width);
				canvas.setAttribute('height', image.height);
				canvasContext.rotate(p_deg * Math.PI / 180);
				canvasContext.drawImage(image, 0, 0);
				break;
			case 90 :
				canvas.setAttribute('width', image.height);
				canvas.setAttribute('height', image.width);
				canvasContext.rotate(p_deg * Math.PI / 180);
				canvasContext.drawImage(image, 0, -image.height);
				break;
			case 180 :
				canvas.setAttribute('width', image.width);
				canvas.setAttribute('height', image.height);
				canvasContext.rotate(p_deg * Math.PI / 180);
				canvasContext.drawImage(image, -image.width, -image.height);
				break;
			case 270 :
			case -90 :
				canvas.setAttribute('width', image.height);
				canvas.setAttribute('height', image.width);
				canvasContext.rotate(p_deg * Math.PI / 180);
				canvasContext.drawImage(image, -image.width, 0);
				break;
		};

	} else {
		/*
		Ok!: MSIE 6 et 7
		*/
		var image = document.getElementById('myimage');
		switch(p_deg) {
			default :
			case 0 :
				image.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(rotation=0)';
				break;
			case 90 :
				image.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(rotation=1)';
				break;
			case 180 :
				image.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)';
				break;
			case 270 :
			case -90 :
				image.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(rotation=3)';
				break;
		};

	};
};

// Multiple onload function created by: Simon Willison
// http://simonwillison.net/2004/May/26/addLoadEvent/
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}

addLoadEvent(function() {
	var image = document.getElementById('myimage');
	var canvas = document.getElementById('ff_canvas');
	if(canvas.getContext) {
		image.style.visibility = 'hidden';
		image.style.position = 'absolute';
	} else {
		canvas.parentNode.removeChild(canvas);
	};

	rotate(0);
});

This is the code in “imgZoomCanvas.js”:

/*Author: Val Cartei,  val.cartei@gmail.com.
 Year:2008
 Description: rotates an image embedded in a canvas element.
This script is an adaptation of a script that can be found at:
 http://www.phpguru.org/downloads/image_rotate/rotate.html
 )*/
 <!--
 mousedown = false; // An important global variable
/**
 * The zoom out function
 *
 * @param object obj The image object
 */
 function ZoomOut(obj)
 {
 if (document.all) {
 // In case the zoom property is not set
 if (obj.style.zoom == '') {
 obj.style.zoom = 1;
 }
if (parseFloat(obj.style.zoom) <= 0.1) {
 return;
 }
obj.style.zoom = obj.style.zoom - 0.1;
if (mousedown) {
 setTimeout("ZoomOut(document.getElementById('" + obj.id + "'))", obj.height);
 }
 } else {
 var canvas  = document.getElementById('ff_canvas');
 var context = canvas.getContext('2d');
canvas.style.width = ((parseInt(canvas.style.width) ? parseInt(canvas.style.width) : obj.width) - 10) + 'px';
 canvas.style.height = ((parseInt(canvas.style.height) ? parseInt(canvas.style.height) : obj.height) - 10) + 'px';
if (mousedown) {
 setTimeout("ZoomOut(document.getElementById('" + obj.id + "'))", 50);
 }
 }
 }
/**
 * The zoom in function
 *
 * @param object obj The image object
 */
 function ZoomIn(obj)
 {
 if (document.all) {
 // In case the zoom property is not set
 if (obj.style.zoom == '') {
 obj.style.zoom = 1;
 }
// Lower limit is 0.1
 if (parseFloat(obj.style.zoom) <= 0.1) {
 obj.style.zoom = 0.1;
 }
obj.style.zoom = Number(obj.style.zoom) + 0.1;
if (mousedown) {
 setTimeout("ZoomIn(document.getElementById('" + obj.id + "'))", obj.width);
 }
 } else {
 var canvas  = document.getElementById('ff_canvas');
 var context = canvas.getContext('2d');
canvas.style.width = ((parseInt(canvas.style.width) ? parseInt(canvas.style.width) : obj.width)+ 10) + 'px';
 canvas.style.height = ((parseInt(canvas.style.height) ? parseInt(canvas.style.height) : obj.height)+ 10) + 'px';
if (mousedown) {
 setTimeout("ZoomIn(document.getElementById('" + obj.id + "'))", 50);
 }
 }
 }
/**
 *
 */
 function Reset(img)
 {
 img.style.zoom = 1;
 img.rotation = -0.01;
 Rotate(img, 0.01);
 }
function CanvasOnload()
 {
 // IE
 if (document.all) {
 return;
 }
var canvas  = document.getElementById('ff_canvas');
 var context = canvas.getContext('2d');
 var img     = document.getElementById('myimage');
context.drawImage(img, 0, 0, img.width, img.height);
 }
/**
 * Shows the status of the rotation
 */
 function ShowStatus()
 {
 var img  = document.getElementById('myimage');
 var zoom = Number(img.style.zoom);
alert('Zoom factor: ' + (zoom ? zoom : 1) + '\nRotation factor: ' + (img.rotation ? img.rotation : '0') );
 }
 // -->

These are image files used. Put them in the root directory together with your html page and the .js scripts.

Zoom in:

plus

ZoomOut:

minus

and the sample image:

fashionable


Actions

Information

One response

24 11 2008
Elinor

Hi Val,
That was really interesting.
There seem to be quite a few useful JS scripts popping up for handling images like Raphael JS for instance, which offers scaling, transformation, etc. Not sure whether you looked into it, it’s licensed under the MIT license.
What I find most difficult is actually trying to handle text as an image (scaling in particular).
Anyway, thanks again for the interesting article!
Elinor

Leave a comment