cutterjs
Version:
javascript cutterjs cropperjs image tool
8 lines (6 loc) • 12.4 kB
JavaScript
/**
* CropperJS v1.0.1 Copyright (c) Sat Aug 01 2020 12:39:15 GMT+0800 (中国标准时间), JIANGXUEYANG All Rights Reserved,
* see: for Details
* @license MIT
*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Cutter=e()}(this,function(){"use strict";function n(t,e){for(var i=0;i<e.length;i++){var o=e[i];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}function e(e,t){var i,o=Object.keys(e);return Object.getOwnPropertySymbols&&(i=Object.getOwnPropertySymbols(e),t&&(i=i.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,i)),o}function x(n){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?e(Object(r),!0).forEach(function(t){var e,i,o;e=n,o=r[i=t],i in e?Object.defineProperty(e,i,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[i]=o}):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(r)):e(Object(r)).forEach(function(t){Object.defineProperty(n,t,Object.getOwnPropertyDescriptor(r,t))})}return n}function w(t){return Object.prototype.toString.call(t).toLowerCase().slice(8,-1)}function M(t){return"function"===w(t)}function H(t){return null===t||""===t||void 0===t}function z(t){return"number"===w(t)||/^\d+$/.test(t)}function W(t){return console.error(t),!1}function T(t,e){var i=1<arguments.length&&void 0!==e?e:2;return Number(t.toFixed(i))}return function(){function e(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),this.rotate=0,this.dragStatus=0,this.cursorEnums=["default","nw-resize","w-resize","sw-resize","n-resize","s-resize","ne-resize","e-resize","se-resize","move"],this.cutterIsEnter=!1,this.ropperIsDown=!1,this.startPos=null,this.defaultConfig={cutWidth:200,cutHeight:200,minCutWidth:16,minCutHeight:16,maxScaleRatio:3,maxZoomRatio:.1,ratio:1.2,scalable:!1,zoomable:!1,rotatable:!1,cutBoxResizable:!1,imageSrc:"",outputType:"png",containerEl:"",scaleEl:"",zoomEl:"",cutEl:"",rotateEl:"",onRender:null,onCut:null,onScale:null,onZoom:null},this.checkConfig(t)&&this.init()}var t,i,o;return t=e,(i=[{key:"checkConfig",value:function(e){if(H(e))return!1;if("object"!==w(e))return W("配置信息格式不合法");["cutWidth","cutHeight","minCutWidth","minCutHeight","maxScaleRatio","maxZoomRatio","ratio"].forEach(function(t){e.hasOwnProperty(t)&&(e[t]=parseFloat(e[t]))});var t=(e=x(x({},this.defaultConfig),e)).containerEl,i=e.minCutWidth,o=e.minCutHeight,n=e.cutWidth,r=e.cutHeight,s=e.maxScaleRatio,a=e.maxZoomRatio,u=e.zoomable,h=e.scalable;if(H(t))return W("containerEl未配置");var c=document.querySelector(t);if(!c)return W(t+"的dom元素不存在");if(this.container=c,e.cutBoxResizable){if(!H(o)){if(!z(o))return W("minCutHeight必须为数值");if(Number(o)<1)return W("minCutHeight不能小于1")}if(!H(i)){if(!z(i))return W("minCutWidth必须为数值");if(Number(i)<1)return W("minCutWidth不能小于1")}}if(!H(n)){if(!z(n))return W("cutWidtht必须为数值");if(Number(n)<1)return W("cutWidth不能小于1")}if(!H(r)){if(!z(r))return W("cutHeight必须为数值");if(Number(r)<1)return W("cutHeight不能小于1")}if(h){if(!H(s)){if(!z(s))return W("maxScaleRatio必须为数值");if(Number(s)<1)return W("maxScaleRatio不能小于1")}var l=e.scaleEl;if(H(l))return W("scaleEl未配置");var f=document.querySelector(l);if(!f)return W(l+"的dom元素不存在");this.scaleNode=f}if(u){if(!H(a)){if(!z(a))return W("maxZoomRatio必须为数值");if(1<=Number(a))return W("maxZoomRatio必须小于1")}var g=e.zoomEl;if(H(g))return W("zoomEl未配置");var m=document.querySelector(g);if(!m)return W(g+"的dom元素不存在");this.zoomNode=m}if(h||u){var d=this.ratio;if(!H(d)){if(!z(d))return W("scale必须为数值");if(Number(s)<=1)return W("scale必须大于1")}}var p=e.cutEl;if(!H(p)){var y=document.querySelector(p);if(!y)return W(p+"的dom不存在");this.submitNode=y}if(H(e.imageSrc))return W("imageSrc不能为空");var v=e.rotatable,b=e.rotateEl;if(v){if(H(b))return W("rotateEl未配置");var k=document.querySelector(b);if(!k)return W(b+"的dom不存在");this.rotateNode=k}return this.config=e,!0}},{key:"init",value:function(){var e=this;this.canvas=document.createElement("canvas"),this.loadImage(function(){e.initContainer();var t=e.config.onRender;M(t)&&t(),e.bindEvent()})}},{key:"loadImage",value:function(t){var e=this,i=this.config.imageSrc,o=new Image;o.src=i,o.onload=function(){e.image=o,M(t)&&t()},o.onerror=function(){W("图片资源加载失败")}}},{key:"initContainer",value:function(){var t=this.container,e=this.image,i=e.naturalHeight,o=e.naturalWidth,n=t.offsetHeight,r=t.offsetWidth;this.containerH=n,this.containerW=r;var s=this.orgImgW=o,a=o/(this.orgImgH=i);n<(h=i)?r<s&&a<r/n?s=(h=n)*a:h=(s=r)/a:r<s&&(s=(h=n)*a);var u=this.adjustToCut(s,h),s=T(u.imgWidth),h=T(u.imgHeight);e.style.width=s+"px",e.style.height=h+"px";var c=(n-h)/2,l=(r-s)/2;this.imgWidth=s,this.imgHeight=h,e.style.top=c+"px",e.style.left=l+"px",this.imgTop=c,this.imgLeft=l,e.style.position="absolute",t.style.position="relative",t.style.overflow="hidden",t.appendChild(e),this.addMask()}},{key:"addMask",value:function(){var e=this.container,t=this.containerH,i=this.containerW,o=this.config,n=o.cutHeight,r=o.cutWidth,s=document.createElement("div");s.setAttribute("style","position:absolute;box-sizing: border-box;border: 1px dashed #fff;");var a=this.createMask(),u=this.createMask(),h=this.createMask(),c=this.createMask();a.style.left=0,u.style.right=0,h.style.top=0,c.style.bottom=0,[a,u,h,c,s].forEach(function(t){e.appendChild(t)}),this.cutterBox=s,this.leftMask=a,this.rightMask=u,this.topMask=h,this.bottomMask=c;var l=(i-r)/2,f=(t-n)/2;this.setMaskStyle(l,f,r,n)}},{key:"setMaskStyle",value:function(t,e,i,o){var n=this.cutterBox,r=this.leftMask,s=this.rightMask,a=this.bottomMask,u=this.topMask,h=this.containerW,c=this.containerH;n.style.top=e+"px",n.style.left=t+"px",n.style.width=i+"px",n.style.height=o+"px",s.style.width=h-t-i+"px",r.style.width=t+"px",r.style.height=s.style.height=c+"px",u.style.width=a.style.width=i+"px",a.style.height=c-e-o+"px",u.style.height=e+"px",u.style.left=a.style.left=t+"px",this.config.cutWidth=i,this.config.cutHeight=o,this.cutTop=e,this.cutLeft=t}},{key:"createMask",value:function(){var t=document.createElement("div");return t.style.position="absolute",t.style.background="rgba(255, 255, 255, 0.45)",t}},{key:"bindEvent",value:function(){var e=this,i=this.container;this.cutterBox.onmouseenter=function(t){e.cutterIsEnter=!0,e.initMouse(t),i.onmousemove=function(t){e.cutterIsEnter&&(e.cutterIsDown?e.handleResize(t):e.initMouse(t))},i.onmousedown=function(t){e.cutterIsEnter&&(e.dragStatus<=0||(e.cutterIsDown=!0,e.handleMouseDown(t),i.onmouseup=function(){e.cutterIsDown&&(e.cutterIsDown=!1,e.checkCutterBox(),i.onmouseup=null)}))}},i.onmouseleave=function(){e.cutterIsEnter=!1,e.dragStatus=0,e.cutterIsDown=!1,i.onmousemove=null,i.onmousedown=null,i.onmouseup=null,e.checkCutterBox()};var t=this.config,o=t.rotatable,n=t.scalable,r=t.zoomable,s=t.ratio;n&&this.scaleNode&&(this.scaleNode.onclick=function(){e.config.scalable&&e.changeImageSize(s)}),r&&this.zoomNode&&(this.zoomNode.onclick=function(){e.config.zoomable&&e.changeImageSize(1/s)}),o&&this.rotateNode&&(this.rotateNode.onclick=function(){e.rotateImage()}),this.submitNode&&(this.submitNode.onclick=function(){e.cutImage()})}},{key:"cutImage",value:function(){var t,e,i,o,n,r,s,a,u=this.canvas,h=this.rotate,c=this.orgImgW,l=this.imgHeight,f=this.imgWidth,g=this.imgTop,m=this.imgLeft,d=this.cutLeft,p=this.cutTop,y=this.image,v=this.containerW,b=this.containerH,k=this.config,x=k.cutHeight,w=k.cutWidth,H=k.onCut,z=k.outputType,W=f/c,I=u.getContext("2d"),C=w/W,S=x/W;u.width=w,u.height=x,-1===h?(t=T((b-x-p-(b-f)/2)/W),e=T((d-(v-l)/2)/W),C=x/W,S=w/W,I.rotate(90*h*Math.PI/180),I.drawImage(y,t,e,C,S,-x,0,x,w)):-2===h?(i=this.toFixed((v-d-w-(v-f)/2)/W),o=this.toFixed((b-x-p-(b-l)/2)/W),I.rotate(90*h*Math.PI/180),I.drawImage(y,i,o,C,S,-w,-x,w,x)):-3===h?(n=this.toFixed((p-(b-f)/2)/W),r=this.toFixed((v-d-w-(v-l)/2)/W),C=x/W,S=w/W,I.rotate(90*h*Math.PI/180),I.drawImage(y,n,r,C,S,0,-w,x,w)):(s=(d-m)/W,a=(p-g)/W,I.drawImage(y,s,a,C,S,0,0,w,x));var E=u.toDataURL("image/".concat(z));return M(H)&&H(E),E}},{key:"changeImageSize",value:function(t){var e=this.imgWidth,i=this.orgImgW,o=this.orgImgH,n=this.imgHeight,r=this.containerH,s=this.containerW,a=this.image,u=this.config,h=u.maxScaleRatio,c=u.maxZoomRatio,l=u.onScale,f=u.onZoom;e*=t,n*=t,1<t?(this.config.zoomable=!0,h<e/i&&(this.config.scalable=!1,e=i*h,n=o*h)):(this.config.scalable=!0,e/i<c&&(this.containerH.zoomable=!1,e=i*c,n=o*c));var g=this.adjustToCut(e,n),e=T(g.imgWidth),n=T(g.imgHeight);this.imgWidth=e,this.imgHeight=n,a.style.width=e+"px",a.style.height=n+"px";var m=T((r-n)/2),d=T((s-e)/2);a.style.top=m+"px",a.style.left=d+"px",this.imgTop=m,this.imgLeft=d,this.checkCutterBox(),1<t&&M(l)&&l(this.config),t<1&&M(f)&&f(this.config)}},{key:"rotateImage",value:function(){var t=this.rotate;--t%4==0&&(t=0),this.image.style.transform="rotate(".concat(90*t,"deg)"),this.rotate=t,this.checkCutterBox()}},{key:"initMouse",value:function(t){var e,i,o,n,r,s,a,u,h,c,l,f;t.preventDefault(),this.cutterIsEnter&&(e=this.cutterBox,i=this.cursorEnums,o=this.container,r=(n=this.config).cutWidth,s=n.cutHeight,a=n.cutBoxResizable,u=t.clientX,l=t.clientY-(h=e.getBoundingClientRect()).top,f=0,(c=u-h.left)<10&&-10<c?l<10&&-10<l?f=1:10<=l&&l<=s-10?f=2:s-10<l&&l<s+10&&(f=3):10<=c&&c<=r-10?l<10&&-10<l?f=4:s-10<l&&l<s+10?f=5:10<=l&&l<=s-10&&(f=9):r-10<c&&c<r+10&&(l<10&&-10<l?f=6:10<=l&&l<=s-10?f=7:s-10<l&&l<s+10&&(f=8)),(a||!a&&9===f)&&(e.style.cursor=i[f]||"default",this.dragStatus=f),(c<-10||r+10<c||l<-10||s+10<l)&&(this.cutterIsEnter=!1,this.cutterIsDown=!1,o.onmousemove=null,o.onmousedown=null,o.onmouseup=null))}},{key:"handleResize",value:function(t){t.preventDefault();var e,i,o=this.config,n=o.cutWidth,r=o.cutHeight,s=o.minCutWidth,a=this.cutTop,u=this.cutLeft,h=this.startPos,c=this.dragStatus,l=this.containerW,f=this.containerH,g=t.clientX-h.clientX,m=t.clientY-h.clientY;if(1<=c&&c<=3){var d,p=n-g,y=u+g,v=r,b=a;if(p<s)return;y<0&&(y=0),1===c?(v=(d=this.resizeTop(r,a,m)).newHeight,b=d.newTop):3===c&&(v=this.resizeBottom(r,a,m).newHeight),this.setMaskStyle(y,b,p,v)}else if(4===c){var k=this.resizeTop(r,a,m),x=k.newHeight,w=k.newTop;this.setMaskStyle(u,w,n,x)}else if(5===c){var H=this.resizeBottom(r,a,m).newHeight;this.setMaskStyle(u,a,n,H)}else if(6<=c&&c<=8){var z,W=n+g,I=a,C=r;if(W<s)return;l<u+W&&(W=l-n),6===c?(C=(z=this.resizeTop(r,a,m)).newHeight,I=z.newTop):8===c&&(C=this.resizeBottom(r,a,m).newHeight),this.setMaskStyle(u,I,W,C)}else{9===c&&((i=a+m)<0&&(i=0),(e=u+g)<0&&(e=0),l<e+n&&(e=l-n),f<i+r&&(i=f-r),this.setMaskStyle(e,i,n,r))}this.startPos={clientX:t.clientX,clientY:t.clientY}}},{key:"checkCutterBox",value:function(){var t,e=this.config,i=e.cutHeight,o=e.cutWidth,n=this.cutterBox,r=this.cutTop,s=this.cutLeft,a=this.imgTop,u=this.imgLeft,h=this.imgHeight,c=this.imgWidth,l=this.bottomMask,f=this.topMask,g=this.rightMask,m=this.leftMask,d=this.containerW,p=this.containerH;this.rotate%2!=0&&(u=(d-h)/2,a=(p-c)/2,t=c,c=h,h=t),c<o&&(o=c),h<i&&(i=h),s<u&&(s=u),u+c<s+o&&(s=u+c-o),r<a&&(r=a),a+h<r+i&&(r=a+h-i);var y=[n,l,f,g,m];y.forEach(function(t){t.style.transition="all 0.3s"}),this.setMaskStyle(s,r,o,i),setTimeout(function(){y.forEach(function(t){t.style.transition=""})},300)}},{key:"handleMouseDown",value:function(t){this.startPos={clientX:t.clientX,clientY:t.clientY}}},{key:"resizeTop",value:function(t,e,i){var o=t-i,n=e+i;if(!(o<this.config.minCutHeight))return n<0&&(n=0),{newTop:n,newHeight:o}}},{key:"resizeBottom",value:function(t,e,i){var o=this.containerH,n=t+i;if(!(n<this.config.minCutHeight))return o<e+n&&(n=o-e),{newHeight:n}}},{key:"adjustToCut",value:function(t,e){var i=this.orgImgW,o=this.orgImgH,n=this.config,r=n.cutWidth,s=n.cutHeight,a=i/o,u=r/s;return e<s?(this.config.zoomable=!1,!(t<r)||u<a?t=(e=s)*a:e=(t=r)/a):t<r&&(this.config.zoomable=!1,e=(t=r)/a),{imgWidth:t,imgHeight:e}}}])&&n(t.prototype,i),o&&n(t,o),e}()});