image-focus
Version:
A dependency free utility for cropping images based on a focal point ~2.13kB gzipped
3 lines (2 loc) • 7.52 kB
JavaScript
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).imageFocus={})}(this,(function(t){"use strict";function e(t){for(var e=arguments.length,i=new Array(e>1?e-1:0),n=1;n<e;n++)i[n-1]=arguments[n];return i.forEach((function(e){return Object.keys(e).forEach((function(i){return t[i]=e[i]}))})),t}var i={position:"relative",overflow:"hidden"},n={position:"absolute",top:"0",right:"0",bottom:"0",left:"0"},s={display:"block",maxWidth:"100%",touchAction:"none"},o={position:"absolute",cursor:"move",transform:"translate(-50%, -50%)"},a={onChange:function(){},retina:"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3e %3cg fill='none' fill-rule='evenodd'%3e %3ccircle id='a' cx='10' cy='10' r='10' fill='black' fill-opacity='.3' /%3e %3ccircle cx='10' cy='10' r='9' stroke='white' stroke-opacity='.8' stroke-width='2'/%3e %3c/g%3e%3c/svg%3e"},r=function(){function t(t,n){var o=this;void 0===n&&(n={}),this._enabled=!1,this.startDragging=function(t){t.preventDefault(),o.isDragging=!0,t instanceof MouseEvent?o.updateCoordinates(t.clientX,t.clientY):o.updateCoordinates(t.touches[0].clientX,t.touches[0].clientY)},this.handleMove=function(t){if(t.preventDefault(),t instanceof MouseEvent)o.updateCoordinates(t.clientX,t.clientY);else{var e=t.touches[0],i=document.elementFromPoint(e.pageX,e.pageY);i!==o.retina&&i!==o.img?o.stopDragging():o.updateCoordinates(e.clientX,e.clientY)}},this.stopDragging=function(){o.isDragging=!1},this.updateRetinaPositionFromFocus=function(){o.updateRetinaPosition(o.calculateOffsetFromFocus())},this.updateRetinaPosition=function(t){o.retina.style.top=t.offsetY+"px",o.retina.style.left=t.offsetX+"px"},this.options=e({},a,n),this.img=t,this.container=t.parentElement,this.img.draggable=!1,e(this.img.style,s),e(this.container.style,i),this.focus=this.getFocus(),this.enable()}var n,r=t.prototype;return r.getFocus=function(){return this.options.focus?this.options.focus:{x:parseFloat(this.img.getAttribute("data-focus-x"))||0,y:parseFloat(this.img.getAttribute("data-focus-y"))||0}},r.enable=function(){this._enabled||(this.retina=document.createElement("img"),this.retina.src=this.options.retina,this.retina.draggable=!1,this.container.appendChild(this.retina),e(this.retina.style,o),this.startListening(),this.setFocus(this.focus),this._enabled=!0)},r.disable=function(){this._enabled&&this.retina&&(this.stopListening(),this.container.removeChild(this.retina),this._enabled=!1)},r.startListening=function(){this.container.addEventListener("mousedown",this.startDragging),this.container.addEventListener("mousemove",this.handleMove),this.container.addEventListener("mouseup",this.stopDragging),this.container.addEventListener("mouseleave",this.stopDragging),this.container.addEventListener("touchend",this.stopDragging),this.container.addEventListener("touchstart",this.startDragging,{passive:!0}),this.container.addEventListener("touchmove",this.handleMove,{passive:!0}),this.img.addEventListener("load",this.updateRetinaPositionFromFocus)},r.stopListening=function(){this.container.removeEventListener("mousedown",this.startDragging),this.container.removeEventListener("mousemove",this.handleMove),this.container.removeEventListener("mouseup",this.stopDragging),this.container.removeEventListener("mouseleave",this.stopDragging),this.container.removeEventListener("touchend",this.stopDragging),this.container.removeEventListener("touchstart",this.startDragging),this.container.removeEventListener("touchmove",this.handleMove),this.img.removeEventListener("load",this.updateRetinaPositionFromFocus)},r.setFocus=function(t){this.focus=t,this.img.setAttribute("data-focus-x",t.x.toString()),this.img.setAttribute("data-focus-y",t.y.toString()),this.updateRetinaPositionFromFocus(),this.options.onChange(t)},r.calculateOffsetFromFocus=function(){var t=this.img.getBoundingClientRect();return{offsetX:t.width*(this.focus.x/2+.5),offsetY:t.height*(this.focus.y/-2+.5)}},r.updateCoordinates=function(t,e){if(this.isDragging){var i=this.img.getBoundingClientRect();this.setFocus({x:2*((t-i.left)/i.width-.5),y:-2*((e-i.top)/i.height-.5)})}},(n=[{key:"enabled",get:function(){return this._enabled}}])&&function(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}(t.prototype,n),t}(),h={minHeight:"100%",minWidth:"100%"},c={height:"100%",width:"100%",border:"none",opacity:0,zIndex:-1,pointerEvents:"none"},u={debounceTime:17,updateOnWindowResize:!0,updateOnContainerResize:!1,containerPosition:"relative"},g=function(){function t(t,s){var o,a,r,c=this;void 0===s&&(s={}),this.imageNode=t,this.listening=!1,this.setFocus=function(t){c.focus=t,c.img.setAttribute("data-focus-x",t.x.toString()),c.img.setAttribute("data-focus-y",t.y.toString()),c.applyShift()},this.applyShift=function(){var t=c.img,e=t.naturalWidth,i=t.naturalHeight,n=c.container.getBoundingClientRect(),s=n.width,o=n.height,a="0",r="0";if(!(s>0&&o>0&&e>0&&i>0))return!1;var h=e/s,u=i/o;c.img.style.maxHeight=null,c.img.style.maxWidth=null,e>s&&i>o&&(c.img.style[h>u?"maxHeight":"maxWidth"]="100%"),h>u?a=c.calcShift(u,s,e,c.focus.x)+"%":h<u&&(r=c.calcShift(h,o,i,c.focus.y,!0)+"%"),c.img.style.top=r,c.img.style.left=a},this.options=e(u,s),this.img=t,this.container=t.parentElement,this.img.__focused_image_instance__&&(this.img.__focused_image_instance__.stopListening(),this.img.removeEventListener("load",this.applyShift)),this.img.__focused_image_instance__=this,this.img.addEventListener("load",this.applyShift),e(this.container.style,i),this.container.style.position=this.options.containerPosition,e(this.img.style,h,n),this.debounceApplyShift=(o=this.applyShift,a=this.options.debounceTime,function(){for(var t=arguments.length,e=new Array(t),i=0;i<t;i++)e[i]=arguments[i];clearTimeout(r),r=setTimeout((function(){return o.apply(void 0,e)}),a)}),this.focus=this.options.focus?this.options.focus:{x:parseFloat(this.img.getAttribute("data-focus-x"))||0,y:parseFloat(this.img.getAttribute("data-focus-y"))||0},this.startListening(),this.setFocus(this.focus)}var s=t.prototype;return s.startListening=function(){var t=this;if(!this.listening&&(this.listening=!0,this.options.updateOnWindowResize&&window.addEventListener("resize",this.debounceApplyShift),this.options.updateOnContainerResize)){var i=document.createElement("object");e(i.style,c,n),i.addEventListener("load",(function(e){return i.contentDocument.defaultView.addEventListener("resize",(function(){return t.debounceApplyShift()}))})),i.type="text/html",i.setAttribute("aria-hidden","true"),i.tabIndex=-1,this.container.appendChild(i),i.data="about:blank",this.resizeListenerObject=i}},s.stopListening=function(){this.listening&&(this.listening=!1,window.removeEventListener("resize",this.debounceApplyShift),this.resizeListenerObject&&this.resizeListenerObject.contentDocument&&(this.resizeListenerObject.contentDocument.defaultView.removeEventListener("resize",this.debounceApplyShift),this.container.removeChild(this.resizeListenerObject),this.resizeListenerObject=null))},s.calcShift=function(t,e,i,n,s){var o=Math.floor(e/2),a=(n+1)/2,r=Math.floor(i/t),h=Math.floor(a*r);s&&(h=r-h);var c=h-o,u=r-h,g=e-o;return u<g&&(c-=g-u),c<0&&(c=0),-100*c/e},t}();t.FocusPicker=r,t.FocusedImage=g,Object.defineProperty(t,"__esModule",{value:!0})}));
//# sourceMappingURL=image-focus.umd.production.min.js.map