3

HI All. I am using the below code to rotate the drag/dropped image.The rotation is working fine,but when i start rotating ,the image moves outside the "div" container .Anything i am missing.

    //Moving outside the container for first time.After dragging inside the div,then rotates inside the div
  var test = 5;
  var mouseDown = false;
  $(function() {
      $('.frame').mousedown(function(e) { mouseDown = true; });
      $('.frame').mouseup(function(e) { mouseDown = false; });
      $('.frame .rotatable').live('mousemove', function(e) {
          if ((mouseDown) && (e.ctrlKey)) {

              test = test + 10;
              var currentId;
              document.getElementById('angle').value = test;
              $(this).rotate({ angle: test });
              var currentId = $(this).attr('id');
              var id = currentId.substring(8);                  
              var deleteimage = 0;
              var angle = test;
              saveCoords(e.clientX, e.clientY, angle, id, document.getElementById("<%=trafficID.ClientID%>").value, deleteimage);
          }
          $('#frame .rotatable').draggable({ containment: 'parent' });

      });
  });

HTML

<div id="frame" class="frame" runat="server"  style="width:550px; height:400px;background-position:bottom; border:1px solid #000;">

Thanks,

Vani
  • 1,345
  • 4
  • 27
  • 48
  • 1
    Rotation and DIV extent work quite oddly, it varies between browsers I have found. – Orbling Feb 09 '11 at 16:50
  • @Vani: Are you just using IE? In general web applications are developed for all browsers, unless it is for internal use only. – Orbling Feb 09 '11 at 17:53
  • @Orbling Its for internal use.. – Vani Feb 09 '11 at 22:08
  • @Vani: Right, as it was an issue I've long had trouble with - I thought I would demonstrate the problem properly so that others can find it. – Orbling Feb 10 '11 at 01:50
  • @Orbling So what do you think about it .. IS it something we can fix... Because of this my project is getting delayed .... – Vani Feb 10 '11 at 14:14
  • @Vani: Did you read my answer? That explains the problem, and effectively provides the basis of the solution. – Orbling Feb 10 '11 at 14:38

2 Answers2

15

The Dimension Problem with CSS3 Rotation


When a DOM element is rotated using the CSS3 transform properties (or the equivalent browser specific routines), the object is rotated to a given angle, but the computed width and height are left untouched. Presumably because the transformations happen after all other redraw events and the original size variables are left as they were.

Rotation does not alter the actual size of an object, however, in the HTML DOM, all objects must be within a rectangular bounding box; the size of this bounding box will alter to accommodate the new extent of the rotated image.

Routines that calculate the position of elements in the DOM tend to rely solely on the position of the element (left & top), and the size of the element (width & height), as all elements are rectangles, this is fine, the rectangular bounding box is identical to the object itself. When the item is rotated this ceases to be true, so routines no longer work correctly, as the width and height of the bounding box are potentially different to the object itself.

Rotation with Bounding Box

Rotation with Bounding Box

The bounding box width and height is simple enough to calculate mathematically, there was a question some time ago on this topic, with an answer given by casablanca stating the mathematics to calculate the new widths and heights. (He also states how to calculate the new positions, but with CSS rotatation, unless you change the origin of rotation, the left/top stay the same.)

Rectangle Rotation - New Dimensions

The maximum extent is given by the diagonal of a rectangle:

Diagonal of a Rectangle

Based on the code the OP gave above, I have created a little demonstration of this in action - note the size of the bounding box as it rotates, and how the .draggable() container fails to contain the item over the extent to which it is beyond it's original dimensions.

Community
  • 1
  • 1
Orbling
  • 20,413
  • 3
  • 53
  • 64
  • 2
    If it only it were possible to upvote more. What a great answer! – Jason Benson Feb 10 '11 at 01:55
  • @Jason Benson: Thank you very much. It would have been great a lot quicker if SO supported [MathJaX](http://www.mathjax.org/)! (had to write the LaTeX on Math.SE, screenie, save, upload!). – Orbling Feb 10 '11 at 01:59
  • Apologies for the slightly disjoint state of the demonstration code/HTML - it came from elsewhere, altered a few times throughout and was not refactored fully. – Orbling Feb 10 '11 at 02:00
  • @Orbling I tested the code in my aspx page,the image is not rotating.It just moving around the container. – Vani Feb 10 '11 at 14:46
  • @Orbling Square Demo: http://jsfiddle.net/pkHFZ/ Rectangular Demo: http://jsfiddle.net/pkHFZ/2/ .As per my issue,i dont think that space is an issue,because even for a small image,its pushing out of the "div". – Vani Feb 10 '11 at 15:39
  • 1
    @Vani: The problem is the bounding box, not the space. As mentioned in the last paragraph above. `.draggable()` does its `containment` calculations based on the dimensions of the item - these are wrong when rotated, hence it protrudes. To fix that you will need to either do the containment by a custom routine, or create a containing bounding box div that is invisible, sized and moved with the other entry and use that bounding box as the container. – Orbling Feb 10 '11 at 15:49
  • @Orbling Thank you for the answer. One thing i noted is when i add resize ,its not moving out of the div,instead its cutting off the image edges $('#frame .rotatable').resizable().parent('.ui-wrapper').draggable({ containment: 'parent' }); – Vani Feb 10 '11 at 16:32
  • @Vani: Yeah, when you wrap it like that, you get `overflow-hidden` on the contents, so it'll butt up to the edge just the same as before, but the protruding parts will be clipped by the container. If you look at how I create and update the bounding box in the demo code, then use that bounding box as the containment, it might work as desired. – Orbling Feb 10 '11 at 19:16
  • @Orbling I couldn't make it work . I ma using JQueryRotate. I have altered the container size as per ur sample code,but no change.I fi use $('#frame .rotatable').draggable({ containment: 'parent' });,for first time rotation ,the image is thrown out of parent and following rotation are good within the parent.If i use $('#frame .rotatable').resizable({ autoHide: true }).parent().draggable({ containment: 'parent' });,the image corners are cliped by the container but its rotation with in parent. Please give some more information. – Vani Feb 14 '11 at 04:38
  • @Vani: You need to change your HTML structure. `
    ...
    ` Where the `container` is your outer box, the `bounding-box` is the bit you drag, pass them to `$('.bounding-box').draggable({ containment: 'container' })`; the rotated part handled by JQueryRotate should be the `.rotatable` DIV; and you need to continuously resize the `.bounding-box` as it rotates.
    – Orbling Feb 14 '11 at 07:30
  • @Vani: In order to get those fiddles to work, you will need to change the URLs to the actual paths, as they are all relative at the moment (to images/resources on your server, not jsfiddle.net) – Orbling Feb 14 '11 at 14:36
  • @orbling I just posted the code there to show you the logic i am using for this ,it will not work now. http://jsfiddle.net/nqjvw/4/ – Vani Feb 14 '11 at 14:58
  • @Orbling in my JqueryRotate plugin ,if i change this._container.style.top = "15px"; this._container.style.right = "25px"; this._container.style.position = "absolute"; I am able to manage the clipped area's but not completely. Do you think its something do with that .http://wilq32.adobeair.pl/jQueryRotate/Wilq32.jQueryRotate.html .I am sorry for keep bothering you in this issue,i completed my rest of project two weeks before,bse of this issue its hanging in the middle. I really appreciate you time & help in this issue. – Vani Feb 14 '11 at 15:39
0

As an alternative to @Orblings answer that don't require any additional Javascript, Math or calculations.

Instead of making the object both draggable and rotatable, you split it up into a container that is draggable, and a child that is rotatable.

<div class="container">
    <span class="draggable-element">
        <span class="rotatable-element"></span>
    </span>
</div>

By doing this, your draggable element always stay leveled with a fixed bounding box while its only the child elements bounding box that changes. Since this one is not limitted to the container, it can still be outside.

Marcus Lind
  • 10,374
  • 7
  • 58
  • 112