123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 |
- 'use strict';
- crop.factory('cropHost', ['$document', 'cropAreaCircle', 'cropAreaSquare', 'cropEXIF', function($document, CropAreaCircle, CropAreaSquare, cropEXIF) {
- /* STATIC FUNCTIONS */
- // Get Element's Offset
- var getElementOffset=function(elem) {
- var box = elem.getBoundingClientRect();
- var body = document.body;
- var docElem = document.documentElement;
- var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
- var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
- var clientTop = docElem.clientTop || body.clientTop || 0;
- var clientLeft = docElem.clientLeft || body.clientLeft || 0;
- var top = box.top + scrollTop - clientTop;
- var left = box.left + scrollLeft - clientLeft;
- return { top: Math.round(top), left: Math.round(left) };
- };
- return function(elCanvas, opts, events){
- /* PRIVATE VARIABLES */
- // Object Pointers
- var ctx=null,
- image=null,
- theArea=null;
- // Dimensions
- var minCanvasDims=[100,100],
- maxCanvasDims=[300,300];
- // Result Image size
- var resImgSize=200;
- // Result Image type
- var resImgFormat='image/png';
- // Result Image quality
- var resImgQuality=null;
- /* PRIVATE FUNCTIONS */
- // Draw Scene
- function drawScene() {
- // clear canvas
- ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
- if(image!==null) {
- // draw source image
- ctx.drawImage(image, 0, 0, ctx.canvas.width, ctx.canvas.height);
- ctx.save();
- // and make it darker
- ctx.fillStyle = 'rgba(0, 0, 0, 0.65)';
- ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
- ctx.restore();
- // draw Area
- theArea.draw();
- }
- }
- // Resets CropHost
- var resetCropHost=function() {
- if(image!==null) {
- theArea.setImage(image);
- var imageDims=[image.width, image.height],
- imageRatio=image.width/image.height,
- canvasDims=imageDims;
- if(canvasDims[0]>maxCanvasDims[0]) {
- canvasDims[0]=maxCanvasDims[0];
- canvasDims[1]=canvasDims[0]/imageRatio;
- } else if(canvasDims[0]<minCanvasDims[0]) {
- canvasDims[0]=minCanvasDims[0];
- canvasDims[1]=canvasDims[0]/imageRatio;
- }
- if(canvasDims[1]>maxCanvasDims[1]) {
- canvasDims[1]=maxCanvasDims[1];
- canvasDims[0]=canvasDims[1]*imageRatio;
- } else if(canvasDims[1]<minCanvasDims[1]) {
- canvasDims[1]=minCanvasDims[1];
- canvasDims[0]=canvasDims[1]*imageRatio;
- }
- elCanvas.prop('width',canvasDims[0]).prop('height',canvasDims[1]).css({'margin-left': -canvasDims[0]/2+'px', 'margin-top': -canvasDims[1]/2+'px'});
- theArea.setX(ctx.canvas.width/2);
- theArea.setY(ctx.canvas.height/2);
- theArea.setSize(Math.min(200, ctx.canvas.width/2, ctx.canvas.height/2));
- } else {
- elCanvas.prop('width',0).prop('height',0).css({'margin-top': 0});
- }
- drawScene();
- };
- /**
- * Returns event.changedTouches directly if event is a TouchEvent.
- * If event is a jQuery event, return changedTouches of event.originalEvent
- */
- var getChangedTouches=function(event){
- if(angular.isDefined(event.changedTouches)){
- return event.changedTouches;
- }else{
- return event.originalEvent.changedTouches;
- }
- };
- var onMouseMove=function(e) {
- if(image!==null) {
- var offset=getElementOffset(ctx.canvas),
- pageX, pageY;
- if(e.type === 'touchmove') {
- pageX=getChangedTouches(e)[0].pageX;
- pageY=getChangedTouches(e)[0].pageY;
- } else {
- pageX=e.pageX;
- pageY=e.pageY;
- }
- theArea.processMouseMove(pageX-offset.left, pageY-offset.top);
- drawScene();
- }
- };
- var onMouseDown=function(e) {
- e.preventDefault();
- e.stopPropagation();
- if(image!==null) {
- var offset=getElementOffset(ctx.canvas),
- pageX, pageY;
- if(e.type === 'touchstart') {
- pageX=getChangedTouches(e)[0].pageX;
- pageY=getChangedTouches(e)[0].pageY;
- } else {
- pageX=e.pageX;
- pageY=e.pageY;
- }
- theArea.processMouseDown(pageX-offset.left, pageY-offset.top);
- drawScene();
- }
- };
- var onMouseUp=function(e) {
- if(image!==null) {
- var offset=getElementOffset(ctx.canvas),
- pageX, pageY;
- if(e.type === 'touchend') {
- pageX=getChangedTouches(e)[0].pageX;
- pageY=getChangedTouches(e)[0].pageY;
- } else {
- pageX=e.pageX;
- pageY=e.pageY;
- }
- theArea.processMouseUp(pageX-offset.left, pageY-offset.top);
- drawScene();
- }
- };
- this.getResultImageDataURI=function() {
- var temp_ctx, temp_canvas;
- temp_canvas = angular.element('<canvas></canvas>')[0];
- temp_ctx = temp_canvas.getContext('2d');
- temp_canvas.width = resImgSize;
- temp_canvas.height = resImgSize;
- if(image!==null){
- temp_ctx.drawImage(image, (theArea.getX()-theArea.getSize()/2)*(image.width/ctx.canvas.width), (theArea.getY()-theArea.getSize()/2)*(image.height/ctx.canvas.height), theArea.getSize()*(image.width/ctx.canvas.width), theArea.getSize()*(image.height/ctx.canvas.height), 0, 0, resImgSize, resImgSize);
- }
- if (resImgQuality!==null ){
- return temp_canvas.toDataURL(resImgFormat, resImgQuality);
- }
- return temp_canvas.toDataURL(resImgFormat);
- };
- this.setNewImageSource=function(imageSource) {
- image=null;
- resetCropHost();
- events.trigger('image-updated');
- if(!!imageSource) {
- var newImage = new Image();
- if(imageSource.substring(0,4).toLowerCase()==='http') {
- newImage.crossOrigin = 'anonymous';
- }
- newImage.onload = function(){
- events.trigger('load-done');
- cropEXIF.getData(newImage,function(){
- var orientation=cropEXIF.getTag(newImage,'Orientation');
- if([3,6,8].indexOf(orientation)>-1) {
- var canvas = document.createElement("canvas"),
- ctx=canvas.getContext("2d"),
- cw = newImage.width, ch = newImage.height, cx = 0, cy = 0, deg=0;
- switch(orientation) {
- case 3:
- cx=-newImage.width;
- cy=-newImage.height;
- deg=180;
- break;
- case 6:
- cw = newImage.height;
- ch = newImage.width;
- cy=-newImage.height;
- deg=90;
- break;
- case 8:
- cw = newImage.height;
- ch = newImage.width;
- cx=-newImage.width;
- deg=270;
- break;
- }
- canvas.width = cw;
- canvas.height = ch;
- ctx.rotate(deg*Math.PI/180);
- ctx.drawImage(newImage, cx, cy);
- image=new Image();
- image.src = canvas.toDataURL("image/png");
- } else {
- image=newImage;
- }
- resetCropHost();
- events.trigger('image-updated');
- });
- };
- newImage.onerror=function() {
- events.trigger('load-error');
- };
- events.trigger('load-start');
- newImage.src=imageSource;
- }
- };
- this.setMaxDimensions=function(width, height) {
- maxCanvasDims=[width,height];
- if(image!==null) {
- var curWidth=ctx.canvas.width,
- curHeight=ctx.canvas.height;
- var imageDims=[image.width, image.height],
- imageRatio=image.width/image.height,
- canvasDims=imageDims;
- if(canvasDims[0]>maxCanvasDims[0]) {
- canvasDims[0]=maxCanvasDims[0];
- canvasDims[1]=canvasDims[0]/imageRatio;
- } else if(canvasDims[0]<minCanvasDims[0]) {
- canvasDims[0]=minCanvasDims[0];
- canvasDims[1]=canvasDims[0]/imageRatio;
- }
- if(canvasDims[1]>maxCanvasDims[1]) {
- canvasDims[1]=maxCanvasDims[1];
- canvasDims[0]=canvasDims[1]*imageRatio;
- } else if(canvasDims[1]<minCanvasDims[1]) {
- canvasDims[1]=minCanvasDims[1];
- canvasDims[0]=canvasDims[1]*imageRatio;
- }
- elCanvas.prop('width',canvasDims[0]).prop('height',canvasDims[1]).css({'margin-left': -canvasDims[0]/2+'px', 'margin-top': -canvasDims[1]/2+'px'});
- var ratioNewCurWidth=ctx.canvas.width/curWidth,
- ratioNewCurHeight=ctx.canvas.height/curHeight,
- ratioMin=Math.min(ratioNewCurWidth, ratioNewCurHeight);
- theArea.setX(theArea.getX()*ratioNewCurWidth);
- theArea.setY(theArea.getY()*ratioNewCurHeight);
- theArea.setSize(theArea.getSize()*ratioMin);
- } else {
- elCanvas.prop('width',0).prop('height',0).css({'margin-top': 0});
- }
- drawScene();
- };
- this.setAreaMinSize=function(size) {
- size=parseInt(size,10);
- if(!isNaN(size)) {
- theArea.setMinSize(size);
- drawScene();
- }
- };
- this.setResultImageSize=function(size) {
- size=parseInt(size,10);
- if(!isNaN(size)) {
- resImgSize=size;
- }
- };
- this.setResultImageFormat=function(format) {
- resImgFormat = format;
- };
- this.setResultImageQuality=function(quality){
- quality = parseFloat(quality);
- if (!isNaN(quality) && quality>=0 && quality<=1){
- resImgQuality = quality;
- }
- };
- this.setAreaType=function(type) {
- var curSize=theArea.getSize(),
- curMinSize=theArea.getMinSize(),
- curX=theArea.getX(),
- curY=theArea.getY();
- var AreaClass=CropAreaCircle;
- if(type==='square') {
- AreaClass=CropAreaSquare;
- }
- theArea = new AreaClass(ctx, events);
- theArea.setMinSize(curMinSize);
- theArea.setSize(curSize);
- theArea.setX(curX);
- theArea.setY(curY);
- // resetCropHost();
- if(image!==null) {
- theArea.setImage(image);
- }
- drawScene();
- };
- /* Life Cycle begins */
- // Init Context var
- ctx = elCanvas[0].getContext('2d');
- // Init CropArea
- theArea = new CropAreaCircle(ctx, events);
- // Init Mouse Event Listeners
- $document.on('mousemove',onMouseMove);
- elCanvas.on('mousedown',onMouseDown);
- $document.on('mouseup',onMouseUp);
- // Init Touch Event Listeners
- $document.on('touchmove',onMouseMove);
- elCanvas.on('touchstart',onMouseDown);
- $document.on('touchend',onMouseUp);
- // CropHost Destructor
- this.destroy=function() {
- $document.off('mousemove',onMouseMove);
- elCanvas.off('mousedown',onMouseDown);
- $document.off('mouseup',onMouseMove);
- $document.off('touchmove',onMouseMove);
- elCanvas.off('touchstart',onMouseDown);
- $document.off('touchend',onMouseMove);
- elCanvas.remove();
- };
- };
- }]);
|