Created
July 27, 2015 14:40
-
-
Save hamishhossack/696d39dd1cf1a35840a6 to your computer and use it in GitHub Desktop.
Image Cropping Manager (needs optimising)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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