Сделал опцию сохранения пропорции (жмём Shift в процессе ресайза).
И обертка создается автоматом.
<!DOCTYPE html>
<style>
.resizeable{
position: relative;
display: inline-block;
overflow: hidden;
min-width: 16px;
min-height: 16px;
}
.resizeable .resizer{
position: absolute;
bottom: 0;
right: 0;
width: 16px;
height: 16px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAACVBMVEX///9/f38/Pz8NdHQxAAAAAXRSTlMAQObYZgAAAC9JREFUeNpNyDENADAMBLGoY5mESuAFwwOtvPWGG1z1d+xaW9CiQSxBiwY1Clo0D+HwCieH9fp/AAAAAElFTkSuQmCC);
cursor: se-resize;
}
</style>
<img width="200" height="193" src="http://upload.wikimedia.org/wikipedia/commons/thumb/8/86/TUX-G2-SVG.svg/610px-TUX-G2-SVG.svg.png" alt="" />
<script>
function Resizeable(element, preserveAspectRatio) {
if (!(this instanceof Resizeable))
return new Resizeable(element, preserveAspectRatio);
this.top = NaN;
this.left = NaN;
this.preserveAspectRatio = Boolean(preserveAspectRatio);
this.aspectRatio = element.offsetWidth / element.offsetHeight;
this.element = element;
this.wrapper = document.createElement('div');
this.wrapper.className = 'resizeable';
this.resizer = document.createElement('div');
this.resizer.className = 'resizer';
this.resizer.addEventListener('mousedown', this);
element.parentNode.replaceChild(this.wrapper, element);
this.wrapper.appendChild(element);
this.wrapper.appendChild(this.resizer);
}
Resizeable.prototype.resize = function(width, height) {
width = width > 0 ? width : 0;
height = height > 0 ? height : 0;
if (this.preserveAspectRatio) {
if (width > height) {
width = height * this.aspectRatio;
} else {
height = width / this.aspectRatio;
}
}
this.element.style.width = width + 'px';
this.element.style.height = height + 'px';
};
Resizeable.prototype.handleEvent = function(event) {
switch (event.type) {
case 'mousedown':
return this.handleMouseDownEvent(event);
case 'mousemove':
return this.handleMouseMoveEvent(event);
case 'mouseup':
return this.handleMouseUpEvent(event);
}
};
Resizeable.prototype.handleMouseDownEvent = function(event) {
if (this.resizer.setCapture)
this.resizer.setCapture();
document.addEventListener('mousemove', this);
document.addEventListener('mouseup', this);
this.top = event.pageX - this.element.offsetWidth;
this.left = event.pageY - this.element.offsetHeight;
event.preventDefault();
};
Resizeable.prototype.handleMouseMoveEvent = function(event) {
this.resize(event.pageX - this.top, event.pageY - this.left);
};
Resizeable.prototype.handleMouseUpEvent = function(event) {
document.removeEventListener('mousemove', this);
document.removeEventListener('mouseup', this);
if (this.resizer.releaseCapture)
this.resizer.releaseCapture();
this.top = NaN;
this.left = NaN;
};
Resizeable.prototype.setPreserveAspectRatio = function(preserveAspectRatio) {
if (this.preserveAspectRatio != preserveAspectRatio) {
this.preserveAspectRatio = preserveAspectRatio;
this.resize(this.element.offsetWidth, this.element.offsetHeight);
}
}
var resizeable = new Resizeable(document.querySelector('img'), false);
var shiftKeyListener = function(event) {
resizeable.setPreserveAspectRatio(event.shiftKey);
};
document.addEventListener('keydown', shiftKeyListener);
document.addEventListener('keyup', shiftKeyListener);
window.focus();
</script>