/** * 图片裁剪 * @author yanglizhe * 2015/11/16 */ (function($){ /** * Drag */ var Drag={obj:null,init:function(elementHeader,element){elementHeader.onmousedown=Drag.start;elementHeader.obj=element;if(isNaN(parseInt(element.style.left))){element.style.left="0px"}if(isNaN(parseInt(element.style.top))){element.style.top="0px"}element.onDragStart=new Function();element.onDragEnd=new Function();element.onDrag=new Function()},start:function(event){var element=Drag.obj=this.obj;event=Drag.fixE(event);if(event.which!=1){return true}element.onDragStart();element.lastMouseX=event.clientX;element.lastMouseY=event.clientY;document.onmouseup=Drag.end;document.onmousemove=Drag.drag;return false},drag:function(event){event=Drag.fixE(event);if(event.which==0){return Drag.end()}var element=Drag.obj;var _clientX=event.clientY;var _clientY=event.clientX;if(element.lastMouseX==_clientY&&element.lastMouseY==_clientX){return false}var _lastX=parseInt(element.style.top);var _lastY=parseInt(element.style.left);var newX,newY;newX=_lastY+_clientY-element.lastMouseX;newY=_lastX+_clientX-element.lastMouseY;element.style.left=newX+"px";element.style.top=newY+"px";element.lastMouseX=_clientY;element.lastMouseY=_clientX;element.onDrag(newX,newY);return false},end:function(event){event=Drag.fixE(event);document.onmousemove=null;document.onmouseup=null;var _onDragEndFuc=Drag.obj.onDragEnd();Drag.obj=null;return _onDragEndFuc},fixE:function(ig_){if(typeof ig_=="undefined"){ig_=window.event}if(typeof ig_.layerX=="undefined"){ig_.layerX=ig_.offsetX}if(typeof ig_.layerY=="undefined"){ig_.layerY=ig_.offsetY}if(typeof ig_.which=="undefined"){ig_.which=ig_.button}return ig_}}; /** * 创建样式表 * @param String cssStr */ function createStyle(cssStr){ if( document.createStyleSheet){ var style = document.createStyleSheet(); style.cssText = cssStr; } else{ var style = document.createElement("style"); style.type = "text/css"; style.textContent = cssStr; document.getElementsByTagName("head").item(0).appendChild(style); } } var MAX_SIZE = 200; function ImageCrop(config){ this.zoomMin = 0.1; //最小比例 this.zoomMax = 10; //最大比例 this.wrapWidth = 280; this.wrapHeight = 260; this.gripMinX = 0; this.gripMaxX = 189; this.originalWidth = 0; this.originalHeight = 0; this.originalLeft = 0; this.origianlTop = 0; this._construct(config); } ImageCrop.prototype = { /** * 构建方法 * @param config * @private */ _construct:function(config){ this.eventTarget = config.target; this.cropWidth = config.width || 140; this.cropHeight = config.height || 140; this.ratio = 1; if(this.cropWidth > MAX_SIZE || this.cropHeight > MAX_SIZE){ if(this.cropWidth > this.cropHeight){ this.ratio = MAX_SIZE/this.cropWidth; this.cropWidth = MAX_SIZE; this.cropHeight *= this.ratio; } else{ this.ratio = MAX_SIZE / this.cropHeight; this.cropHeight = MAX_SIZE; this.cropWidth *= this.ratio; } } this.offsetX = (this.wrapWidth - this.cropWidth ) / 2; this.offsetY = (this.wrapHeight - this.cropHeight) / 2; this.destWidth = config.destWidth || this.cropWidth; this.destHeight = config.destHeight || this.cropHeight; this.onConfirm = config.onConfirm || function(){}; var parent = config.container || $(document.body); this.initHTML(parent); this.bindEvent(); }, initHTML:function(parent){ var html = ‘<div class="crop-container" style="display:block;">‘+ ‘ <div class="left-box">‘+ ‘ <div class="crop-wrapper">‘+ ‘ <div class="crop-preview"><div class="crop-preview-box"></div></div>‘+ ‘ <img class="crop-target" style="position:relative;" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />‘+ ‘ </div>‘+ ‘ <div class="crop-tool-bar">‘+ ‘ <span><a href="javascript:;" class="zoom-tool btn-zoom zoom-out" alt="图片缩小"></a></span>‘+ ‘ <span class="bar-zoom-box">‘+ ‘ <span class="zoom-tool bar-zoom"></span>‘+ ‘ <a href="javascript:;" class= "zoom-tool crop-grip"></a>‘+ ‘ </span>‘+ ‘ <span><a href="javascript:;" class="zoom-tool btn-zoom zoom-in" alt="图片放大"></a></span>‘+ ‘ </div>‘+ ‘ </div>‘+ ‘ <div class="right-box">‘+ ‘ <div class="image-preview"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" /></div>‘+ ‘ <div class="btn-box"><a class="btn-upload-image" href="javascript:;">图片上传</a></div>‘+ ‘ <div class="btn-box"><a class="btn-confirm-crop" href="javascript:;">确认裁剪</a></div>‘+ ‘ </div>‘+ ‘</div>‘; this.container = $(html); this.find(".crop-preview").css({ width : (this.cropWidth + 4) +"px", height: (this.cropHeight + 4) + "px", "border-width": (this.offsetY -2) +"px " + (this.offsetX - 2) +"px" }); this.find(".crop-preview-box").css({ width : (this.cropWidth) +"px", height: (this.cropHeight) + "px" }); parent.append(this.container); }, bindEvent:function(){ this.cropTarget = this.find(".crop-target"); this.cropGrip = this.find(".crop-grip"); this.wrapper = this.find(".crop-wrapper"); var _this = this; this.eventTarget.bind("click", function(){ _this.show(); }); this.bindCropGrip(); this.bindUpload(); this.find(".btn-zoom").bind("click", function(){ if($(this).hasClass("zoom-out")){ _this.scale(false); } else if($(this).hasClass("zoom-in")){ _this.scale(true); } }); var canvas = document.createElement("canvas"); canvas.width = this.destWidth; canvas.height = this.destHeight; var context = canvas.getContext("2d"); this.find(".btn-confirm-crop").bind("click", function(){ var target = _this.cropTarget.get(0); var top = parseInt(target.style.top); var left = parseInt(target.style.left); var offsetLeft = left - _this.originalLeft; var offsetTop = top - _this.origianlTop; var scale = _this.zoom; var _left = (_this.zoom * _this.originalWidth - _this.cropWidth) / 2; var _top = (_this.zoom * _this.originalHeight - _this.cropHeight) / 2; var x = (-_left + offsetLeft) / scale; var y = (-_top + offsetTop) /scale; context.clearRect(0, 0, canvas.width, canvas.height); context.save(); context.scale(scale, scale); context.drawImage(_this.cropTarget.get(0), x, y); context.restore(); var base64Url = canvas.toDataURL("image/png"); _this.find(".image-preview").find("img").attr("src", base64Url); _this.onConfirm(base64Url) }); }, bindUpload:function(){ var _this = this; this.fileInput = $(‘<input type="file" accept="image/*" style="position: absolute;left: -999999px;" />‘); this.fileInput.bind("change", function(e){ if($.trim($(this).val())==""){ return ; } var files = e.target.files || e.dataTransfer.files; var file = files[0]; if(!/^image\//.test(file.type)){ alert("请上传图片文件"); _this.fileInput.val(""); return false; } //对路径进行压缩 var reader = new FileReader(); reader.onload = function(e) { var image = new Image(); image.onload = function(){ _this.cropTarget.attr("src", this.src); _this.initImage(this.width, this.height); }; image.src = e.target.result; } reader.readAsDataURL(file); }); var _this = this; this.find(".btn-upload-image").bind("click", function(){ _this.fileInput.trigger("click"); }); }, initImage:function(width, height){ var _this = this; var top = -(height - this.wrapHeight) / 2; var left = -(width - this.wrapWidth) / 2; this.originalLeft = left; this.origianlTop = top; this.originalWidth = width; this.originalHeight = height; this.cropTarget.get(0).style.transform = ""; this.cropTarget.css({ top:top, left:left }); this.zoomMin = 1; this.gripPos = 5; this.zoom = 1; if (width > this.cropWidth) { this.zoomMin = this.cropWidth / width; } this.zoomMax = this.zoomMin > 0.25 ? 8.0 : 4.0 / Math.sqrt(this.zoomMin); this.cropGrip.css({ "left":(this.gripMinX + (this.gripPos / 10 * (this.gripMaxX - this.gripMinX))) + "px" }); var target = this.cropTarget.get(0); Drag.init(this.wrapper.get(0), target); target.onDrag = function(){ _this.rePosition(); }; }, rePosition:function(){ var target = this.cropTarget.get(0); var width = this.originalWidth; var height = this.originalHeight; var offsetLeft = parseInt(this.cropTarget.css("left")); var offsetTop = parseInt(this.cropTarget.css("top")); var _width = width * this.zoom; var _height = height * this.zoom; var _x = (_width - width ) / 2; var _y = (_height - height) / 2; var maxX = Math.max(this.offsetX, this.offsetX + this.cropWidth - _width) + _x; var minX = Math.min(this.offsetX + this.cropWidth - _width, this.offsetX) + _x; if (offsetLeft > maxX) target.style.left = maxX + ‘px‘; else if (offsetLeft < minX) target.style.left = minX + ‘px‘; var maxY = Math.max(this.offsetY, this.offsetY + this.cropHeight - _height) + _y; var minY = Math.min(this.offsetY + this.cropHeight - _height, this.offsetY) + _y; if (offsetTop > maxY) target.style.top = maxY + ‘px‘; else if (offsetTop < minY) target.style.top = minY + ‘px‘; }, scale:function(flag){ if (flag) { this.zoom = this.zoom * 1.5; } else { this.zoom = this.zoom / 1.5; } if (this.zoom < this.zoomMin) this.zoom = this.zoomMin; if (this.zoom > this.zoomMax) this.zoom = this.zoomMax; this.imageResize(this.zoom); this.gripPos = 5 * (Math.log(this.zoom * this.zoomMax) / Math.log(this.zoomMax)); this.cropGrip.css({ left:(this.gripMinX + (this.gripPos / 10 * (this.gripMaxX - this.gripMinX))) + "px" }); this.rePosition(); }, bindCropGrip:function(){ var _this = this; var cropGrip = this.cropGrip.get(0); Drag.init(cropGrip, cropGrip); cropGrip.onDrag = function (clientX, clientY) { var offsetX = clientX; if (clientX < _this.gripMinX) { cropGrip.style.left = _this.gripMinX + "px"; offsetX = _this.gripMinX; } if (clientX > _this.gripMaxX) { cropGrip.style.left = _this.gripMaxX + "px"; offsetX = _this.gripMaxX; } cropGrip.style.top = 0; var x = (offsetX - _this.gripMinX) * 10 / (_this.gripMaxX - _this.gripMinX); var zoom = Math.pow(_this.zoomMax, x / 5) / _this.zoomMax; if (zoom < _this.zoomMin) zoom = _this.zoomMin; if (zoom > _this.zoomMax) zoom = _this.zoomMax; _this.imageResize(zoom); _this.rePosition(); } }, imageResize:function(zoom){ this.zoom = zoom; this.cropTarget.get(0).style.transform = "scale("+zoom+")"; }, show:function(){ this.container.show(); }, hide:function(){ this.container.hide(); }, find:function(selector){ return $(selector, this.container); } }; $.fn.imageCrop = function(config){ return this.each(function(){ new ImageCrop($.extend({ target:$(this) },config||{})); }); }; createStyle(‘.crop-container{width:480px;height:300px;overflow:hidden;margin:10px auto;border:1px solid #e0e0e0;border-radius:5px;padding:10px}.zoom-tool{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAASCAYAAAGWfdOKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjIzMDY1QUQ4QzEzMTFFNUJGQTk5MTg5Q0Q5RjA1NjkiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjIzMDY1QUU4QzEzMTFFNUJGQTk5MTg5Q0Q5RjA1NjkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MjMwNjVBQjhDMTMxMUU1QkZBOTkxODlDRDlGMDU2OSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2MjMwNjVBQzhDMTMxMUU1QkZBOTkxODlDRDlGMDU2OSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PiaUw1sAAAjASURBVHjaYvwPBAy0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);background-repeat:no-repeat}.left-box{float:left;height:320px;width:292px;overflow:hidden}.crop-wrapper{border:2px solid #888;width:280px;height:260px;overflow:hidden;position:relative;margin:4px;cursor:pointer;float:left}.crop-preview{width:144px;height:144px;border-color:#ccc;border-style:solid;border-width:58px 68px;position:absolute;z-index:1;opacity:.75}.crop-preview-box{width:140px;height:140px;border:2px solid #e0e0e0}.crop-tool-bar{width:252px;padding:4px 20px;height:20px;position:relative;overflow:hidden}.bar-zoom-box{position:relative;width:200px;display:inline-block}.crop-grip{position:absolute;z-index:100;left:100%;top:0;cursor:pointer;width:11px;height:18px;display:inline-block;background-position:-287px 0}.right-box{float:right;width:144px;padding:8px;height:280px}.right-box .image-preview{height:166px;width:144px;margin:8px auto;overflow:hidden;text-align:center;}.image-preview img{border:2px #eee solid;max-height:100%;max-width:140px;}.right-box .btn-box{height:50px;text-align:center}.right-box .btn-box a{display:inline-block;width:100px;padding:8px;text-align:center;border-radius:8px;text-decoration:none;border:1px solid #efefef;color:#FFF;font-size:14px;background:#80b6e7}.right-box .btn-box a:hover{background:#5498db}.btn-zoom{width:18px;height:18px;display:inline-block}.bar-zoom{width:200px;height:18px;display:inline-block}.zoom-out{background-position:-224px 0}.zoom-out:hover{background-position:-203px 0}.zoom-in{background-position:-266px 0}.zoom-in:hover{background-position:-245px 0}‘); })(jQuery);
时间: 2024-10-05 04:24:52