3

I'm trying to add JQuery resize with handles to an element and it works fine, Except when I rotate it transform: rotate(90deg) or any other angle, the handles axis remains the same and causes issues.

I'm trying to rotate the resize handlers axis as per the elements' angle (if that's possible).

Here's the sample code I made for this:

<div class="main">
  <img src="https://tinypng.com/images/social/website.jpg" />
</div>

<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">

<style>
.main {
  width: 400px;
  height: 400px;
  /* transform:rotate(90deg); */
  & img {
    width:100%;
    width:100%;
  }
}
</style>

<script>
function dragger() {
  $(".main").draggable({
      cursor: "move"
    });

    $(".main").resizable({
      handles: "n, e, s, w, se, ne",
     });
}

dragger();
</script>

Here, the resize along with draggable works perfectly fine, except as I add transform: rotate(90deg) to the `main element, the resize handles axis remains the same.

Here's a JSFiddle for the same to play around.

Any help is greatly appreciated.

Harry K
  • 125
  • 12
  • You do not seem to be the first asking this, please have a look at some previous examples of the same issue [Question 1 - 5 years old](https://stackoverflow.com/questions/45127468/jquery-resizing-a-rotated-image-using-mouse-mousemove-event) and [Question 2 - 4 years old](https://stackoverflow.com/questions/51773686/how-to-resize-div-after-rotating-it-is-it-possible-to-modify-the-mouse-event-co). There seems no great solution, as the cursor is handled by the browser. Perhaps if you implement this in a canvas, and rotate a custom cursor, you will have more granular control. – Daniel ZA Jan 29 '23 at 17:46
  • hi, I seen your both references, none of them has answers. – Harry K Jan 30 '23 at 05:46
  • 1
    In your example, why not add the transform to the child image attribute – Chris Warnes Feb 01 '23 at 09:03
  • @ChrisWarnes (1). Cause I have a border around the parent div that is visible, so, if I rotate the image alone, there is white space on the sides when it comes to a nonsquare image. (FYI, I need that parent div, cant remove it and add border to image). (2). I even tried the same thing, instead of rotating parent div, rotating the image, as the non-square image rotates, the resize parameters are applied to the parent div not the image itself, so you cannot actually drag the image side to resize it rather have to find the parent div side. Hope i was clear. – Harry K Feb 02 '23 at 04:48

1 Answers1

0

You can calculate the new position of the handles based on the rotation angle and the original position of the handle. You can do this using JavaScript and the CSS transform properties.

Here's a sample code that you can use:

<div class="main">
  <img src="https://tinypng.com/images/social/website.jpg" />
</div>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<style>
.main {
  width: 400px;
  height: 400px;
  transform: rotate(90deg);
  & img {
    width:100%;
    width:100%;
  }
}
</style>
<script>
function dragger() {
  $(".main").draggable({
      cursor: "move"
    });

  $(".main").resizable({
    handles: "n, e, s, w, se, ne",
    start: function(event, ui) {
      // Store the original position of the handles
      var handles = $(this).resizable("option", "handles");
      $(handles).each(function() {
        var handle = $(this);
        var pos = handle.position();
        handle.data("origin", {
          top: pos.top,
          left: pos.left
        });
      });
    },
    resize: function(event, ui) {
      // Calculate the new position of the handles based on the rotation angle
      var rotation = $(this).css("transform");
      rotation = rotation.split("(")[1];
      rotation = rotation.split("deg")[0];
      rotation = parseInt(rotation);
      var handles = $(this).resizable("option", "handles");
      $(handles).each(function() {
        var handle = $(this);
        var origin = handle.data("origin");
        var newTop = origin.top - ui.originalPosition.top + ui.position.top;
        var newLeft = origin.left - ui.originalPosition.left + ui.position.left;
        var newPos = rotate(newTop, newLeft, rotation);
        handle.css("top", newPos.top);
        handle.css("left", newPos.left);
      });
    }
  });
}

function rotate(top, left, angle) {
  // Calculate the new position of the handle based on the rotation angle
  var rad = angle * Math.PI / 180;
  var cos = Math.cos(rad);
  var sin = Math.sin(rad);
  var newTop = left * sin + top * cos;
  var newLeft = left * cos - top * sin;
  return {
    top: newTop,
    left: newLeft
  };
}

dragger();
</script>
  • This is the [jsfiddle](https://jsfiddle.net/v2zkmo3y/) of your code. I don't think it works. please kindly check. – Harry K Feb 06 '23 at 15:57