Skip to content

Instantly share code, notes, and snippets.

@hamishhossack
Created July 27, 2015 14:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hamishhossack/696d39dd1cf1a35840a6 to your computer and use it in GitHub Desktop.
Save hamishhossack/696d39dd1cf1a35840a6 to your computer and use it in GitHub Desktop.
Image Cropping Manager (needs optimising)
var Crop = {
elements: {
editor: null,
container: null,
slider: null,
img: null,
overlay: null,
preview: null
},
initialize: function (opts) {
$(opts.container)
.attr({
'data-crop': '',
'data-mask': opts.mask
})
.append('<div class="editor"></div>');
var shell = $(opts.container),
scaleContainer = $(opts.sliderContainer),
cropMain = shell.find('.editor'),
cropPreview = opts.preview,
proceedBtn = $(opts.proceed),
img,
container,
slider,
overlay,
self = this;
container = $('<div />')
.attr({
class: 'crop-container'
})
.css({
width: opts.width + 'px',
height: opts.height + 'px'
});
slider = $('<input />')
.attr({
type: 'range',
min: opts.zoom.min,
max: opts.zoom.max,
step: opts.zoom.step,
value: 1
});
img = $('<img />')
.attr('class', 'crop-img')
.css({
zIndex: 5999,
top: 0,
left: 0
});
overlay = $('<div />')
.attr({
class: 'crop-overlay',
draggable: "true"
})
.css({
zIndex: 6000
});
container.append(overlay);
container.append(img);
cropMain.append(container);
scaleContainer.append(slider);
this.elements.editor = cropMain;
this.elements.container = container;
this.elements.slider = slider || false;
this.elements.proceed = proceedBtn;
this.elements.img = img;
this.elements.overlay = overlay;
this.elements.preview = cropPreview || false;
this.imgInfo = {
aw: 0,
ah: 0,
w: 0,
h: 0,
at: 0,
al: 0,
t: 0,
l: 0,
s: opts.zoom.min || 1
};
this.loadImg(opts.image);
container.resize(function () {
self.imgSize();
});
// Force Disable Features until ready
slider.attr('disabled', 'disabled');
proceedBtn.attr('disabled', 'disabled');
slider.on('input change', function () {
self.imgResize(this.value);
});
this.moveableObject(overlay);
},
moveableObject: function (element) {
var self = this;
element.bind(((document.ontouchstart !== null) ? 'mousedown' : 'touchstart'), function (e) {
$('body').addClass('grabcursor');
var o = $(this),
mousedown = {
x: (e.originalEvent.pageX || e.originalEvent.touches[0].pageX),
y: (e.originalEvent.pageY || e.originalEvent.touches[0].pageY)
},
elepos = {
x: o.parent().offset().left,
y: o.parent().offset().top
};
e.preventDefault();
$(document).bind(((document.ontouchmove !== null) ? 'mousemove' : 'touchmove'), function (e) {
var mousepos = {
x: (e.originalEvent.pageX || e.originalEvent.changedTouches[0].pageX || mousedown.x),
y: (e.originalEvent.pageY || e.originalEvent.changedTouches[0].pageY || mousedown.y)
};
if (mousedown.y !== mousepos.y) {
if (parseInt(o.css('top')) === 0) o.css({
top: self.elements.editor.offset().top,
left: self.elements.editor.offset().left
});
// Move Image
self.imgMove({
t: parseInt(o.css('top')) - (elepos.y - (mousedown.y - mousepos.y)),
l: parseInt(o.css('left')) - (elepos.x - (mousedown.x - mousepos.x))
});
// Reposition Overlay
o.css({
left: elepos.x - (mousedown.x - mousepos.x),
top: elepos.y - (mousedown.y - mousepos.y)
});
}
});
$(document).bind(((document.ontouchend !== null) ? 'mouseup' : 'touchend'), function (e) {
// remove grab cursor
$('body').removeClass('grabcursor');
$(document).unbind(((document.ontouchmove !== null) ? 'mousemove' : 'touchmove'));
element.css({
top: 0,
left: 0
});
});
return false;
});
},
loadImg: function (url) {
var self = this;
this.elements.img
.removeAttr('style')
.attr('src', url)
.load(function () {
self.elements.img.width(this.width);
self.elements.img.height(this.height);
self.imgSize();
});
},
newImage: function (data) {
var c = this.elements.container,
img = this.elements.img;
c.find('.crop-img')
.removeAttr('style')
.attr('src', data);
this.elements.slider.removeAttr('disabled');
this.elements.proceed.removeAttr('disabled');
},
imgSize: function () {
var c = this.elements.container,
img = this.elements.img,
imgSize = {
w: img.width(),
h: img.height()
};
var holderRatio = {
wh: this.elements.container.width() / this.elements.container.height(),
hw: this.elements.container.height() / this.elements.container.width()
};
this.imgInfo.aw = imgSize.w;
this.imgInfo.ah = imgSize.h;
if (imgSize.w * holderRatio.hw < imgSize.h * holderRatio.wh) {
this.imgInfo.w = c.width();
this.imgInfo.h = this.imgInfo.w * (imgSize.h / imgSize.w);
this.imgInfo.al = 0;
} else {
this.imgInfo.h = c.height();
this.imgInfo.w = this.imgInfo.h * (imgSize.w / imgSize.h);
this.imgInfo.at = 0;
}
this.imgResize();
},
imgResize: function (scale) {
var img = this.elements.img,
imgInfo = this.imgInfo,
oldScale = imgInfo.s;
imgInfo.s = scale || imgInfo.s;
img.css({
width: imgInfo.w * imgInfo.s,
height: imgInfo.h * imgInfo.s
});
this.imgMove({
t: -((imgInfo.h * oldScale) - (imgInfo.h * imgInfo.s)) / 2,
l: -((imgInfo.w * oldScale) - (imgInfo.w * imgInfo.s)) / 2
});
},
imgMove: function (move) {
var img = this.elements.img,
imgInfo = this.imgInfo,
c = this.elements.container;
imgInfo.t += move.t;
imgInfo.l += move.l;
var t = imgInfo.at - imgInfo.t,
l = imgInfo.al - imgInfo.l;
if (t >= 0) t = imgInfo.t = 0;
else if (t < -((imgInfo.h * imgInfo.s) - c.height())) {
t = -((imgInfo.h * imgInfo.s) - c.height());
imgInfo.t = ((imgInfo.at === 0) ? (imgInfo.h * imgInfo.s) - c.height() : (imgInfo.h * imgInfo.s) - c.height());
}
if (l >= 0) l = imgInfo.l = 0;
else if (l < -((imgInfo.w * imgInfo.s) - c.width())) {
l = -((imgInfo.w * imgInfo.s) - c.width());
imgInfo.l = ((imgInfo.al === 0) ? (imgInfo.w * imgInfo.s) - c.width() : (imgInfo.w * imgInfo.s) - c.width());
}
// Set Position
img.css({
top: t,
left: l
});
if (this.elements.preview)
this.preview(this.elements.preview.width, this.elements.preview.height, this.elements.preview.container);
},
data: function (width, height, filetype) {
var c = this.elements.container,
imgInfo = this.imgInfo,
img = this.elements.img;
var original = new Image();
original.src = img.attr('src');
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var w = Math.round((c.width() - (0 * 2)) * (imgInfo.aw / (imgInfo.w * imgInfo.s))),
h = Math.round((c.height() - (0 * 2)) * (imgInfo.ah / (imgInfo.h * imgInfo.s))),
x = Math.round(-(parseInt(img.css('left')) - 0) * (imgInfo.aw / (imgInfo.w * imgInfo.s))),
y = Math.round(-(parseInt(img.css('top')) - 0) * (imgInfo.ah / (imgInfo.h * imgInfo.s)));
canvas.getContext('2d').drawImage(original, x, y, w, h, 0, 0, width, height);
return {
width: width,
height: height,
image: canvas.toDataURL("image/" + filetype),
filetype: filetype
};
},
preview: function (width, height, target) {
if (!$(target + ' img').length)
$(target).append('<img>');
var c = this.elements.container,
imgInfo = this.imgInfo,
img = this.elements.img;
var original = new Image();
original.src = img.attr('src');
// draw image to canvas
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var w = Math.round((c.width() - (0 * 2)) * (imgInfo.aw / (imgInfo.w * imgInfo.s))),
h = Math.round((c.height() - (0 * 2)) * (imgInfo.ah / (imgInfo.h * imgInfo.s))),
x = Math.round(-(parseInt(img.css('left')) - 0) * (imgInfo.aw / (imgInfo.w * imgInfo.s))),
y = Math.round(-(parseInt(img.css('top')) - 0) * (imgInfo.ah / (imgInfo.h * imgInfo.s)));
canvas.getContext('2d').drawImage(original, x, y, w, h, 0, 0, width, height);
$(target + ' img')
.attr('src', canvas.toDataURL());
},
flip: function () {
var c = this.elements.container,
img = this.elements.img;
var original = new Image();
original.src = img.attr('src');
var height = original.naturalHeight;
var width = original.naturalWidth;
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').translate(width, 0);
canvas.getContext('2d').scale(-1, 1);
canvas.getContext('2d').drawImage(original, 0, 0);
canvas.getContext('2d').translate(width, 0);
canvas.getContext('2d').scale(-1, 1);
c.find('.crop-img')
.removeAttr('style')
.attr('src', canvas.toDataURL());
},
rotate: function () {
var c = this.elements.container,
img = this.elements.img;
// get current width & height
var original = new Image();
original.src = img.attr('src');
var height = original.naturalHeight;
var width = original.naturalWidth;
var canvas = document.createElement('canvas');
canvas.width = height;
canvas.height = width;
canvas.getContext('2d').translate(canvas.width / 2, canvas.height / 2);
canvas.getContext('2d').rotate(Math.PI / 2);
canvas.getContext('2d').drawImage(original, -width / 2, -height / 2);
canvas.getContext('2d').rotate(-Math.PI / 2);
canvas.getContext('2d').translate(-canvas.width / 2, -canvas.height / 2);
c.find('.crop-img')
.removeAttr('style')
.attr('src', canvas.toDataURL());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment