Get relative x and y div after rotation

So, I would like for me to pay more attention to the math class for:

http://i.imgur.com/noKxg.jpg

I have a large div container, and inside this I have some div divs that are rotated.

What I'm trying to do is animate between child divs by moving the Main Div around in the viewport. It would be very simple if I just did it based on simple x / y calculations (top / left), however, when it comes to rotation, my math just breaks down.

I tried a few things and didn't really rip it.

Here a simplified version of my results is sorted far, please feel free to:

http://jsfiddle.net/dXKJH/3/

I really can't figure it out!

[EDIT]

I am going to use this solution as a preference simply because I already worked on how to get the rotate plugin to work with MSIE6 +.

No matter how I say that, although I follow all the mathematical functions and they seem clean, the results are not perfect for pixels, is this something related to calculating the PI? It seems that the more and more spaced apart I make the boxes, the less likely they are to match to the top left? Oddness.

Also can someone remind me what I need to do if the angle is more than 45 degrees, I can’t find the link that I remember from the math class years ago when there were 4 quadrants or something like that ... rr, as I want, I paid more attention .. :-)

Thank you for your help!

+7
source share
3 answers

Well, that’s how I guessed ... I did less to better see where the div ends, and also added scrollbars for this reason.

Important points:

  • Math.sin / Math.cos require radians, not degrees
  • CSS rotates around the middle of the element, not (0, 0) (this applies to both the main div and the div s box; first translate -width / 2 , -height / 2 , rotate, and then translate back)
  • Use parseInt(x, 10) to make sure you are using base 10

Final code: http://jsfiddle.net/pimvdb/dXKJH/10/ . This solution needs hardcoded positions and rotations in HTML, as .css had some quirks with rotating elements.

 $("#div-1").rotate("-10deg"); $("#div-2").rotate("10deg"); $("#div-3").rotate("15deg"); $("#div-4").rotate("75deg"); $("#main").click(function() { console.log($('body').scrollLeft(), $('body').scrollTop()); }); $("a").click(function(e){ goTo($(this).attr("id").substring(4,5)); return false; }); function n(x) { return parseInt(x, 10); } function sin(x) { return Math.sin(x / 180 * Math.PI); } function cos(x) { return Math.cos(x / 180 * Math.PI); } function rotate(x, y, a) { var x2 = cos(a) * x - sin(a) * y; var y2 = sin(a) * x + cos(a) * y; return [x2, y2]; } var offsets = [null, [0,100,-10], [100,200, 10], [300,100, 15], [400,100, 75]].map(function(v) { if(!v) return v; var rotated = rotate(-50, -50, v[2]); rotated[0] += v[0] + 50; rotated[1] += v[1] + 50; return rotated.concat(v[2]); }); function goTo(num){ var obj = $("#div-" + num); var angle = -n(obj.rotate()); var pointX = offsets[num][0] - 500; var pointY = offsets[num][1] - 500; var rotated = rotate(pointX, pointY, angle); var newX = rotated[0] + 500; var newY = rotated[1] + 500; $("#main").animate({rotate: angle + "deg"}, 1000); $("body").animate({scrollLeft: newX, scrollTop: newY}, 1000) } 
+2
source

I would suggest a different approach:

  • Move to div-2 from the initial state (move Main Div using styles left / right)
  • Set the conversion-start of the main Div to the center of view (also the center of div-2)
  • Rotate the main Div to the opposite amount of div-2 (div-2 must be centered correctly)
  • Turn the Main Div back 0 degrees.
  • Move to div-3
  • Set the conversion-start of the main Div to the view center (also the center of div-3)
  • Rotate the main Div to the opposite amount of div-3 (div-3 must be centered correctly)
  • Rinse and repeat

This can be simpler and lead to less complex (more supported) code. Please note that movement and rotation can be animated. In addition, if you use translations instead of left / top styles, this solution will be much more complicated due to transformation changes.

+1
source

It looks like you're trying to mimic the Apple iPhone website: http://www.apple.com/iphone/ . I emulated this method here:

http://jsfiddle.net/Yw9SK/2/ (uses Webkit transitions)

It really does not require a lot of math, do not overdo it. You just need to undo the rotation of the child <div> element and adjust its width / height and offset from the <div> container.

Here's how to do it:

 container width: 500 height: 500 rotation: 0 top: 0 left: 0 child width: 90 height: 90 rotation: 120deg top: 330 left: 0 


  • To ensure proper rotation, the container must receive a negative rotation of the child:

     child rotation: 120deg --> container rotation: -120deg 
  • To have a child center in the view, we need to subtract its width from the width of the container, divide by 2 (to keep it centered), and then subtract any offsets. The same thing happens for height:

     Width Height 500 (container width) 500 (container height) - 60 (child width) - 40 (child height) ---- ---- 440 460 / (divide by 2 / (divide by 2 2 to keep it centered) 2 to keep it centered) ---- ---- 220 230 - 0 (subtract the left: offset) -330 (subtract the top: offset) ---- ---- 220 translateX -100 translateY 


Since the “stage” is in the center of the top of the container, the new transformation will also be centered inside the scene. (This is not much harder to do for a rectangle compared to a square.) Thus, our transformation, which should be applied to the <div> container, is:

 transform: rotate(-120eg) translateX(220px) translateY(-100px) 

Rinse and repeat for the remaining children and go through them accordingly.


This JSFiddle is just an example of how to do this. This is not a very well-designed implantation. A better solution would be to delay the transition or delay the animation (instead of setInterval), and then listen for the events of 'transitionEnd' or 'animationEnd'.

I would definitely recommend NOT trying to calculate new positions and rotations programmatically on the fly (although you can, and then you just need to get these values ​​from the .style property in JS). I would recommend that the translations / rotations be predefined for you in advance (as can be seen from my example, although they should be in CSS) and just apply them in the correct order to the container. This will ensure a quick and smooth transition.

+1
source

All Articles