1

I want to crop image in specific area, I made below example it is work when the inner not been rotate
my problem is after rotate the inner, I don't get how to find correct sx,sy,sw,sh to crop

UPDATE
base on this answer fix the draw rotate image part, I update in fiddle. but I still don't get how to find correct position to crop rotated image ...

https://jsfiddle.net/ve219z34/3/

var crop = function() {
  var transformMediaBlock = $('.mediaBlock');
  var transformCropInner = $('.transformCropInner');
  var transformCropLimit = $('.transformCropLimit');
  var canvasContainer = $('.canvasContainer')

  var limitLeft = transformCropLimit.offset().left;
  var limitTop = transformCropLimit.offset().top;
  var limitRight = limitLeft + transformCropLimit.width();
  var limitBottom = limitTop + transformCropLimit.height();
  
  var imageRatio = transformMediaBlock.find('img')[0].naturalWidth/transformMediaBlock.find('img').width();


  // draw rotate image
  var deg2Rad = Math.PI/180;

  var rotateDegree = -20;

  $('<canvas/>',{'class':'rotate'}).appendTo($(canvasContainer));
  var canvas = $('.canvasContainer canvas')[0];


  var ctx = canvas.getContext("2d");
  var width = 0;
  var height = 0;
  var diagonal = 0;
  var angleInDegrees = 0;

  width = transformMediaBlock.find('img')[0].naturalWidth;
  height = transformMediaBlock.find('img')[0].naturalHeight;
  diagonal = Math.sqrt(Math.pow(width,2)+Math.pow(height,2));
  ctx.canvas.width = diagonal;
  ctx.canvas.height = diagonal;
  ctx.clearRect(0,0,canvas.width,canvas.height);
  ctx.save();
  ctx.translate(diagonal/2,diagonal/2);
  ctx.rotate(0*Math.PI/180);
  ctx.drawImage(transformMediaBlock.find('img')[0],-width/2,-height/2);
  ctx.restore();

  var drawRotated = function(degrees){
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.save();
    ctx.translate(diagonal/2,diagonal/2);
    ctx.rotate(degrees*Math.PI/180);
    ctx.drawImage(transformMediaBlock.find('img')[0],-width/2,-height/2);
    ctx.restore();
  };

  drawRotated(rotateDegree);
  
  
  // problem is here don't know how to get correct sx sy sw sh with image been rotate
  // draw crop rotate image
  var imageLeft = transformMediaBlock.find('img').offset().left;
  var imageTop = transformMediaBlock.find('img').offset().top;
  var imageRight = imageLeft + transformMediaBlock.find('img').width();
  var imageBottom = imageTop + transformMediaBlock.find('img').height();

  if (limitLeft <= imageLeft) {
    var sx = 0;
  } else {
    var sx = limitLeft - imageLeft;
  }
  if (limitTop <= imageTop) {
    var sy = 0;
  } else {
    var sy = limitTop - imageTop;
  }
  if (limitLeft <= imageLeft) {
    var l =  imageLeft;
  } else {
    var l = limitLeft;
  }
  if (limitRight <= imageRight) {
    var r = limitRight;
  } else {
    var r = imageRight;
  }
  var sw = r - l;
  if (limitTop <= imageTop) {
    var t = imageTop;
  } else {
    var t = limitTop;
  }
  if (limitBottom <= imageBottom) {
    var b = limitBottom;
  } else {
    var b = imageBottom;
  }
  var sh = b - t;

  sx = sx*imageRatio;
  sy = sy*imageRatio;
  sw = sw*imageRatio;
  sh = sh*imageRatio;

  var dx = 0;
  var dy = 0;
  var dw = sw;
  var dh = sh;
  
};


$('#container').on('click', '.action.crop', function (e) {
  var transformMediaBlock = $('.mediaBlock');
  transformMediaBlock.find('img').on('load', function() {
   $('.transformCropInner').addClass('rotate');
    crop();
  }).each(function() {
    if(this.complete) $(this).load();
  });
});
.mediaBlock {
  position: relative;
  display: block;
  overflow: hidden;
}
.mediaBlock img {
  max-width: 100%;
}

.transformCropLimit {
  position: relative;
  top: 20px;
  left: 20px;
  width: 200px;
  height: 200px;
  border: 1px solid blue;
}

.transformCropInner {
  width: 100px;
  cursor: pointer;
  position: relative;
  top: 10px;
  left: 100px;
}

.transformCropInner.rotate {
  transform: rotate(9-2deg);
  -ms-transform: rotate(-20deg); /* IE 9 */
  -moz-transform: rotate(-20deg); /* Firefox */
  -webkit-transform: rotate(-20deg); /* Safari and Chrome */
  -o-transform: rotate(-20deg); /* Opera */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container">
  <div class="canvasContainer"></div>  

  <div class="content main">
    <div class="action crop">Crop</div>

    <div class="transformCropLimit">
      <div class="transformCropInner">
        <div class="mediaBlock">
          <img src="http://image.vsco.co/1/55210eb4aceed3144059/57f2471df662677e548b4568/300x400/25e7b55c-6ed9-490c-95c2-6d69520eb7bd1835072132.jpg">
        </div>
      </div>
    </div>
  </div>
</div>

Please don't provide plugin as an answer, and css crop is not what I'm looking for.

Community
  • 1
  • 1
user1775888
  • 3,147
  • 13
  • 45
  • 65
  • Possible duplicate of [javascript crop image to canvas](http://stackoverflow.com/questions/39968756/javascript-crop-image-to-canvas) – winterfruit Oct 11 '16 at 21:45
  • 1
    no it's different. I want find how to crop the rotate image. can't figure how to set sx,sy after rotate. your marked question that just crop. – user1775888 Oct 11 '16 at 22:34
  • Several options: 1. Use trigonometry to calculate the rotated vertices. Then make a path of those rotated vertices and clip(). 2. Repeat the transformations and context.rect the sub-image using the original (untransformed) position & size of the sub-image. Do clip(). Then when using either #1 or #2, set globalCompositeOperation='copy' and fillRect the entire canvas. Compositing will redraw the canvas and clipping will allow only your desired rotated-rect to display. Sorry for the summary comments, but time doesn't permit a full answer. – markE Oct 12 '16 at 02:46

0 Answers0