HTML5 Zone is brought to you in partnership with:

Scott is a Senior Software Architect at Altamira Corporation. He has been developing enterprise and web applications for over 15 years professionally, and has developed applications using Java, Ruby/Rails, Groovy/Grails and Python. His main areas of interest include object-oriented design, system architecture, testing, and frameworks of all types including Spring, Hibernate, Ruby on Rails, Grails, and Django. In addition, Scott enjoys learning new languages to make himself a better and more well-rounded developer a la The Pragmatic Programmers' advice to "learn one language per year." Scott is a DZone MVB and is not an employee of DZone and has posted 43 posts at DZone. You can read more from them at their website. View Full User Profile

Scale and Crop an Image using Javascript and CSS

01.29.2013
| 3158 views |
  • submit to reddit

A common CSS problem is the need to crop and scale an image on a page. Scaling an image is easily done using the hight and width attributes of the image. Likewise cropping an image can be accomplished by using the image as a background of an element and setting the hight and width of the element. Both scaling and cropping an image is a bit more involved however, and if it's something that's done often it pays to have a class that handles the creation of cropped and scaled images. For this purpose I've written the Croppenscaler.

The idea here is to create a div element with a set size that has a nested div within that displays a relatively positioned image. I found that it was useful to have a hash of image data that defines the default size and crop position of an image. These values are adjusted when the frame is built so that no matter what scale the resulting frame has, the image is positioned in the same place.

CSS Classes

Let's examine the nessessary CSS classes first:

  .croppenscaler {
    display: inline-block;
    overflow: hidden;
  }

  .croppenscaler img {
    position: relative;
    border: none;
  }

The important attributes to note above are the use of overflow on the main croppenscaler, this ensures that the top frame has the intended size. The nested image is positioned relatively. All of the other CSS attributes are written in the style attribute because they have to be calculated when the frame is built.

The Croppenscaler Class:

The javascript below uses the Prototype framework, but it could just as easily use JQuery or raw javascript to accomplish the same thing.

var imageData = {
  kittah: {  width:900, top:-175, left:-165, url: '/blogs/assets/jcato/images/Kittah.jpg' },
};

var Croppenscaler = Class.create();
Croppenscaler.prototype = {

  initialize: function(options) {
    var image = imageData[options.image];

    this.url = image.url;
    this.frameHeight = options.height || 400;
    this.frameWidth = options.width || 300;

    var scale = this.frameWidth / 300;

    this.imageWidth = (image.width) * scale;
    this.positionTop = (image.top) * scale;
    this.positionLeft = (image.left) * scale;
  },

  buildFrame: function() {

    var img = new Element('img',{src:this.url, 'class':'zoom'});
    img.setStyle({
      width: this.imageWidth+'px',
      top: this.positionTop+'px',
      left: this.positionLeft+'px',
    });

    var frame = new Element('div',{'class':'croppenscaler'});
    frame.update(img);
    frame.setStyle({
      height:this.frameHeight+'px',
      width:this.frameWidth+'px',
    });

    return frame;
  },
};

The class has two functions. The constructor takes a hash of options for the resulting frame; the image key and the height and width of the frame. In this version the constructor references an imageData hash to get the details about the image to display, but they could be passed into the function as well. The important thing is that the constructor has access to the height and width of the frame, as well as the default width of the image and the top and left attributes that define where the upper left corner of the image should be when it's displayed at its default width.

The buildFrame() function takes the calculated sizes and uses them to construct the frame div, with a nested image at a scale that fits within the frame, and positioned the same at any scale.

Then to use the class, create a new Croppenscaler with a hash that at least includes the image key, and an optional height and width, call the buildFrame() function and insert the resulting element onto the page.

var loadImages = function() {
  $('cats').insert(new Croppenscaler({image:'kittah'}).buildFrame());
  $('cats').insert(new Croppenscaler({image:'kittah',height:300}).buildFrame());
  $('cats').insert(new Croppenscaler({image:'kittah',width:400,height:250}).buildFrame());
  $('cats').insert(new Croppenscaler({image:'kittah',width:200,height:300}).buildFrame());
  $('cats').insert(new Croppenscaler({image:'kittah',width:100,height:150}).buildFrame());
}

The above code will then produce the clowder of cats below.

Published at DZone with permission of Scott Leberknight, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags: