jQuery UI resizable() and images: a first look

jQuery UI resizable() and images: a first look

Some problems encountered during the study of the jQuery UI resizable() object applied to images.

I'm currently working on a challenging project which is entirely based on the capability of editing a PDF template online. I've already set the base editor for rich text formatting, but I'm actually struggling with images. The problem is not inserting an image, but instead resizing it so that it can fit the page. Of course page dimensions are entirely calculated by making a direct conversion from the target PDF dimensions to the text area of the web page, namely a millimeters to pixels conversion. I don't really know if I should provide a trivial form to allow a user to specify the final dimensions of the image or, on the contrary, dynamically resize the images with some jQuery plugin or the jQuery's UI resizable() object. I decided to test the resizable object but things are a little bit complicated.

First of all, you need to include both jQuery UI and its default CSS file:

<head>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css"/>
</head>
<body>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
</body>

Then you have to specify the ui-widget-content CSS class on the image:

<div id="wrapper">
	<img src="img.jpg" id="test" class="ui-widget-content"/>
</div>

Some developers have reported several problems when an image is provided without any dimension attributes or any stated dimension in the CSS file. The problem is that when you fetch your images from remote or when an image is uploaded, you can't predict its dimensions on the client-side.

Next step: initialize the object:

$('#test').resizable();

Now you should see a different type of cursor appearing on the image, indicating that the image is actually resizable. This kind of object has several methods, properties and events, but the most interesting feature concerns the beginning (event.start()) and the end (event.stop()) of the resizing action:

$('#test').resizable({
	start: function(event, ui) {
	
		console.log($('#test').width() + ' ' + $('#test').height());
	
	},
	stop: function(event, ui) {
	
		console.log($('#test').width() + ' ' + $('#test').height());
	
	}	
});

It does work, but the tricky part is that this kind of event is continuous, meaning that a user can keep resizing the image if you don't stop the event by destroying the object.

If you can't set width and height on the image, you can play a simple trick by using the image itself as the background image of its container. So you have to change the previous markup into this:

<div id="wrapper" class="ui-widget-content">
	<img src="img.jpg" id="test"/>
</div>

The jQuery code then becomes:

$('#wrapper').css({
    backgroundImage: 'url(' + $('#test').attr('src') + ')',
    width: $('#test').width(),
    height: $('#test').height()
});

$('#test').remove();

$('#wrapper').resizable({
	start: function(event, ui) {
	
		console.log($('#wrapper').width() + ' ' + $('#wrapper').height());
	
	},
	stop: function(event, ui) {
	
		console.log($('#wrapper').width() + ' ' + $('#wrapper').height());
	
	}	
});

However, I still can't find out a good solution to this problem.