diff --git a/service/Application/Home/View/Default/Public/Footer.html b/service/Application/Home/View/Default/Public/Footer.html index 73050dce0..6cb8bce5a 100755 --- a/service/Application/Home/View/Default/Public/Footer.html +++ b/service/Application/Home/View/Default/Public/Footer.html @@ -22,6 +22,9 @@ + + + diff --git a/service/Application/Home/View/Default/Public/Header.html b/service/Application/Home/View/Default/Public/Header.html index f79493cca..d3fcc082a 100755 --- a/service/Application/Home/View/Default/Public/Header.html +++ b/service/Application/Home/View/Default/Public/Header.html @@ -14,6 +14,7 @@ + diff --git a/service/Application/Home/View/Default/Public/UserMenu.html b/service/Application/Home/View/Default/Public/UserMenu.html index 928dce7c5..05972d798 100755 --- a/service/Application/Home/View/Default/Public/UserMenu.html +++ b/service/Application/Home/View/Default/Public/UserMenu.html @@ -26,4 +26,44 @@ - \ No newline at end of file + + + +
+
+
+

头像上传

+ × +
+
+
+ +
+
+ Picture +
+
+
+
+ + + + + +
+
+ +
+ + +
+ +
+ + + 请上传图片 +
+
+
+
\ No newline at end of file diff --git a/service/Application/Home/View/Default/User/Index.html b/service/Application/Home/View/Default/User/Index.html index 2af547f21..7eae0111a 100755 --- a/service/Application/Home/View/Default/User/Index.html +++ b/service/Application/Home/View/Default/User/Index.html @@ -34,7 +34,7 @@

{{$user.user_name_view}}

diff --git a/service/Public/Common/Lib/cropper/cropper.css b/service/Public/Common/Lib/cropper/cropper.css new file mode 100755 index 000000000..6707912a2 --- /dev/null +++ b/service/Public/Common/Lib/cropper/cropper.css @@ -0,0 +1,248 @@ +/*! + * Cropper v0.9.2 + * https://github.com/fengyuanchen/cropper + * + * Copyright (c) 2014-2015 Fengyuan Chen and contributors + * Released under the MIT license + * + * Date: 2015-04-18T04:35:01.500Z + */ +.cropper-container { + position: relative; + overflow: hidden; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; +} +.cropper-container img { + display: block; + width: 100%; + min-width: 0 !important; + max-width: none !important; + height: 100%; + min-height: 0 !important; + max-height: none !important; + + image-orientation: 0deg !important; +} +.cropper-canvas, +.cropper-drag-box, +.cropper-crop-box, +.cropper-modal { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} +.cropper-drag-box { + background-color: #fff; + filter: alpha(opacity=0); + opacity: 0; +} +.cropper-modal { + background-color: #000; + filter: alpha(opacity=50); + opacity: .5; +} +.cropper-view-box { + display: block; + width: 100%; + height: 100%; + overflow: hidden; + outline: 1px solid #69f; + outline-color: rgba(102, 153, 255, .75); +} +.cropper-dashed { + position: absolute; + display: block; + filter: alpha(opacity=50); + border: 0 dashed #fff; + opacity: .5; +} +.cropper-dashed.dashed-h { + top: 33.33333333%; + left: 0; + width: 100%; + height: 33.33333333%; + border-top-width: 1px; + border-bottom-width: 1px; +} +.cropper-dashed.dashed-v { + top: 0; + left: 33.33333333%; + width: 33.33333333%; + height: 100%; + border-right-width: 1px; + border-left-width: 1px; +} +.cropper-face, +.cropper-line, +.cropper-point { + position: absolute; + display: block; + width: 100%; + height: 100%; + filter: alpha(opacity=10); + opacity: .1; +} +.cropper-face { + top: 0; + left: 0; + cursor: move; + background-color: #fff; +} +.cropper-line { + background-color: #69f; +} +.cropper-line.line-e { + top: 0; + right: -3px; + width: 5px; + cursor: e-resize; +} +.cropper-line.line-n { + top: -3px; + left: 0; + height: 5px; + cursor: n-resize; +} +.cropper-line.line-w { + top: 0; + left: -3px; + width: 5px; + cursor: w-resize; +} +.cropper-line.line-s { + bottom: -3px; + left: 0; + height: 5px; + cursor: s-resize; +} +.cropper-point { + width: 5px; + height: 5px; + background-color: #69f; + filter: alpha(opacity=75); + opacity: .75; +} +.cropper-point.point-e { + top: 50%; + right: -3px; + margin-top: -3px; + cursor: e-resize; +} +.cropper-point.point-n { + top: -3px; + left: 50%; + margin-left: -3px; + cursor: n-resize; +} +.cropper-point.point-w { + top: 50%; + left: -3px; + margin-top: -3px; + cursor: w-resize; +} +.cropper-point.point-s { + bottom: -3px; + left: 50%; + margin-left: -3px; + cursor: s-resize; +} +.cropper-point.point-ne { + top: -3px; + right: -3px; + cursor: ne-resize; +} +.cropper-point.point-nw { + top: -3px; + left: -3px; + cursor: nw-resize; +} +.cropper-point.point-sw { + bottom: -3px; + left: -3px; + cursor: sw-resize; +} +.cropper-point.point-se { + right: -3px; + bottom: -3px; + width: 20px; + height: 20px; + cursor: se-resize; + filter: alpha(opacity=100); + opacity: 1; +} +.cropper-point.point-se:before { + position: absolute; + right: -50%; + bottom: -50%; + display: block; + width: 200%; + height: 200%; + content: " "; + background-color: #69f; + filter: alpha(opacity=0); + opacity: 0; +} +@media (min-width: 768px) { + .cropper-point.point-se { + width: 15px; + height: 15px; + } +} +@media (min-width: 992px) { + .cropper-point.point-se { + width: 10px; + height: 10px; + } +} +@media (min-width: 1200px) { + .cropper-point.point-se { + width: 5px; + height: 5px; + filter: alpha(opacity=75); + opacity: .75; + } +} +.cropper-bg { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC"); +} +.cropper-invisible { + filter: alpha(opacity=0); + opacity: 0; +} +.cropper-hide { + position: fixed; + top: 0; + left: 0; + z-index: -1; + width: auto!important; + min-width: 0!important; + max-width: none!important; + height: auto!important; + min-height: 0!important; + max-height: none!important; + filter: alpha(opacity=0); + opacity: 0; +} +.cropper-hidden { + display: none !important; +} +.cropper-move { + cursor: move; +} +.cropper-crop { + cursor: crosshair; +} +.cropper-disabled .cropper-drag-box, +.cropper-disabled .cropper-face, +.cropper-disabled .cropper-line, +.cropper-disabled .cropper-point { + cursor: not-allowed; +} diff --git a/service/Public/Common/Lib/cropper/cropper.js b/service/Public/Common/Lib/cropper/cropper.js new file mode 100755 index 000000000..733c2cd52 --- /dev/null +++ b/service/Public/Common/Lib/cropper/cropper.js @@ -0,0 +1,1980 @@ +/*! + * Cropper v0.9.2 + * https://github.com/fengyuanchen/cropper + * + * Copyright (c) 2014-2015 Fengyuan Chen and contributors + * Released under the MIT license + * + * Date: 2015-04-18T04:35:01.500Z + */ + +(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as anonymous module. + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // Node / CommonJS + factory(require('jquery')); + } else { + // Browser globals. + factory(jQuery); + } +})(function ($) { + + 'use strict'; + + var $window = $(window), + $document = $(document), + location = window.location, + + // Constants + CROPPER_NAMESPACE = '.cropper', + CROPPER_PREVIEW = 'preview' + CROPPER_NAMESPACE, + + // RegExps + REGEXP_DRAG_TYPES = /^(e|n|w|s|ne|nw|sw|se|all|crop|move|zoom)$/, + + // Classes + CLASS_MODAL = 'cropper-modal', + CLASS_HIDE = 'cropper-hide', + CLASS_HIDDEN = 'cropper-hidden', + CLASS_INVISIBLE = 'cropper-invisible', + CLASS_MOVE = 'cropper-move', + CLASS_CROP = 'cropper-crop', + CLASS_DISABLED = 'cropper-disabled', + CLASS_BG = 'cropper-bg', + + // Events + EVENT_MOUSE_DOWN = 'mousedown touchstart', + EVENT_MOUSE_MOVE = 'mousemove touchmove', + EVENT_MOUSE_UP = 'mouseup mouseleave touchend touchleave touchcancel', + EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll', + EVENT_DBLCLICK = 'dblclick', + EVENT_RESIZE = 'resize' + CROPPER_NAMESPACE, // Bind to window with namespace + EVENT_BUILD = 'build' + CROPPER_NAMESPACE, + EVENT_BUILT = 'built' + CROPPER_NAMESPACE, + EVENT_DRAG_START = 'dragstart' + CROPPER_NAMESPACE, + EVENT_DRAG_MOVE = 'dragmove' + CROPPER_NAMESPACE, + EVENT_DRAG_END = 'dragend' + CROPPER_NAMESPACE, + EVENT_ZOOM_IN = 'zoomin' + CROPPER_NAMESPACE, + EVENT_ZOOM_OUT = 'zoomout' + CROPPER_NAMESPACE, + + // Supports + SUPPORT_CANVAS = $.isFunction($('')[0].getContext), + + // Others + sqrt = Math.sqrt, + min = Math.min, + max = Math.max, + abs = Math.abs, + sin = Math.sin, + cos = Math.cos, + num = parseFloat, + + // Prototype + prototype = {}; + + function isNumber(n) { + return typeof n === 'number'; + } + + function isUndefined(n) { + return typeof n === 'undefined'; + } + + function toArray(obj, offset) { + var args = []; + + if (isNumber(offset)) { // It's necessary for IE8 + 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 inRange(source, target) { + return target.left < 0 && source.width < (target.left + target.width) && target.top < 0 && source.height < (target.top + target.height); + } + + function getRotateValue(degree) { + return degree ? 'rotate(' + degree + 'deg)' : 'none'; + } + + function getRotatedSizes(data, reverse) { + var deg = abs(data.degree) % 180, + arc = (deg > 90 ? (180 - deg) : deg) * Math.PI / 180, + sinArc = sin(arc), + cosArc = cos(arc), + width = data.width, + height = data.height, + aspectRatio = data.aspectRatio, + newWidth, + 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], + context = canvas.getContext('2d'), + width = data.naturalWidth, + height = data.naturalHeight, + rotate = data.rotate, + rotated = getRotatedSizes({ + width: width, + height: height, + degree: rotate + }); + + if (rotate) { + canvas.width = rotated.width; + canvas.height = rotated.height; + context.save(); + context.translate(rotated.width / 2, rotated.height / 2); + context.rotate(rotate * Math.PI / 180); + context.drawImage(image, -width / 2, -height / 2, width, height); + context.restore(); + } else { + canvas.width = width; + canvas.height = height; + context.drawImage(image, 0, 0, width, height); + } + + return canvas; + } + + function Cropper(element, options) { + this.$element = $(element); + this.options = $.extend({}, Cropper.DEFAULTS, $.isPlainObject(options) && options); + + this.ready = false; + this.built = false; + this.rotated = false; + this.cropped = false; + this.disabled = false; + this.canvas = null; + this.cropBox = null; + + this.load(); + } + + prototype.load = function (url) { + var options = this.options, + $this = this.$element, + crossOrigin, + bustCacheUrl, + buildEvent, + $clone; + + if (!url) { + if ($this.is('img')) { + if (!$this.attr('src')) { + return; + } + + url = $this.prop('src'); + } else if ($this.is('canvas') && SUPPORT_CANVAS) { + url = $this[0].toDataURL(); + } + } + + if (!url) { + return; + } + + buildEvent = $.Event(EVENT_BUILD); + $this.one(EVENT_BUILD, options.build).trigger(buildEvent); // Only trigger once + + if (buildEvent.isDefaultPrevented()) { + return; + } + + if (options.checkImageOrigin && isCrossOriginURL(url)) { + crossOrigin = 'anonymous'; + + if (!$this.prop('crossOrigin')) { // Only when there was not a "crossOrigin" property + bustCacheUrl = addTimestamp(url); // Bust cache (#148) + } + } + + this.$clone = $clone = $(''); + + $clone.one('load', $.proxy(function () { + var naturalWidth = $clone.prop('naturalWidth') || $clone.width(), + naturalHeight = $clone.prop('naturalHeight') || $clone.height(); + + this.image = { + naturalWidth: naturalWidth, + naturalHeight: naturalHeight, + aspectRatio: naturalWidth / naturalHeight, + rotate: 0 + }; + + this.url = url; + this.ready = true; + this.build(); + }, this)).one('error', function () { + $clone.remove(); + }).attr({ + src: bustCacheUrl || url, + crossOrigin: crossOrigin + }); + + // Hide and insert into the document + $clone.addClass(CLASS_HIDE).insertAfter($this); + }; + + prototype.build = function () { + var $this = this.$element, + $clone = this.$clone, + options = this.options, + $cropper, + $cropBox; + + if (!this.ready) { + return; + } + + if (this.built) { + this.unbuild(); + } + + // Create cropper elements + this.$cropper = $cropper = $(Cropper.TEMPLATE); + + // Hide the original image + $this.addClass(CLASS_HIDDEN); + + // Show the clone iamge + $clone.removeClass(CLASS_HIDE); + + this.$container = $this.parent().append($cropper); + this.$canvas = $cropper.find('.cropper-canvas').append($clone); + this.$dragBox = $cropper.find('.cropper-drag-box'); + this.$cropBox = $cropBox = $cropper.find('.cropper-crop-box'); + this.$viewBox = $cropper.find('.cropper-view-box'); + + this.addListeners(); + this.initPreview(); + + // Format aspect ratio + options.aspectRatio = num(options.aspectRatio) || NaN; // 0 -> NaN + + if (options.autoCrop) { + this.cropped = true; + + if (options.modal) { + this.$dragBox.addClass(CLASS_MODAL); + } + } else { + $cropBox.addClass(CLASS_HIDDEN); + } + + if (options.background) { + $cropper.addClass(CLASS_BG); + } + + if (!options.highlight) { + $cropBox.find('.cropper-face').addClass(CLASS_INVISIBLE); + } + + if (!options.guides) { + $cropBox.find('.cropper-dashed').addClass(CLASS_HIDDEN); + } + + if (!options.movable) { + $cropBox.find('.cropper-face').data('drag', 'move'); + } + + if (!options.resizable) { + $cropBox.find('.cropper-line, .cropper-point').addClass(CLASS_HIDDEN); + } + + this.setDragMode(options.dragCrop ? 'crop' : 'move'); + + this.built = true; + this.render(); + $this.one(EVENT_BUILT, options.built).trigger(EVENT_BUILT); // Only trigger once + }; + + prototype.unbuild = function () { + if (!this.built) { + return; + } + + this.built = false; + this.container = null; + this.canvas = null; + this.cropBox = null; // This is necessary when replace + this.removeListeners(); + + this.resetPreview(); + this.$preview = null; + + this.$viewBox = null; + this.$cropBox = null; + this.$dragBox = null; + this.$canvas = null; + this.$container = null; + + this.$cropper.remove(); + this.$cropper = null; + }; + + $.extend(prototype, { + render: function () { + this.initContainer(); + this.initCanvas(); + this.initCropBox(); + + this.renderCanvas(); + + if (this.cropped) { + this.renderCropBox(); + } + }, + + initContainer: function () { + var $this = this.$element, + $container = this.$container, + $cropper = this.$cropper, + options = this.options; + + $cropper.addClass(CLASS_HIDDEN); + $this.removeClass(CLASS_HIDDEN); + + $cropper.css((this.container = { + width: max($container.width(), num(options.minContainerWidth) || 200), + height: max($container.height(), num(options.minContainerHeight) || 100) + })); + + $this.addClass(CLASS_HIDDEN); + $cropper.removeClass(CLASS_HIDDEN); + }, + + // image box (wrapper) + initCanvas: function () { + var container = this.container, + containerWidth = container.width, + containerHeight = container.height, + image = this.image, + aspectRatio = image.aspectRatio, + canvas = { + aspectRatio: aspectRatio, + width: containerWidth, + height: containerHeight + }; + + if (containerHeight * aspectRatio > containerWidth) { + canvas.height = containerWidth / aspectRatio; + } else { + canvas.width = containerHeight * aspectRatio; + } + + canvas.oldLeft = canvas.left = (containerWidth - canvas.width) / 2; + canvas.oldTop = canvas.top = (containerHeight - canvas.height) / 2; + + this.canvas = canvas; + this.limitCanvas(true, true); + this.initialImage = $.extend({}, image); + this.initialCanvas = $.extend({}, canvas); + }, + + limitCanvas: function (size, position) { + var options = this.options, + strict = options.strict, + container = this.container, + containerWidth = container.width, + containerHeight = container.height, + canvas = this.canvas, + aspectRatio = canvas.aspectRatio, + cropBox = this.cropBox, + cropped = this.cropped && cropBox, + minCanvasWidth, + minCanvasHeight; + + if (size) { + minCanvasWidth = num(options.minCanvasWidth) || 0; + minCanvasHeight = num(options.minCanvasHeight) || 0; + + if (minCanvasWidth) { + if (strict) { + minCanvasWidth = max(cropped ? cropBox.width : containerWidth, minCanvasWidth); + } + + minCanvasHeight = minCanvasWidth / aspectRatio; + } else if (minCanvasHeight) { + + if (strict) { + minCanvasHeight = max(cropped ? cropBox.height : containerHeight, minCanvasHeight); + } + + minCanvasWidth = minCanvasHeight * aspectRatio; + } else if (strict) { + if (cropped) { + minCanvasWidth = cropBox.width; + minCanvasHeight = cropBox.height; + + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } else { + minCanvasWidth = containerWidth; + minCanvasHeight = containerHeight; + + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasHeight = minCanvasWidth / aspectRatio; + } else { + minCanvasWidth = minCanvasHeight * aspectRatio; + } + } + } + + $.extend(canvas, { + minWidth: minCanvasWidth, + minHeight: minCanvasHeight, + maxWidth: Infinity, + maxHeight: Infinity + }); + } + + if (position) { + if (strict) { + if (cropped) { + canvas.minLeft = min(cropBox.left, (cropBox.left + cropBox.width) - canvas.width); + canvas.minTop = min(cropBox.top, (cropBox.top + cropBox.height) - canvas.height); + canvas.maxLeft = cropBox.left; + canvas.maxTop = cropBox.top; + } else { + canvas.minLeft = min(0, containerWidth - canvas.width); + canvas.minTop = min(0, containerHeight - canvas.height); + canvas.maxLeft = max(0, containerWidth - canvas.width); + canvas.maxTop = max(0, containerHeight - canvas.height); + } + } else { + canvas.minLeft = -canvas.width; + canvas.minTop = -canvas.height; + canvas.maxLeft = containerWidth; + canvas.maxTop = containerHeight; + } + } + }, + + renderCanvas: function (changed) { + var options = this.options, + canvas = this.canvas, + image = this.image, + aspectRatio, + rotated; + + if (this.rotated) { + this.rotated = false; + + // Computes rotatation sizes with image sizes + rotated = getRotatedSizes({ + width: image.width, + height: image.height, + degree: image.rotate + }); + + aspectRatio = rotated.width / rotated.height; + + if (aspectRatio !== canvas.aspectRatio) { + canvas.left -= (rotated.width - canvas.width) / 2; + canvas.top -= (rotated.height - canvas.height) / 2; + canvas.width = rotated.width; + canvas.height = rotated.height; + canvas.aspectRatio = aspectRatio; + this.limitCanvas(true, false); + } + } + + if (canvas.width > canvas.maxWidth || canvas.width < canvas.minWidth) { + canvas.left = canvas.oldLeft; + } + + if (canvas.height > canvas.maxHeight || canvas.height < canvas.minHeight) { + canvas.top = canvas.oldTop; + } + + canvas.width = min(max(canvas.width, canvas.minWidth), canvas.maxWidth); + canvas.height = min(max(canvas.height, canvas.minHeight), canvas.maxHeight); + + this.limitCanvas(false, true); + + canvas.oldLeft = canvas.left = min(max(canvas.left, canvas.minLeft), canvas.maxLeft); + canvas.oldTop = canvas.top = min(max(canvas.top, canvas.minTop), canvas.maxTop); + + this.$canvas.css({ + width: canvas.width, + height: canvas.height, + left: canvas.left, + top: canvas.top + }); + + this.renderImage(); + + if (this.cropped && options.strict && !inRange(this.container, canvas)) { + this.limitCropBox(true, true); + } + + if (changed) { + this.output(); + } + }, + + renderImage: function () { + var canvas = this.canvas, + image = this.image, + reversed; + + if (image.rotate) { + reversed = getRotatedSizes({ + width: canvas.width, + height: canvas.height, + degree: image.rotate, + aspectRatio: image.aspectRatio + }, true); + } + + $.extend(image, reversed ? { + width: reversed.width, + height: reversed.height, + left: (canvas.width - reversed.width) / 2, + top: (canvas.height - reversed.height) / 2 + } : { + width: canvas.width, + height: canvas.height, + left: 0, + top: 0 + }); + + this.$clone.css({ + width: image.width, + height: image.height, + marginLeft: image.left, + marginTop: image.top, + transform: getRotateValue(image.rotate) + }); + }, + + initCropBox: function () { + var options = this.options, + canvas = this.canvas, + aspectRatio = options.aspectRatio, + autoCropArea = num(options.autoCropArea) || 0.8, + cropBox = { + width: canvas.width, + height: canvas.height + }; + + if (aspectRatio) { + if (canvas.height * aspectRatio > canvas.width) { + cropBox.height = cropBox.width / aspectRatio; + } else { + cropBox.width = cropBox.height * aspectRatio; + } + } + + this.cropBox = cropBox; + this.limitCropBox(true, true); + + // Initialize auto crop area + cropBox.width = min(max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); + cropBox.height = min(max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); + + // The width of auto crop area must large than "minWidth", and the height too. (#164) + cropBox.width = max(cropBox.minWidth, cropBox.width * autoCropArea); + cropBox.height = max(cropBox.minHeight, cropBox.height * autoCropArea); + cropBox.oldLeft = cropBox.left = canvas.left + (canvas.width - cropBox.width) / 2; + cropBox.oldTop = cropBox.top = canvas.top + (canvas.height - cropBox.height) / 2; + + this.initialCropBox = $.extend({}, cropBox); + }, + + limitCropBox: function (size, position) { + var options = this.options, + strict = options.strict, + container = this.container, + containerWidth = container.width, + containerHeight = container.height, + canvas = this.canvas, + cropBox = this.cropBox, + aspectRatio = options.aspectRatio, + minCropBoxWidth, + minCropBoxHeight; + + if (size) { + minCropBoxWidth = num(options.minCropBoxWidth) || 0; + minCropBoxHeight = num(options.minCropBoxHeight) || 0; + + // min/maxCropBoxWidth/Height must less than conatiner width/height + cropBox.minWidth = min(containerWidth, minCropBoxWidth); + cropBox.minHeight = min(containerHeight, minCropBoxHeight); + cropBox.maxWidth = min(containerWidth, strict ? canvas.width : containerWidth); + cropBox.maxHeight = min(containerHeight, strict ? canvas.height : containerHeight); + + if (aspectRatio) { + // compare crop box size with container first + if (cropBox.maxHeight * aspectRatio > cropBox.maxWidth) { + cropBox.minHeight = cropBox.minWidth / aspectRatio; + cropBox.maxHeight = cropBox.maxWidth / aspectRatio; + } else { + cropBox.minWidth = cropBox.minHeight * aspectRatio; + cropBox.maxWidth = cropBox.maxHeight * aspectRatio; + } + } + + // The "minWidth" must be less than "maxWidth", and the "minHeight" too. + cropBox.minWidth = min(cropBox.maxWidth, cropBox.minWidth); + cropBox.minHeight = min(cropBox.maxHeight, cropBox.minHeight); + } + + if (position) { + if (strict) { + cropBox.minLeft = max(0, canvas.left); + cropBox.minTop = max(0, canvas.top); + cropBox.maxLeft = min(containerWidth, canvas.left + canvas.width) - cropBox.width; + cropBox.maxTop = min(containerHeight, canvas.top + canvas.height) - cropBox.height; + } else { + cropBox.minLeft = 0; + cropBox.minTop = 0; + cropBox.maxLeft = containerWidth - cropBox.width; + cropBox.maxTop = containerHeight - cropBox.height; + } + } + }, + + renderCropBox: function () { + var options = this.options, + container = this.container, + containerWidth = container.width, + containerHeight = container.height, + $cropBox = this.$cropBox, + cropBox = this.cropBox; + + if (cropBox.width > cropBox.maxWidth || cropBox.width < cropBox.minWidth) { + cropBox.left = cropBox.oldLeft; + } + + if (cropBox.height > cropBox.maxHeight || cropBox.height < cropBox.minHeight) { + cropBox.top = cropBox.oldTop; + } + + cropBox.width = min(max(cropBox.width, cropBox.minWidth), cropBox.maxWidth); + cropBox.height = min(max(cropBox.height, cropBox.minHeight), cropBox.maxHeight); + + this.limitCropBox(false, true); + + cropBox.oldLeft = cropBox.left = min(max(cropBox.left, cropBox.minLeft), cropBox.maxLeft); + cropBox.oldTop = cropBox.top = min(max(cropBox.top, cropBox.minTop), cropBox.maxTop); + + if (options.movable) { + $cropBox.find('.cropper-face').data('drag', (cropBox.width === containerWidth && cropBox.height === containerHeight) ? 'move' : 'all'); + } + + $cropBox.css({ + width: cropBox.width, + height: cropBox.height, + left: cropBox.left, + top: cropBox.top + }); + + if (this.cropped && options.strict && !inRange(container, this.canvas)) { + this.limitCanvas(true, true); + } + + if (!this.disabled) { + this.output(); + } + }, + + output: function () { + var options = this.options; + + this.preview(); + + if (options.crop) { + options.crop.call(this.$element, this.getData()); + } + } + }); + + prototype.initPreview = function () { + var url = this.url; + + this.$preview = $(this.options.preview); + this.$viewBox.html(''); + + // Override img element styles + // Add `display:block` to avoid margin top issue (Occur only when margin-top <= -height) + this.$preview.each(function () { + var $this = $(this); + + $this.data(CROPPER_PREVIEW, { + width: $this.width(), + height: $this.height(), + original: $this.html() + }).html(''); + }); + }; + + prototype.resetPreview = function () { + this.$preview.each(function () { + var $this = $(this); + + $this.html($this.data(CROPPER_PREVIEW).original).removeData(CROPPER_PREVIEW); + }); + }; + + prototype.preview = function () { + var image = this.image, + canvas = this.canvas, + cropBox = this.cropBox, + width = image.width, + height = image.height, + left = cropBox.left - canvas.left - image.left, + top = cropBox.top - canvas.top - image.top, + rotate = image.rotate; + + if (!this.cropped || this.disabled) { + return; + } + + this.$viewBox.find('img').css({ + width: width, + height: height, + marginLeft: -left, + marginTop: -top, + transform: getRotateValue(rotate) + }); + + this.$preview.each(function () { + var $this = $(this), + data = $this.data(CROPPER_PREVIEW), + ratio = data.width / cropBox.width, + newWidth = data.width, + newHeight = cropBox.height * ratio; + + if (newHeight > data.height) { + ratio = data.height / cropBox.height; + newWidth = cropBox.width * ratio; + newHeight = data.height; + } + + $this.width(newWidth).height(newHeight).find('img').css({ + width: width * ratio, + height: height * ratio, + marginLeft: -left * ratio, + marginTop: -top * ratio, + transform: getRotateValue(rotate) + }); + }); + }; + + prototype.addListeners = function () { + var options = this.options; + + this.$element.on(EVENT_DRAG_START, options.dragstart).on(EVENT_DRAG_MOVE, options.dragmove).on(EVENT_DRAG_END, options.dragend).on(EVENT_ZOOM_IN, options.zoomin).on(EVENT_ZOOM_OUT, options.zoomout); + this.$cropper.on(EVENT_MOUSE_DOWN, $.proxy(this.dragstart, this)).on(EVENT_DBLCLICK, $.proxy(this.dblclick, this)); + + if (options.zoomable && options.mouseWheelZoom) { + this.$cropper.on(EVENT_WHEEL, $.proxy(this.wheel, this)); + } + + $document.on(EVENT_MOUSE_MOVE, (this._dragmove = proxy(this.dragmove, this))).on(EVENT_MOUSE_UP, (this._dragend = proxy(this.dragend, this))); + + if (options.responsive) { + $window.on(EVENT_RESIZE, (this._resize = proxy(this.resize, this))); + } + }; + + prototype.removeListeners = function () { + var options = this.options; + + this.$element.off(EVENT_DRAG_START, options.dragstart).off(EVENT_DRAG_MOVE, options.dragmove).off(EVENT_DRAG_END, options.dragend).off(EVENT_ZOOM_IN, options.zoomin).off(EVENT_ZOOM_OUT, options.zoomout); + this.$cropper.off(EVENT_MOUSE_DOWN, this.dragstart).off(EVENT_DBLCLICK, this.dblclick); + + if (options.zoomable && options.mouseWheelZoom) { + this.$cropper.off(EVENT_WHEEL, this.wheel); + } + + $document.off(EVENT_MOUSE_MOVE, this._dragmove).off(EVENT_MOUSE_UP, this._dragend); + + if (options.responsive) { + $window.off(EVENT_RESIZE, this._resize); + } + }; + + $.extend(prototype, { + resize: function () { + var $container = this.$container, + container = this.container, + canvasData, + cropBoxData, + ratio; + + if (this.disabled) { + return; + } + + ratio = $container.width() / container.width; + + if (ratio !== 1 || $container.height() !== container.height) { + canvasData = this.getCanvasData(); + cropBoxData = this.getCropBoxData(); + + this.render(); + this.setCanvasData($.each(canvasData, function (i, n) { + canvasData[i] = n * ratio; + })); + this.setCropBoxData($.each(cropBoxData, function (i, n) { + cropBoxData[i] = n * ratio; + })); + } + }, + + dblclick: function () { + if (this.disabled) { + return; + } + + if (this.$dragBox.hasClass(CLASS_CROP)) { + this.setDragMode('move'); + } else { + this.setDragMode('crop'); + } + }, + + wheel: function (event) { + var e = event.originalEvent, + delta = 1; + + if (this.disabled) { + return; + } + + event.preventDefault(); + + if (e.deltaY) { + delta = e.deltaY > 0 ? 1 : -1; + } else if (e.wheelDelta) { + delta = -e.wheelDelta / 120; + } else if (e.detail) { + delta = e.detail > 0 ? 1 : -1; + } + + this.zoom(-delta * 0.1); + }, + + dragstart: function (event) { + var options = this.options, + originalEvent = event.originalEvent, + touches = originalEvent && originalEvent.touches, + e = event, + dragType, + dragStartEvent, + touchesLength; + + if (this.disabled) { + return; + } + + if (touches) { + touchesLength = touches.length; + + if (touchesLength > 1) { + if (options.zoomable && options.touchDragZoom && touchesLength === 2) { + e = touches[1]; + this.startX2 = e.pageX; + this.startY2 = e.pageY; + dragType = 'zoom'; + } else { + return; + } + } + + e = touches[0]; + } + + dragType = dragType || $(e.target).data('drag'); + + if (REGEXP_DRAG_TYPES.test(dragType)) { + event.preventDefault(); + + dragStartEvent = $.Event(EVENT_DRAG_START, { + originalEvent: originalEvent, + dragType: dragType + }); + + this.$element.trigger(dragStartEvent); + + if (dragStartEvent.isDefaultPrevented()) { + return; + } + + this.dragType = dragType; + this.cropping = false; + this.startX = e.pageX; + this.startY = e.pageY; + + if (dragType === 'crop') { + this.cropping = true; + this.$dragBox.addClass(CLASS_MODAL); + } + } + }, + + dragmove: function (event) { + var options = this.options, + originalEvent = event.originalEvent, + touches = originalEvent && originalEvent.touches, + e = event, + dragType = this.dragType, + dragMoveEvent, + touchesLength; + + if (this.disabled) { + return; + } + + if (touches) { + touchesLength = touches.length; + + if (touchesLength > 1) { + if (options.zoomable && options.touchDragZoom && touchesLength === 2) { + e = touches[1]; + this.endX2 = e.pageX; + this.endY2 = e.pageY; + } else { + return; + } + } + + e = touches[0]; + } + + if (dragType) { + event.preventDefault(); + + dragMoveEvent = $.Event(EVENT_DRAG_MOVE, { + originalEvent: originalEvent, + dragType: dragType + }); + + this.$element.trigger(dragMoveEvent); + + if (dragMoveEvent.isDefaultPrevented()) { + return; + } + + this.endX = e.pageX; + this.endY = e.pageY; + + this.change(); + } + }, + + dragend: function (event) { + var dragType = this.dragType, + dragEndEvent; + + if (this.disabled) { + return; + } + + if (dragType) { + event.preventDefault(); + + dragEndEvent = $.Event(EVENT_DRAG_END, { + originalEvent: event.originalEvent, + dragType: dragType + }); + + this.$element.trigger(dragEndEvent); + + if (dragEndEvent.isDefaultPrevented()) { + return; + } + + if (this.cropping) { + this.cropping = false; + this.$dragBox.toggleClass(CLASS_MODAL, this.cropped && this.options.modal); + } + + this.dragType = ''; + } + } + }); + + $.extend(prototype, { + reset: function () { + if (!this.built || this.disabled) { + return; + } + + this.image = $.extend({}, this.initialImage); + this.canvas = $.extend({}, this.initialCanvas); + this.renderCanvas(); + + if (this.cropped) { + this.cropBox = $.extend({}, this.initialCropBox); + this.renderCropBox(); + } + }, + + clear: function () { + if (!this.cropped || this.disabled) { + return; + } + + $.extend(this.cropBox, { + left: 0, + top: 0, + width: 0, + height: 0 + }); + + this.cropped = false; + this.renderCropBox(); + + this.limitCanvas(); + this.renderCanvas(); // Render canvas after render crop box + + this.$dragBox.removeClass(CLASS_MODAL); + this.$cropBox.addClass(CLASS_HIDDEN); + }, + + destroy: function () { + var $this = this.$element; + + if (this.ready) { + this.unbuild(); + $this.removeClass(CLASS_HIDDEN); + } else { + this.$clone.off('load').remove(); + } + + $this.removeData('cropper'); + }, + + replace: function (url) { + if (!this.disabled && url) { + this.load(url); + } + }, + + enable: function () { + if (this.built) { + this.disabled = false; + this.$cropper.removeClass(CLASS_DISABLED); + } + }, + + disable: function () { + if (this.built) { + this.disabled = true; + this.$cropper.addClass(CLASS_DISABLED); + } + }, + + move: function (offsetX, offsetY) { + var canvas = this.canvas; + + if (this.built && !this.disabled && isNumber(offsetX) && isNumber(offsetY)) { + canvas.left += offsetX; + canvas.top += offsetY; + this.renderCanvas(true); + } + }, + + zoom: function (delta) { + var canvas = this.canvas, + zoomEvent, + width, + height; + + delta = num(delta); + + if (delta && this.built && !this.disabled && this.options.zoomable) { + zoomEvent = delta > 0 ? $.Event(EVENT_ZOOM_IN) : $.Event(EVENT_ZOOM_OUT); + this.$element.trigger(zoomEvent); + + if (zoomEvent.isDefaultPrevented()) { + return; + } + + delta = delta <= -1 ? 1 / (1 - delta) : delta <= 1 ? (1 + delta) : delta; + width = canvas.width * delta; + height = canvas.height * delta; + canvas.left -= (width - canvas.width) / 2; + canvas.top -= (height - canvas.height) / 2; + canvas.width = width; + canvas.height = height; + this.renderCanvas(true); + this.setDragMode('move'); + } + }, + + rotate: function (degree) { + var image = this.image; + + degree = num(degree); + + if (degree && this.built && !this.disabled && this.options.rotatable) { + image.rotate = (image.rotate + degree) % 360; + this.rotated = true; + this.renderCanvas(true); + } + }, + + getData: function () { + var cropBox = this.cropBox, + canvas = this.canvas, + image = this.image, + ratio, + data; + + if (this.built && this.cropped) { + data = { + x: cropBox.left - canvas.left, + y: cropBox.top - canvas.top, + width: cropBox.width, + height: cropBox.height + }; + + ratio = image.width / image.naturalWidth; + + $.each(data, function (i, n) { + n = n / ratio; + data[i] = n; + }); + + } else { + data = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + } + + data.rotate = image.rotate; + + return data; + }, + + getContainerData: function () { + return this.built ? this.container : {}; + }, + + getImageData: function () { + return this.ready ? this.image : {}; + }, + + getCanvasData: function () { + var canvas = this.canvas, + data; + + if (this.built) { + data = { + left: canvas.left, + top: canvas.top, + width: canvas.width, + height: canvas.height + }; + } + + return data || {}; + }, + + setCanvasData: function (data) { + var canvas = this.canvas, + aspectRatio = canvas.aspectRatio; + + if (this.built && !this.disabled && $.isPlainObject(data)) { + if (isNumber(data.left)) { + canvas.left = data.left; + } + + if (isNumber(data.top)) { + canvas.top = data.top; + } + + if (isNumber(data.width)) { + canvas.width = data.width; + canvas.height = data.width / aspectRatio; + } else if (isNumber(data.height)) { + canvas.height = data.height; + canvas.width = data.height * aspectRatio; + } + + this.renderCanvas(true); + } + }, + + getCropBoxData: function () { + var cropBox = this.cropBox, + data; + + if (this.built && this.cropped) { + data = { + left: cropBox.left, + top: cropBox.top, + width: cropBox.width, + height: cropBox.height + }; + } + + return data || {}; + }, + + setCropBoxData: function (data) { + var cropBox = this.cropBox, + aspectRatio = this.options.aspectRatio; + + if (this.built && this.cropped && !this.disabled && $.isPlainObject(data)) { + + if (isNumber(data.left)) { + cropBox.left = data.left; + } + + if (isNumber(data.top)) { + cropBox.top = data.top; + } + + if (aspectRatio) { + if (isNumber(data.width)) { + cropBox.width = data.width; + cropBox.height = cropBox.width / aspectRatio; + } else if (isNumber(data.height)) { + cropBox.height = data.height; + cropBox.width = cropBox.height * aspectRatio; + } + } else { + if (isNumber(data.width)) { + cropBox.width = data.width; + } + + if (isNumber(data.height)) { + cropBox.height = data.height; + } + } + + this.renderCropBox(); + } + }, + + getCroppedCanvas: function (options) { + var originalWidth, + originalHeight, + canvasWidth, + canvasHeight, + scaledWidth, + scaledHeight, + scaledRatio, + aspectRatio, + canvas, + context, + data; + + if (!this.built || !this.cropped || !SUPPORT_CANVAS) { + return; + } + + if (!$.isPlainObject(options)) { + options = {}; + } + + data = this.getData(); + originalWidth = data.width; + originalHeight = data.height; + aspectRatio = originalWidth / originalHeight; + + if ($.isPlainObject(options)) { + scaledWidth = options.width; + scaledHeight = options.height; + + if (scaledWidth) { + scaledHeight = scaledWidth / aspectRatio; + scaledRatio = scaledWidth / originalWidth; + } else if (scaledHeight) { + scaledWidth = scaledHeight * aspectRatio; + scaledRatio = scaledHeight / originalHeight; + } + } + + canvasWidth = scaledWidth || originalWidth; + canvasHeight = scaledHeight || originalHeight; + + canvas = $('')[0]; + canvas.width = canvasWidth; + canvas.height = canvasHeight; + context = canvas.getContext('2d'); + + if (options.fillColor) { + context.fillStyle = options.fillColor; + context.fillRect(0, 0, canvasWidth, canvasHeight); + } + + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage + context.drawImage.apply(context, (function () { + var source = getSourceCanvas(this.$clone[0], this.image), + sourceWidth = source.width, + sourceHeight = source.height, + args = [source], + srcX = data.x, // source canvas + srcY = data.y, + srcWidth, + srcHeight, + dstX, // destination canvas + dstY, + dstWidth, + dstHeight; + + if (srcX <= -originalWidth || srcX > sourceWidth) { + srcX = srcWidth = dstX = dstWidth = 0; + } else if (srcX <= 0) { + dstX = -srcX; + srcX = 0; + srcWidth = dstWidth = min(sourceWidth, originalWidth + srcX); + } else if (srcX <= sourceWidth) { + dstX = 0; + srcWidth = dstWidth = min(originalWidth, sourceWidth - srcX); + } + + if (srcWidth <= 0 || srcY <= -originalHeight || srcY > sourceHeight) { + srcY = srcHeight = dstY = dstHeight = 0; + } else if (srcY <= 0) { + dstY = -srcY; + srcY = 0; + srcHeight = dstHeight = min(sourceHeight, originalHeight + srcY); + } else if (srcY <= sourceHeight) { + dstY = 0; + srcHeight = dstHeight = min(originalHeight, sourceHeight - srcY); + } + + args.push(srcX, srcY, srcWidth, srcHeight); + + // Scale destination sizes + if (scaledRatio) { + dstX *= scaledRatio; + dstY *= scaledRatio; + dstWidth *= scaledRatio; + dstHeight *= scaledRatio; + } + + // Avoid "IndexSizeError" in IE and Firefox + if (dstWidth > 0 && dstHeight > 0) { + args.push(dstX, dstY, dstWidth, dstHeight); + } + + return args; + }).call(this)); + + return canvas; + }, + + setAspectRatio: function (aspectRatio) { + var options = this.options; + + if (!this.disabled && !isUndefined(aspectRatio)) { + options.aspectRatio = num(aspectRatio) || NaN; // 0 -> NaN + + if (this.built) { + this.initCropBox(); + + if (this.cropped) { + this.renderCropBox(); + } + } + } + }, + + setDragMode: function (mode) { + var $dragBox = this.$dragBox, + cropable = false, + movable = false; + + if (!this.ready || this.disabled) { + return; + } + + switch (mode) { + case 'crop': + if (this.options.dragCrop) { + cropable = true; + $dragBox.data('drag', mode); + } else { + movable = true; + } + + break; + + case 'move': + movable = true; + $dragBox.data('drag', mode); + + break; + + default: + $dragBox.removeData('drag'); + } + + $dragBox.toggleClass(CLASS_CROP, cropable).toggleClass(CLASS_MOVE, movable); + } + }); + + prototype.change = function () { + var dragType = this.dragType, + options = this.options, + canvas = this.canvas, + container = this.container, + cropBox = this.cropBox, + width = cropBox.width, + height = cropBox.height, + left = cropBox.left, + top = cropBox.top, + right = left + width, + bottom = top + height, + minLeft = 0, + minTop = 0, + maxWidth = container.width, + maxHeight = container.height, + renderable = true, + aspectRatio = options.aspectRatio, + range = { + x: this.endX - this.startX, + y: this.endY - this.startY + }, + offset; + + if (options.strict) { + minLeft = cropBox.minLeft; + minTop = cropBox.minTop; + maxWidth = minLeft + min(container.width, canvas.width); + maxHeight = minTop + min(container.height, canvas.height); + } + + if (aspectRatio) { + range.X = range.y * aspectRatio; + range.Y = range.x / aspectRatio; + } + + switch (dragType) { + // Move cropBox + case 'all': + left += range.x; + top += range.y; + break; + + // Resize cropBox + case 'e': + if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) { + renderable = false; + break; + } + + width += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top -= range.Y / 2; + } + + if (width < 0) { + dragType = 'w'; + width = 0; + } + + break; + + case 'n': + if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) { + renderable = false; + break; + } + + height -= range.y; + top += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left += range.X / 2; + } + + if (height < 0) { + dragType = 's'; + height = 0; + } + + break; + + case 'w': + if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) { + renderable = false; + break; + } + + width -= range.x; + left += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top += range.Y / 2; + } + + if (width < 0) { + dragType = 'e'; + width = 0; + } + + break; + + case 's': + if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) { + renderable = false; + break; + } + + height += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left -= range.X / 2; + } + + if (height < 0) { + dragType = 'n'; + height = 0; + } + + break; + + case 'ne': + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || right >= maxWidth)) { + renderable = false; + break; + } + + height -= range.y; + top += range.y; + width = height * aspectRatio; + } else { + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y <= 0) { + if (top > 0) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + dragType = 'sw'; + height = 0; + width = 0; + } else if (width < 0) { + dragType = 'nw'; + width = 0; + } else if (height < 0) { + dragType = 'se'; + height = 0; + } + + break; + + case 'nw': + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || left <= minLeft)) { + renderable = false; + break; + } + + height -= range.y; + top += range.y; + width = height * aspectRatio; + left += range.X; + } else { + if (range.x <= 0) { + if (left > 0) { + width -= range.x; + left += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y <= 0) { + if (top > 0) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + dragType = 'se'; + height = 0; + width = 0; + } else if (width < 0) { + dragType = 'ne'; + width = 0; + } else if (height < 0) { + dragType = 'sw'; + height = 0; + } + + break; + + case 'sw': + if (aspectRatio) { + if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) { + renderable = false; + break; + } + + width -= range.x; + left += range.x; + height = width / aspectRatio; + } else { + if (range.x <= 0) { + if (left > 0) { + width -= range.x; + left += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + dragType = 'ne'; + height = 0; + width = 0; + } else if (width < 0) { + dragType = 'se'; + width = 0; + } else if (height < 0) { + dragType = 'nw'; + height = 0; + } + + break; + + case 'se': + if (aspectRatio) { + if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) { + renderable = false; + break; + } + + width += range.x; + height = width / aspectRatio; + } else { + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + dragType = 'nw'; + height = 0; + width = 0; + } else if (width < 0) { + dragType = 'sw'; + width = 0; + } else if (height < 0) { + dragType = 'ne'; + height = 0; + } + + break; + + // Move image + case 'move': + canvas.left += range.x; + canvas.top += range.y; + this.renderCanvas(true); + renderable = false; + break; + + // Scale image + case 'zoom': + this.zoom(function (x1, y1, x2, y2) { + var z1 = sqrt(x1 * x1 + y1 * y1), + z2 = sqrt(x2 * x2 + y2 * y2); + + return (z2 - z1) / z1; + }( + abs(this.startX - this.startX2), + abs(this.startY - this.startY2), + abs(this.endX - this.endX2), + abs(this.endY - this.endY2) + )); + + this.startX2 = this.endX2; + this.startY2 = this.endY2; + renderable = false; + break; + + // Crop image + case 'crop': + if (range.x && range.y) { + offset = this.$cropper.offset(); + left = this.startX - offset.left; + top = this.startY - offset.top; + width = cropBox.minWidth; + height = cropBox.minHeight; + + if (range.x > 0) { + if (range.y > 0) { + dragType = 'se'; + } else { + dragType = 'ne'; + top -= height; + } + } else { + if (range.y > 0) { + dragType = 'sw'; + left -= width; + } else { + dragType = 'nw'; + left -= width; + top -= height; + } + } + + // Show the cropBox if is hidden + if (!this.cropped) { + this.cropped = true; + this.$cropBox.removeClass(CLASS_HIDDEN); + } + } + + break; + + // No default + } + + if (renderable) { + cropBox.width = width; + cropBox.height = height; + cropBox.left = left; + cropBox.top = top; + this.dragType = dragType; + + this.renderCropBox(); + } + + // Override + this.startX = this.endX; + this.startY = this.endY; + }; + + $.extend(Cropper.prototype, prototype); + + Cropper.DEFAULTS = { + // Defines the aspect ratio of the crop box + // Type: Number + aspectRatio: NaN, + + // Defines the percentage of automatic cropping area when initializes + // Type: Number (Must large than 0 and less than 1) + autoCropArea: 0.8, // 80% + + // Outputs the cropping results. + // Type: Function + crop: null, + + // Add extra containers for previewing + // Type: String (jQuery selector) + preview: '', + + // Toggles + strict: true, // strict mode, the image cannot zoom out less than the container + responsive: true, // Rebuild when resize the window + checkImageOrigin: true, // Check if the target image is cross origin + + modal: true, // Show the black modal + guides: true, // Show the dashed lines for guiding + highlight: true, // Show the white modal to highlight the crop box + background: true, // Show the grid background + + autoCrop: true, // Enable to crop the image automatically when initialize + dragCrop: true, // Enable to create new crop box by dragging over the image + movable: true, // Enable to move the crop box + resizable: true, // Enable to resize the crop box + rotatable: true, // Enable to rotate the image + zoomable: true, // Enable to zoom the image + touchDragZoom: true, // Enable to zoom the image by wheeling mouse + mouseWheelZoom: true, // Enable to zoom the image by dragging touch + + // Dimensions + minCanvasWidth: 0, + minCanvasHeight: 0, + minCropBoxWidth: 0, + minCropBoxHeight: 0, + minContainerWidth: 200, + minContainerHeight: 100, + + // Events + build: null, // Function + built: null, // Function + dragstart: null, // Function + dragmove: null, // Function + dragend: null, // Function + zoomin: null, // Function + zoomout: null // Function + }; + + Cropper.setDefaults = function (options) { + $.extend(Cropper.DEFAULTS, options); + }; + + // Use the string compressor: Strmin (https://github.com/fengyuanchen/strmin) + Cropper.TEMPLATE = (function (source, words) { + words = words.split(','); + return source.replace(/\d+/g, function (i) { + return words[i]; + }); + })('<0 6="5-container"><0 6="5-canvas"><0 6="5-2-9" 3-2="move"><0 6="5-crop-9"><1 6="5-view-9"><1 6="5-8 8-h"><1 6="5-8 8-v"><1 6="5-face" 3-2="all"><1 6="5-7 7-e" 3-2="e"><1 6="5-7 7-n" 3-2="n"><1 6="5-7 7-w" 3-2="w"><1 6="5-7 7-s" 3-2="s"><1 6="5-4 4-e" 3-2="e"><1 6="5-4 4-n" 3-2="n"><1 6="5-4 4-w" 3-2="w"><1 6="5-4 4-s" 3-2="s"><1 6="5-4 4-ne" 3-2="ne"><1 6="5-4 4-nw" 3-2="nw"><1 6="5-4 4-sw" 3-2="sw"><1 6="5-4 4-se" 3-2="se">', 'div,span,drag,data,point,cropper,class,line,dashed,box'); + + /* Template source: +
+
+
+
+ + + + + + + + + + + + + + + + +
+
+ */ + + // Save the other cropper + Cropper.other = $.fn.cropper; + + // Register as jQuery plugin + $.fn.cropper = function (options) { + var args = toArray(arguments, 1), + result; + + this.each(function () { + var $this = $(this), + data = $this.data('cropper'), + fn; + + if (!data) { + $this.data('cropper', (data = new Cropper(this, options))); + } + + if (typeof options === 'string' && $.isFunction((fn = data[options]))) { + result = fn.apply(data, args); + } + }); + + return isUndefined(result) ? this : result; + }; + + $.fn.cropper.Constructor = Cropper; + $.fn.cropper.setDefaults = Cropper.setDefaults; + + // No conflict + $.fn.cropper.noConflict = function () { + $.fn.cropper = Cropper.other; + return this; + }; + +}); diff --git a/service/Public/Common/Lib/cropper/cropper.min.css b/service/Public/Common/Lib/cropper/cropper.min.css new file mode 100755 index 000000000..558039ea4 --- /dev/null +++ b/service/Public/Common/Lib/cropper/cropper.min.css @@ -0,0 +1,9 @@ +/*! + * Cropper v0.9.2 + * https://github.com/fengyuanchen/cropper + * + * Copyright (c) 2014-2015 Fengyuan Chen and contributors + * Released under the MIT license + * + * Date: 2015-04-18T04:35:01.500Z + */.cropper-container{position:relative;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.cropper-container img{display:block;width:100%;min-width:0!important;max-width:none!important;height:100%;min-height:0!important;max-height:none!important;image-orientation:0deg!important}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal{position:absolute;top:0;right:0;bottom:0;left:0}.cropper-drag-box{background-color:#fff;filter:alpha(opacity=0);opacity:0}.cropper-modal{background-color:#000;filter:alpha(opacity=50);opacity:.5}.cropper-view-box{display:block;width:100%;height:100%;overflow:hidden;outline:#69f solid 1px;outline-color:rgba(102,153,255,.75)}.cropper-dashed{position:absolute;display:block;filter:alpha(opacity=50);border:0 dashed #fff;opacity:.5}.cropper-dashed.dashed-h{top:33.33333333%;left:0;width:100%;height:33.33333333%;border-top-width:1px;border-bottom-width:1px}.cropper-dashed.dashed-v{top:0;left:33.33333333%;width:33.33333333%;height:100%;border-right-width:1px;border-left-width:1px}.cropper-face,.cropper-line,.cropper-point{position:absolute;display:block;width:100%;height:100%;filter:alpha(opacity=10);opacity:.1}.cropper-face{top:0;left:0;cursor:move;background-color:#fff}.cropper-line{background-color:#69f}.cropper-line.line-e{top:0;right:-3px;width:5px;cursor:e-resize}.cropper-line.line-n{top:-3px;left:0;height:5px;cursor:n-resize}.cropper-line.line-w{top:0;left:-3px;width:5px;cursor:w-resize}.cropper-line.line-s{bottom:-3px;left:0;height:5px;cursor:s-resize}.cropper-point{width:5px;height:5px;background-color:#69f;filter:alpha(opacity=75);opacity:.75}.cropper-point.point-e{top:50%;right:-3px;margin-top:-3px;cursor:e-resize}.cropper-point.point-n{top:-3px;left:50%;margin-left:-3px;cursor:n-resize}.cropper-point.point-w{top:50%;left:-3px;margin-top:-3px;cursor:w-resize}.cropper-point.point-s{bottom:-3px;left:50%;margin-left:-3px;cursor:s-resize}.cropper-point.point-ne{top:-3px;right:-3px;cursor:ne-resize}.cropper-point.point-nw{top:-3px;left:-3px;cursor:nw-resize}.cropper-point.point-sw{bottom:-3px;left:-3px;cursor:sw-resize}.cropper-point.point-se{right:-3px;bottom:-3px;width:20px;height:20px;cursor:se-resize;filter:alpha(opacity=100);opacity:1}.cropper-point.point-se:before{position:absolute;right:-50%;bottom:-50%;display:block;width:200%;height:200%;content:" ";background-color:#69f;filter:alpha(opacity=0);opacity:0}@media (min-width:768px){.cropper-point.point-se{width:15px;height:15px}}@media (min-width:992px){.cropper-point.point-se{width:10px;height:10px}}@media (min-width:1200px){.cropper-point.point-se{width:5px;height:5px;filter:alpha(opacity=75);opacity:.75}}.cropper-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)}.cropper-invisible{filter:alpha(opacity=0);opacity:0}.cropper-hide{position:fixed;top:0;left:0;z-index:-1;width:auto!important;min-width:0!important;max-width:none!important;height:auto!important;min-height:0!important;max-height:none!important;filter:alpha(opacity=0);opacity:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed} \ No newline at end of file diff --git a/service/Public/Common/Lib/cropper/cropper.min.js b/service/Public/Common/Lib/cropper/cropper.min.js new file mode 100755 index 000000000..cc227c905 --- /dev/null +++ b/service/Public/Common/Lib/cropper/cropper.min.js @@ -0,0 +1,10 @@ +/*! + * Cropper v0.9.2 + * https://github.com/fengyuanchen/cropper + * + * Copyright (c) 2014-2015 Fengyuan Chen and contributors + * Released under the MIT license + * + * Date: 2015-04-18T04:35:01.500Z + */ +!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){"use strict";function b(a){return"number"==typeof a}function c(a){return"undefined"==typeof a}function d(a,c){var d=[];return b(c)&&d.push(c),d.slice.apply(a,d)}function e(a,b){var c=d(arguments,2);return function(){return a.apply(b,c.concat(d(arguments)))}}function f(a){var b=a.match(/^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i);return b&&(b[1]!==o.protocol||b[2]!==o.hostname||b[3]!==o.port)}function g(a){var b="timestamp="+(new Date).getTime();return a+(-1===a.indexOf("?")?"?":"&")+b}function h(a,b){return b.left<0&&a.width90?180-e:e)*Math.PI/180,g=S(f),h=T(f),i=a.width,j=a.height,k=a.aspectRatio;return b?(c=i/(h+g/k),d=c/k):(c=i*h+j*g,d=i*g+j*h),{width:c,height:d}}function k(b,c){var d=a("")[0],e=d.getContext("2d"),f=c.naturalWidth,g=c.naturalHeight,h=c.rotate,i=j({width:f,height:g,degree:h});return h?(d.width=i.width,d.height=i.height,e.save(),e.translate(i.width/2,i.height/2),e.rotate(h*Math.PI/180),e.drawImage(b,-f/2,-g/2,f,g),e.restore()):(d.width=f,d.height=g,e.drawImage(b,0,0,f,g)),d}function l(b,c){this.$element=a(b),this.options=a.extend({},l.DEFAULTS,a.isPlainObject(c)&&c),this.ready=!1,this.built=!1,this.rotated=!1,this.cropped=!1,this.disabled=!1,this.canvas=null,this.cropBox=null,this.load()}var m=a(window),n=a(document),o=window.location,p=".cropper",q="preview"+p,r=/^(e|n|w|s|ne|nw|sw|se|all|crop|move|zoom)$/,s="cropper-modal",t="cropper-hide",u="cropper-hidden",v="cropper-invisible",w="cropper-move",x="cropper-crop",y="cropper-disabled",z="cropper-bg",A="mousedown touchstart",B="mousemove touchmove",C="mouseup mouseleave touchend touchleave touchcancel",D="wheel mousewheel DOMMouseScroll",E="dblclick",F="resize"+p,G="build"+p,H="built"+p,I="dragstart"+p,J="dragmove"+p,K="dragend"+p,L="zoomin"+p,M="zoomout"+p,N=a.isFunction(a("")[0].getContext),O=Math.sqrt,P=Math.min,Q=Math.max,R=Math.abs,S=Math.sin,T=Math.cos,U=parseFloat,V={};V.load=function(b){var c,d,e,h,i=this.options,j=this.$element;if(!b)if(j.is("img")){if(!j.attr("src"))return;b=j.prop("src")}else j.is("canvas")&&N&&(b=j[0].toDataURL());b&&(e=a.Event(G),j.one(G,i.build).trigger(e),e.isDefaultPrevented()||(i.checkImageOrigin&&f(b)&&(c="anonymous",j.prop("crossOrigin")||(d=g(b))),this.$clone=h=a(""),h.one("load",a.proxy(function(){var a=h.prop("naturalWidth")||h.width(),c=h.prop("naturalHeight")||h.height();this.image={naturalWidth:a,naturalHeight:c,aspectRatio:a/c,rotate:0},this.url=b,this.ready=!0,this.build()},this)).one("error",function(){h.remove()}).attr({src:d||b,crossOrigin:c}),h.addClass(t).insertAfter(j)))},V.build=function(){var b,c,d=this.$element,e=this.$clone,f=this.options;this.ready&&(this.built&&this.unbuild(),this.$cropper=b=a(l.TEMPLATE),d.addClass(u),e.removeClass(t),this.$container=d.parent().append(b),this.$canvas=b.find(".cropper-canvas").append(e),this.$dragBox=b.find(".cropper-drag-box"),this.$cropBox=c=b.find(".cropper-crop-box"),this.$viewBox=b.find(".cropper-view-box"),this.addListeners(),this.initPreview(),f.aspectRatio=U(f.aspectRatio)||0/0,f.autoCrop?(this.cropped=!0,f.modal&&this.$dragBox.addClass(s)):c.addClass(u),f.background&&b.addClass(z),f.highlight||c.find(".cropper-face").addClass(v),f.guides||c.find(".cropper-dashed").addClass(u),f.movable||c.find(".cropper-face").data("drag","move"),f.resizable||c.find(".cropper-line, .cropper-point").addClass(u),this.setDragMode(f.dragCrop?"crop":"move"),this.built=!0,this.render(),d.one(H,f.built).trigger(H))},V.unbuild=function(){this.built&&(this.built=!1,this.container=null,this.canvas=null,this.cropBox=null,this.removeListeners(),this.resetPreview(),this.$preview=null,this.$viewBox=null,this.$cropBox=null,this.$dragBox=null,this.$canvas=null,this.$container=null,this.$cropper.remove(),this.$cropper=null)},a.extend(V,{render:function(){this.initContainer(),this.initCanvas(),this.initCropBox(),this.renderCanvas(),this.cropped&&this.renderCropBox()},initContainer:function(){var a=this.$element,b=this.$container,c=this.$cropper,d=this.options;c.addClass(u),a.removeClass(u),c.css(this.container={width:Q(b.width(),U(d.minContainerWidth)||200),height:Q(b.height(),U(d.minContainerHeight)||100)}),a.addClass(u),c.removeClass(u)},initCanvas:function(){var b=this.container,c=b.width,d=b.height,e=this.image,f=e.aspectRatio,g={aspectRatio:f,width:c,height:d};d*f>c?g.height=c/f:g.width=d*f,g.oldLeft=g.left=(c-g.width)/2,g.oldTop=g.top=(d-g.height)/2,this.canvas=g,this.limitCanvas(!0,!0),this.initialImage=a.extend({},e),this.initialCanvas=a.extend({},g)},limitCanvas:function(b,c){var d,e,f=this.options,g=f.strict,h=this.container,i=h.width,j=h.height,k=this.canvas,l=k.aspectRatio,m=this.cropBox,n=this.cropped&&m;b&&(d=U(f.minCanvasWidth)||0,e=U(f.minCanvasHeight)||0,d?(g&&(d=Q(n?m.width:i,d)),e=d/l):e?(g&&(e=Q(n?m.height:j,e)),d=e*l):g&&(n?(d=m.width,e=m.height,e*l>d?d=e*l:e=d/l):(d=i,e=j,e*l>d?e=d/l:d=e*l)),a.extend(k,{minWidth:d,minHeight:e,maxWidth:1/0,maxHeight:1/0})),c&&(g?n?(k.minLeft=P(m.left,m.left+m.width-k.width),k.minTop=P(m.top,m.top+m.height-k.height),k.maxLeft=m.left,k.maxTop=m.top):(k.minLeft=P(0,i-k.width),k.minTop=P(0,j-k.height),k.maxLeft=Q(0,i-k.width),k.maxTop=Q(0,j-k.height)):(k.minLeft=-k.width,k.minTop=-k.height,k.maxLeft=i,k.maxTop=j))},renderCanvas:function(a){var b,c,d=this.options,e=this.canvas,f=this.image;this.rotated&&(this.rotated=!1,c=j({width:f.width,height:f.height,degree:f.rotate}),b=c.width/c.height,b!==e.aspectRatio&&(e.left-=(c.width-e.width)/2,e.top-=(c.height-e.height)/2,e.width=c.width,e.height=c.height,e.aspectRatio=b,this.limitCanvas(!0,!1))),(e.width>e.maxWidth||e.widthe.maxHeight||e.heightc.width?f.height=f.width/d:f.width=f.height*d),this.cropBox=f,this.limitCropBox(!0,!0),f.width=P(Q(f.width,f.minWidth),f.maxWidth),f.height=P(Q(f.height,f.minHeight),f.maxHeight),f.width=Q(f.minWidth,f.width*e),f.height=Q(f.minHeight,f.height*e),f.oldLeft=f.left=c.left+(c.width-f.width)/2,f.oldTop=f.top=c.top+(c.height-f.height)/2,this.initialCropBox=a.extend({},f)},limitCropBox:function(a,b){var c,d,e=this.options,f=e.strict,g=this.container,h=g.width,i=g.height,j=this.canvas,k=this.cropBox,l=e.aspectRatio;a&&(c=U(e.minCropBoxWidth)||0,d=U(e.minCropBoxHeight)||0,k.minWidth=P(h,c),k.minHeight=P(i,d),k.maxWidth=P(h,f?j.width:h),k.maxHeight=P(i,f?j.height:i),l&&(k.maxHeight*l>k.maxWidth?(k.minHeight=k.minWidth/l,k.maxHeight=k.maxWidth/l):(k.minWidth=k.minHeight*l,k.maxWidth=k.maxHeight*l)),k.minWidth=P(k.maxWidth,k.minWidth),k.minHeight=P(k.maxHeight,k.minHeight)),b&&(f?(k.minLeft=Q(0,j.left),k.minTop=Q(0,j.top),k.maxLeft=P(h,j.left+j.width)-k.width,k.maxTop=P(i,j.top+j.height)-k.height):(k.minLeft=0,k.minTop=0,k.maxLeft=h-k.width,k.maxTop=i-k.height))},renderCropBox:function(){var a=this.options,b=this.container,c=b.width,d=b.height,e=this.$cropBox,f=this.cropBox;(f.width>f.maxWidth||f.widthf.maxHeight||f.height'),this.$preview.each(function(){var c=a(this);c.data(q,{width:c.width(),height:c.height(),original:c.html()}).html('')})},V.resetPreview=function(){this.$preview.each(function(){var b=a(this);b.html(b.data(q).original).removeData(q)})},V.preview=function(){var b=this.image,c=this.canvas,d=this.cropBox,e=b.width,f=b.height,g=d.left-c.left-b.left,h=d.top-c.top-b.top,j=b.rotate;this.cropped&&!this.disabled&&(this.$viewBox.find("img").css({width:e,height:f,marginLeft:-g,marginTop:-h,transform:i(j)}),this.$preview.each(function(){var b=a(this),c=b.data(q),k=c.width/d.width,l=c.width,m=d.height*k;m>c.height&&(k=c.height/d.height,l=d.width*k,m=c.height),b.width(l).height(m).find("img").css({width:e*k,height:f*k,marginLeft:-g*k,marginTop:-h*k,transform:i(j)})}))},V.addListeners=function(){var b=this.options;this.$element.on(I,b.dragstart).on(J,b.dragmove).on(K,b.dragend).on(L,b.zoomin).on(M,b.zoomout),this.$cropper.on(A,a.proxy(this.dragstart,this)).on(E,a.proxy(this.dblclick,this)),b.zoomable&&b.mouseWheelZoom&&this.$cropper.on(D,a.proxy(this.wheel,this)),n.on(B,this._dragmove=e(this.dragmove,this)).on(C,this._dragend=e(this.dragend,this)),b.responsive&&m.on(F,this._resize=e(this.resize,this))},V.removeListeners=function(){var a=this.options;this.$element.off(I,a.dragstart).off(J,a.dragmove).off(K,a.dragend).off(L,a.zoomin).off(M,a.zoomout),this.$cropper.off(A,this.dragstart).off(E,this.dblclick),a.zoomable&&a.mouseWheelZoom&&this.$cropper.off(D,this.wheel),n.off(B,this._dragmove).off(C,this._dragend),a.responsive&&m.off(F,this._resize)},a.extend(V,{resize:function(){var b,c,d,e=this.$container,f=this.container;this.disabled||(d=e.width()/f.width,(1!==d||e.height()!==f.height)&&(b=this.getCanvasData(),c=this.getCropBoxData(),this.render(),this.setCanvasData(a.each(b,function(a,c){b[a]=c*d})),this.setCropBoxData(a.each(c,function(a,b){c[a]=b*d}))))},dblclick:function(){this.disabled||this.setDragMode(this.$dragBox.hasClass(x)?"move":"crop")},wheel:function(a){var b=a.originalEvent,c=1;this.disabled||(a.preventDefault(),b.deltaY?c=b.deltaY>0?1:-1:b.wheelDelta?c=-b.wheelDelta/120:b.detail&&(c=b.detail>0?1:-1),this.zoom(.1*-c))},dragstart:function(b){var c,d,e,f=this.options,g=b.originalEvent,h=g&&g.touches,i=b;if(!this.disabled){if(h){if(e=h.length,e>1){if(!f.zoomable||!f.touchDragZoom||2!==e)return;i=h[1],this.startX2=i.pageX,this.startY2=i.pageY,c="zoom"}i=h[0]}if(c=c||a(i.target).data("drag"),r.test(c)){if(b.preventDefault(),d=a.Event(I,{originalEvent:g,dragType:c}),this.$element.trigger(d),d.isDefaultPrevented())return;this.dragType=c,this.cropping=!1,this.startX=i.pageX,this.startY=i.pageY,"crop"===c&&(this.cropping=!0,this.$dragBox.addClass(s))}}},dragmove:function(b){var c,d,e=this.options,f=b.originalEvent,g=f&&f.touches,h=b,i=this.dragType;if(!this.disabled){if(g){if(d=g.length,d>1){if(!e.zoomable||!e.touchDragZoom||2!==d)return;h=g[1],this.endX2=h.pageX,this.endY2=h.pageY}h=g[0]}if(i){if(b.preventDefault(),c=a.Event(J,{originalEvent:f,dragType:i}),this.$element.trigger(c),c.isDefaultPrevented())return;this.endX=h.pageX,this.endY=h.pageY,this.change()}}},dragend:function(b){var c,d=this.dragType;if(!this.disabled&&d){if(b.preventDefault(),c=a.Event(K,{originalEvent:b.originalEvent,dragType:d}),this.$element.trigger(c),c.isDefaultPrevented())return;this.cropping&&(this.cropping=!1,this.$dragBox.toggleClass(s,this.cropped&&this.options.modal)),this.dragType=""}}}),a.extend(V,{reset:function(){this.built&&!this.disabled&&(this.image=a.extend({},this.initialImage),this.canvas=a.extend({},this.initialCanvas),this.renderCanvas(),this.cropped&&(this.cropBox=a.extend({},this.initialCropBox),this.renderCropBox()))},clear:function(){this.cropped&&!this.disabled&&(a.extend(this.cropBox,{left:0,top:0,width:0,height:0}),this.cropped=!1,this.renderCropBox(),this.limitCanvas(),this.renderCanvas(),this.$dragBox.removeClass(s),this.$cropBox.addClass(u))},destroy:function(){var a=this.$element;this.ready?(this.unbuild(),a.removeClass(u)):this.$clone.off("load").remove(),a.removeData("cropper")},replace:function(a){!this.disabled&&a&&this.load(a)},enable:function(){this.built&&(this.disabled=!1,this.$cropper.removeClass(y))},disable:function(){this.built&&(this.disabled=!0,this.$cropper.addClass(y))},move:function(a,c){var d=this.canvas;this.built&&!this.disabled&&b(a)&&b(c)&&(d.left+=a,d.top+=c,this.renderCanvas(!0))},zoom:function(b){var c,d,e,f=this.canvas;if(b=U(b),b&&this.built&&!this.disabled&&this.options.zoomable){if(c=a.Event(b>0?L:M),this.$element.trigger(c),c.isDefaultPrevented())return;b=-1>=b?1/(1-b):1>=b?1+b:b,d=f.width*b,e=f.height*b,f.left-=(d-f.width)/2,f.top-=(e-f.height)/2,f.width=d,f.height=e,this.renderCanvas(!0),this.setDragMode("move")}},rotate:function(a){var b=this.image;a=U(a),a&&this.built&&!this.disabled&&this.options.rotatable&&(b.rotate=(b.rotate+a)%360,this.rotated=!0,this.renderCanvas(!0))},getData:function(){var b,c,d=this.cropBox,e=this.canvas,f=this.image;return this.built&&this.cropped?(c={x:d.left-e.left,y:d.top-e.top,width:d.width,height:d.height},b=f.width/f.naturalWidth,a.each(c,function(a,d){d/=b,c[a]=d})):c={x:0,y:0,width:0,height:0},c.rotate=f.rotate,c},getContainerData:function(){return this.built?this.container:{}},getImageData:function(){return this.ready?this.image:{}},getCanvasData:function(){var a,b=this.canvas;return this.built&&(a={left:b.left,top:b.top,width:b.width,height:b.height}),a||{}},setCanvasData:function(c){var d=this.canvas,e=d.aspectRatio;this.built&&!this.disabled&&a.isPlainObject(c)&&(b(c.left)&&(d.left=c.left),b(c.top)&&(d.top=c.top),b(c.width)?(d.width=c.width,d.height=c.width/e):b(c.height)&&(d.height=c.height,d.width=c.height*e),this.renderCanvas(!0))},getCropBoxData:function(){var a,b=this.cropBox;return this.built&&this.cropped&&(a={left:b.left,top:b.top,width:b.width,height:b.height}),a||{}},setCropBoxData:function(c){var d=this.cropBox,e=this.options.aspectRatio;this.built&&this.cropped&&!this.disabled&&a.isPlainObject(c)&&(b(c.left)&&(d.left=c.left),b(c.top)&&(d.top=c.top),e?b(c.width)?(d.width=c.width,d.height=d.width/e):b(c.height)&&(d.height=c.height,d.width=d.height*e):(b(c.width)&&(d.width=c.width),b(c.height)&&(d.height=c.height)),this.renderCropBox())},getCroppedCanvas:function(b){var c,d,e,f,g,h,i,j,l,m,n;if(this.built&&this.cropped&&N)return a.isPlainObject(b)||(b={}),n=this.getData(),c=n.width,d=n.height,j=c/d,a.isPlainObject(b)&&(g=b.width,h=b.height,g?(h=g/j,i=g/c):h&&(g=h*j,i=h/d)),e=g||c,f=h||d,l=a("")[0],l.width=e,l.height=f,m=l.getContext("2d"),b.fillColor&&(m.fillStyle=b.fillColor,m.fillRect(0,0,e,f)),m.drawImage.apply(m,function(){var a,b,e,f,g,h,j=k(this.$clone[0],this.image),l=j.width,m=j.height,o=[j],p=n.x,q=n.y;return-c>=p||p>l?p=a=e=g=0:0>=p?(e=-p,p=0,a=g=P(l,c+p)):l>=p&&(e=0,a=g=P(c,l-p)),0>=a||-d>=q||q>m?q=b=f=h=0:0>=q?(f=-q,q=0,b=h=P(m,d+q)):m>=q&&(f=0,b=h=P(d,m-q)),o.push(p,q,a,b),i&&(e*=i,f*=i,g*=i,h*=i),g>0&&h>0&&o.push(e,f,g,h),o}.call(this)),l},setAspectRatio:function(a){var b=this.options;this.disabled||c(a)||(b.aspectRatio=U(a)||0/0,this.built&&(this.initCropBox(),this.cropped&&this.renderCropBox()))},setDragMode:function(a){var b=this.$dragBox,c=!1,d=!1;if(this.ready&&!this.disabled){switch(a){case"crop":this.options.dragCrop?(c=!0,b.data("drag",a)):d=!0;break;case"move":d=!0,b.data("drag",a);break;default:b.removeData("drag")}b.toggleClass(x,c).toggleClass(w,d)}}}),V.change=function(){var a,b=this.dragType,c=this.options,d=this.canvas,e=this.container,f=this.cropBox,g=f.width,h=f.height,i=f.left,j=f.top,k=i+g,l=j+h,m=0,n=0,o=e.width,p=e.height,q=!0,r=c.aspectRatio,s={x:this.endX-this.startX,y:this.endY-this.startY};switch(c.strict&&(m=f.minLeft,n=f.minTop,o=m+P(e.width,d.width),p=n+P(e.height,d.height)),r&&(s.X=s.y*r,s.Y=s.x/r),b){case"all":i+=s.x,j+=s.y;break;case"e":if(s.x>=0&&(k>=o||r&&(n>=j||l>=p))){q=!1;break}g+=s.x,r&&(h=g/r,j-=s.Y/2),0>g&&(b="w",g=0);break;case"n":if(s.y<=0&&(n>=j||r&&(m>=i||k>=o))){q=!1;break}h-=s.y,j+=s.y,r&&(g=h*r,i+=s.X/2),0>h&&(b="s",h=0);break;case"w":if(s.x<=0&&(m>=i||r&&(n>=j||l>=p))){q=!1;break}g-=s.x,i+=s.x,r&&(h=g/r,j+=s.Y/2),0>g&&(b="e",g=0);break;case"s":if(s.y>=0&&(l>=p||r&&(m>=i||k>=o))){q=!1;break}h+=s.y,r&&(g=h*r,i-=s.X/2),0>h&&(b="n",h=0);break;case"ne":if(r){if(s.y<=0&&(n>=j||k>=o)){q=!1;break}h-=s.y,j+=s.y,g=h*r}else s.x>=0?o>k?g+=s.x:s.y<=0&&n>=j&&(q=!1):g+=s.x,s.y<=0?j>0&&(h-=s.y,j+=s.y):(h-=s.y,j+=s.y);0>g&&0>h?(b="sw",h=0,g=0):0>g?(b="nw",g=0):0>h&&(b="se",h=0);break;case"nw":if(r){if(s.y<=0&&(n>=j||m>=i)){q=!1;break}h-=s.y,j+=s.y,g=h*r,i+=s.X}else s.x<=0?i>0?(g-=s.x,i+=s.x):s.y<=0&&n>=j&&(q=!1):(g-=s.x,i+=s.x),s.y<=0?j>0&&(h-=s.y,j+=s.y):(h-=s.y,j+=s.y);0>g&&0>h?(b="se",h=0,g=0):0>g?(b="ne",g=0):0>h&&(b="sw",h=0);break;case"sw":if(r){if(s.x<=0&&(m>=i||l>=p)){q=!1;break}g-=s.x,i+=s.x,h=g/r}else s.x<=0?i>0?(g-=s.x,i+=s.x):s.y>=0&&l>=p&&(q=!1):(g-=s.x,i+=s.x),s.y>=0?p>l&&(h+=s.y):h+=s.y;0>g&&0>h?(b="ne",h=0,g=0):0>g?(b="se",g=0):0>h&&(b="nw",h=0);break;case"se":if(r){if(s.x>=0&&(k>=o||l>=p)){q=!1;break}g+=s.x,h=g/r}else s.x>=0?o>k?g+=s.x:s.y>=0&&l>=p&&(q=!1):g+=s.x,s.y>=0?p>l&&(h+=s.y):h+=s.y;0>g&&0>h?(b="nw",h=0,g=0):0>g?(b="sw",g=0):0>h&&(b="ne",h=0);break;case"move":d.left+=s.x,d.top+=s.y,this.renderCanvas(!0),q=!1;break;case"zoom":this.zoom(function(a,b,c,d){var e=O(a*a+b*b),f=O(c*c+d*d);return(f-e)/e}(R(this.startX-this.startX2),R(this.startY-this.startY2),R(this.endX-this.endX2),R(this.endY-this.endY2))),this.startX2=this.endX2,this.startY2=this.endY2,q=!1;break;case"crop":s.x&&s.y&&(a=this.$cropper.offset(),i=this.startX-a.left,j=this.startY-a.top,g=f.minWidth,h=f.minHeight,s.x>0?s.y>0?b="se":(b="ne",j-=h):s.y>0?(b="sw",i-=g):(b="nw",i-=g,j-=h),this.cropped||(this.cropped=!0,this.$cropBox.removeClass(u)))}q&&(f.width=g,f.height=h,f.left=i,f.top=j,this.dragType=b,this.renderCropBox()),this.startX=this.endX,this.startY=this.endY},a.extend(l.prototype,V),l.DEFAULTS={aspectRatio:0/0,autoCropArea:.8,crop:null,preview:"",strict:!0,responsive:!0,checkImageOrigin:!0,modal:!0,guides:!0,highlight:!0,background:!0,autoCrop:!0,dragCrop:!0,movable:!0,resizable:!0,rotatable:!0,zoomable:!0,touchDragZoom:!0,mouseWheelZoom:!0,minCanvasWidth:0,minCanvasHeight:0,minCropBoxWidth:0,minCropBoxHeight:0,minContainerWidth:200,minContainerHeight:100,build:null,built:null,dragstart:null,dragmove:null,dragend:null,zoomin:null,zoomout:null},l.setDefaults=function(b){a.extend(l.DEFAULTS,b)},l.TEMPLATE=function(a,b){return b=b.split(","),a.replace(/\d+/g,function(a){return b[a]})}('<0 6="5-container"><0 6="5-canvas"><0 6="5-2-9" 3-2="move"><0 6="5-crop-9"><1 6="5-view-9"><1 6="5-8 8-h"><1 6="5-8 8-v"><1 6="5-face" 3-2="all"><1 6="5-7 7-e" 3-2="e"><1 6="5-7 7-n" 3-2="n"><1 6="5-7 7-w" 3-2="w"><1 6="5-7 7-s" 3-2="s"><1 6="5-4 4-e" 3-2="e"><1 6="5-4 4-n" 3-2="n"><1 6="5-4 4-w" 3-2="w"><1 6="5-4 4-s" 3-2="s"><1 6="5-4 4-ne" 3-2="ne"><1 6="5-4 4-nw" 3-2="nw"><1 6="5-4 4-sw" 3-2="sw"><1 6="5-4 4-se" 3-2="se">',"div,span,drag,data,point,cropper,class,line,dashed,box"),l.other=a.fn.cropper,a.fn.cropper=function(b){var e,f=d(arguments,1);return this.each(function(){var c,d=a(this),g=d.data("cropper");g||d.data("cropper",g=new l(this,b)),"string"==typeof b&&a.isFunction(c=g[b])&&(e=c.apply(g,f))}),c(e)?this:e},a.fn.cropper.Constructor=l,a.fn.cropper.setDefaults=l.setDefaults,a.fn.cropper.noConflict=function(){return a.fn.cropper=l.other,this}}); \ No newline at end of file diff --git a/service/Public/Home/Default/Css/Common.css b/service/Public/Home/Default/Css/Common.css index 102f8f725..e4858938c 100755 --- a/service/Public/Home/Default/Css/Common.css +++ b/service/Public/Home/Default/Css/Common.css @@ -688,4 +688,29 @@ background:url(../Images/ibar_sprites.png) no-repeat;background-position:0px -23 .user-main { padding-top: 10px; } .more-icon-rotate {-webkit-transform: rotate(-90deg);transform: rotate(-90deg);-webkit-transition: all 300ms;transition: all 300ms;} -button { outline: none !important;} \ No newline at end of file +button { outline: none !important;} + + + + +/** + * 公共头像样式 + */ +.common-cropper-popup .cropper-images-view, +.common-cropper-popup .img-preview, +.common-cropper-popup .submit-operation { overflow:hidden; } +.common-cropper-popup .img-container { width:200px; height:200px; margin-bottom:5px; } +.common-cropper-popup .cropper-input-images-submit { width:104px; margin:0px 5px 0px 2px; height: 32px; } +.common-cropper-popup .preview-lg { width:180px; height:180px; } +.common-cropper-popup .preview-md { width:100px; height:100px; } +.common-cropper-popup .preview-sm { width:50px; height:50px; } +.common-cropper-popup .img-preview { margin-left:20px; border: 1px solid #eee; background-color: #f9f9f9; } +.common-cropper-popup .cropper-container, .cropper-input-images-submit { border-radius:2px; } +.common-cropper-popup .am-form-file input[type="file"] { margin-top: 0; } +@media only screen and (max-width:641px){ + .common-cropper-popup .img-preview { margin-left:10px; } + .common-cropper-popup .preview-md, + .common-cropper-popup .preview-sm { margin:0 0 5px 8px; } + .common-cropper-popup .preview-md { width:90px; height:90px; } + .common-cropper-popup .preview-sm { width:50px; height:50px; } +} \ No newline at end of file diff --git a/service/Public/Home/Default/Css/User.Index.css b/service/Public/Home/Default/Css/User.Index.css index ac5fc1abc..f92d767eb 100644 --- a/service/Public/Home/Default/Css/User.Index.css +++ b/service/Public/Home/Default/Css/User.Index.css @@ -63,7 +63,7 @@ ul.user-base-icon { vertical-align: bottom; } .order-nav .nav-name i.order-icon { - background-image: url(../images/user-index-nav-order-icon.png); + background-image: url(../Images/user-index-nav-order-icon.png); } .order-nav .icon-tips, .order-base a { color: #888; diff --git a/service/Public/Home/Default/Images/default-user-avatar-s.jpg b/service/Public/Home/Default/Images/default-user-avatar-s.jpg new file mode 100755 index 000000000..fce14d5f9 Binary files /dev/null and b/service/Public/Home/Default/Images/default-user-avatar-s.jpg differ diff --git a/service/Public/Home/Default/Images/default-user-avatar.jpg b/service/Public/Home/Default/Images/default-user-avatar.jpg old mode 100755 new mode 100644 index fce14d5f9..e9160f113 Binary files a/service/Public/Home/Default/Images/default-user-avatar.jpg and b/service/Public/Home/Default/Images/default-user-avatar.jpg differ diff --git a/service/Public/Home/Default/Js/Common.js b/service/Public/Home/Default/Js/Common.js index 937c71761..04eb9960c 100755 --- a/service/Public/Home/Default/Js/Common.js +++ b/service/Public/Home/Default/Js/Common.js @@ -150,5 +150,139 @@ $(function() store.set(store_user_menu_key, value); } }); + + + + + var $image = $('.user-head-img-container > img'), + $dataX = $('#user-head-img_x'), + $dataY = $('#user-head-img_y'), + $dataHeight = $('#user-head-img_height'), + $dataWidth = $('#user-head-img_width'), + $dataRotate = $('#user-head-img_rotate'), + options = { + // strict: false, + // responsive: false, + // checkImageOrigin: false + + // modal: false, + // guides: false, + // highlight: false, + // background: false, + + // autoCrop: false, + // autoCropArea: 0.5, + // dragCrop: false, + // movable: false, + // resizable: false, + // rotatable: false, + // zoomable: false, + // touchDragZoom: false, + // mouseWheelZoom: false, + + // minCanvasWidth: 320, + // minCanvasHeight: 180, + // minCropBoxWidth: 160, + // minCropBoxHeight: 90, + // minContainerWidth: 320, + // minContainerHeight: 180, + + // build: null, + // built: null, + // dragstart: null, + // dragmove: null, + // dragend: null, + // zoomin: null, + // zoomout: null, + + aspectRatio: 1 / 1, + preview: '.user-head-img-preview', + crop: function (data) { + $dataX.val(Math.round(data.x)); + $dataY.val(Math.round(data.y)); + $dataHeight.val(Math.round(data.height)); + $dataWidth.val(Math.round(data.width)); + $dataRotate.val(Math.round(data.rotate)); + } + }; + $image.on({}).cropper(options); + + // Methods + $(document.body).on('click', '[data-method]', function () { + var data = $(this).data(), + $target, + result; + if (data.method) { + data = $.extend({}, data); // Clone a new one + if (typeof data.target !== 'undefined') { + $target = $(data.target); + + if (typeof data.option === 'undefined') { + try { + data.option = JSON.parse($target.val()); + } catch (e) { + console.log(e.message); + } + } + } + + result = $image.cropper(data.method, data.option); + + if (data.method === 'getCroppedCanvas') { + $('#getCroppedCanvasModal').modal().find('.modal-body').html(result); + } + + if ($.isPlainObject(result) && $target) { + try { + $target.val(JSON.stringify(result)); + } catch (e) { + console.log(e.message); + } + } + + } + }).on('keydown', function (e) {}); + + + // 头像图片上传 + var $inputimage = $('.common-cropper-popup input[type="file"]'), + URL = window.URL || window.webkitURL, + blobURL; + + if (URL) { + $inputimage.change(function () { + var files = this.files, + file; + + if (files && files.length) { + file = files[0]; + + if (/^image\/\w+$/.test(file.type)) { + blobURL = URL.createObjectURL(file); + $image.one('built.cropper', function () { + URL.revokeObjectURL(blobURL); // Revoke when load complete + }).cropper('reset', true).cropper('replace', blobURL); + //$inputimage.val(''); + } else { + Prompt('Please choose an image file.'); + } + } + }); + } else { + $inputimage.parent().remove(); + } + + // 图片裁剪提交确认 + $('.common-cropper-popup button[type="submit"]').on('click', function() + { + var v = $inputimage.val(); + if(v.length == 0) + { + $(this).parents('.common-cropper-popup').find('.from-text-tips').removeClass('none'); + Prompt('请上传图片'); + return false; + } + }); + }); \ No newline at end of file