function isNumber(n) { return typeof n === 'number' && !isNaN(n); } function isUndefined(n) { return typeof n === 'undefined'; } function toArray(obj, offset) { var args = []; // This is necessary for IE8 if (isNumber(offset)) { args.push(offset); } return args.slice.apply(obj, args); } // Custom proxy to avoid jQuery's guid function proxy(fn, context) { var args = toArray(arguments, 2); return function () { return fn.apply(context, args.concat(toArray(arguments))); }; } function isCrossOriginURL(url) { var parts = url.match(/^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i); return parts && ( parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port ); } function addTimestamp(url) { var timestamp = 'timestamp=' + (new Date()).getTime(); return (url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp); } function getCrossOrigin(crossOrigin) { return crossOrigin ? ' crossOrigin="' + crossOrigin + '"' : ''; } function getImageSize(image, callback) { var newImage; // Modern browsers if (image.naturalWidth) { return callback(image.naturalWidth, image.naturalHeight); } // IE8: Don't use `new Image()` here (#319) newImage = document.createElement('img'); newImage.onload = function () { callback(this.width, this.height); }; newImage.src = image.src; } function getTransform(options) { var transforms = []; var rotate = options.rotate; var scaleX = options.scaleX; var scaleY = options.scaleY; if (isNumber(rotate)) { transforms.push('rotate(' + rotate + 'deg)'); } if (isNumber(scaleX) && isNumber(scaleY)) { transforms.push('scale(' + scaleX + ',' + scaleY + ')'); } return transforms.length ? transforms.join(' ') : 'none'; } function getRotatedSizes(data, reverse) { var deg = abs(data.degree) % 180; var arc = (deg > 90 ? (180 - deg) : deg) * Math.PI / 180; var sinArc = sin(arc); var cosArc = cos(arc); var width = data.width; var height = data.height; var aspectRatio = data.aspectRatio; var newWidth; var newHeight; if (!reverse) { newWidth = width * cosArc + height * sinArc; newHeight = width * sinArc + height * cosArc; } else { newWidth = width / (cosArc + sinArc / aspectRatio); newHeight = newWidth / aspectRatio; } return { width: newWidth, height: newHeight }; } function getSourceCanvas(image, data) { var canvas = $('')[0]; var context = canvas.getContext('2d'); var x = 0; var y = 0; var width = data.naturalWidth; var height = data.naturalHeight; var rotate = data.rotate; var scaleX = data.scaleX; var scaleY = data.scaleY; var scalable = isNumber(scaleX) && isNumber(scaleY) && (scaleX !== 1 || scaleY !== 1); var rotatable = isNumber(rotate) && rotate !== 0; var advanced = rotatable || scalable; var canvasWidth = width; var canvasHeight = height; var translateX; var translateY; var rotated; if (scalable) { translateX = width / 2; translateY = height / 2; } if (rotatable) { rotated = getRotatedSizes({ width: width, height: height, degree: rotate }); canvasWidth = rotated.width; canvasHeight = rotated.height; translateX = rotated.width / 2; translateY = rotated.height / 2; } canvas.width = canvasWidth; canvas.height = canvasHeight; if (advanced) { x = -width / 2; y = -height / 2; context.save(); context.translate(translateX, translateY); } if (rotatable) { context.rotate(rotate * Math.PI / 180); } // Should call `scale` after rotated if (scalable) { context.scale(scaleX, scaleY); } context.drawImage(image, x, y, width, height); if (advanced) { context.restore(); } return canvas; }