Question

Hi I'm having issue with the jcrop selector when I rotate my jcropped image. When the image is rotated with css, my jcrop selector moves in an inverse fashion. I believe it is because jcrop doesn't realize it's getting rotated and the selector is moving according to the original image dimensions.

Is there a way for me to tell jcrop that the image is rotated?

Btw I'm using angularjs directive to implement jcrop (it's an angularjsapp). Thanks

directive.js

.directive('imgCropped', function() {
return {
    restrict: 'E',
    replace: true,
    scope: {src: '@', selected: '&'},
    link: function(scope, element, attr) {
        var myImg;
        var clear = function() {
            if (myImg) {
                myImg.next().remove();
                myImg.remove();
                myImg = undefined;
            }
        };
        scope.$watch('src', function(nv) {
            clear();
            if (nv) {
                element.after('<img degrees="angle" rotate/>');
                myImg = element.next();
                myImg.attr('src', nv);

                $(myImg).Jcrop({
                    trackDocument: true,
                    onSelect: function(x) {
                        /*if (!scope.$$phase) {
                         scope.$apply(function() {
                         scope.selected({cords: x});
                         });
                         }*/
                        scope.selected({cords: x});
                    },
                    keySupport: false,
                  aspectRatio: 1,
                    boxWidth: 400, boxHeight: 400,
                    setSelect: [0, 0, 400, 400]
                }, function(){
                     jcrop_api = this;
                });
                //$(myImg).rotate(90);


            }
        });
        scope.$on('$destroy', clear);
     }
    };
   })
Was it helpful?

Solution

the question is same as Make Jcrop tracker not rotate when cropping a rotated image

the JCrop has the problem of selection direction error after rotated by JQuery rotate. I had to resolve it by change the JCrop's js code to support rotate.

Fortunatly, it's not hard to do, you can do it yourself by replace one line: 136 to sub codes:

    //========= begin replace origin line 136 for rotate
    var x = pos[0] - lloc[0];
    var y = pos[1] - lloc[1];
    var rotate = options.rotate || 0;
    var angle = (rotate / 90) % 4;
    if (angle == 1) {
      var temp = x;
      x = y;
      y = - temp;
    } else if (angle == 2) {
      x = -x;
      y = -y;
    } else if (angle == 3) {
      var temp = x;
      x = -y;
      y = temp;
    }
    Coords.moveOffset([x, y]);
    //========= end replace origin line 136 for rotate

or you can get the updated code by url: https://github.com/ergoli/Jcrop/tree/master/js

be careful! you should transfer the rotate option after each rotate click:

jCropApi.setoptions({rotate : 90});  //rotate 90

OTHER TIPS

it's better to change this function so that it can affect all the functionalities not only moving the selected area.

function mouseAbs(e) //{{{
        {
            //return [(e.pageX - docOffset[0]), (e.pageY - docOffset[1])];
            var x = e.pageX - docOffset[0];
            var y = e.pageY - docOffset[1];
            var rotate = options.rotate || 0;
            var angle = (rotate / 90) % 4;
            if (angle == 1) {
                var temp = x;
                x = (e.pageY - docOffset[1]);
                y = -(e.pageX - docOffset[0] - $('.jcrop-holder').height());
            } else if (angle == 2) {
                x = -(e.pageX - docOffset[0] - $('.jcrop-holder').width());
                y = -(e.pageY - docOffset[1] - $('.jcrop-holder').height());
            } else if (angle == 3) {
                var temp = x;
                x = -(e.pageY - docOffset[1] - $('.jcrop-holder').width());
                y = (e.pageX - docOffset[0]);
            }
            return [x, y];
        }

George's answer works by far the best than any other I've seen, with the exception that it does not handle angles that are not right-angles (80 degrees, 150 degrees, etc.).

Based on this algorithm, here's what I came up with:

    function mouseAbs(e) //{{{
{
  //return [(e.pageX - docOffset[0]), (e.pageY - docOffset[1])];
  var x = e.pageX - docOffset[0];
  var y = -(e.pageY - docOffset[1]);
  var centerY = -($j('.jcrop-holder').height() / 2);
  var centerX = $j('.jcrop-holder').width() / 2;
  var rotate = options.rotate || 0;
  // radians
  rotate = rotate * Math.PI / 180;
  var x2 = x - centerX;
  var y2 = y - centerY;
  var cos = Math.cos(rotate);
  var sin = Math.sin(rotate);
  x = x2 * cos - y2 * sin + centerX;
  y = x2 * sin + y2 * cos + centerY;
  return [x, -y];
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top