Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
swampthang

Get rotated position of element

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

The pen shows a typical way of getting the x/y coordinates for a rotated element. I can use this, but wondering if there might be some hidden gem in GSAP that calculates these points already or, if there might be a faster way to get these values...

See the Pen QrBMqm by swampthang (@swampthang) on CodePen

Share this post


Link to post
Share on other sites

It's pretty easy if you can get the matrix. SVG provides the easiest way to get a matrix. 

 

a = topLeft;

b = topRight;

c = bottomRight;

d = bottomLeft;

 

var r = element.getBBox(); 
var p = svg.createSVGPoint(); 
      
var matrix = svg.getScreenCTM().inverse().multiply(element.getScreenCTM()); 

p.x = r.x;
p.y = r.y;
var a = p.matrixTransform(matrix);

p.x = r.x + r.width;
p.y = r.y;
var b = p.matrixTransform(matrix);

p.x = r.x + r.width;
p.y = r.y + r.height;
var c = p.matrixTransform(matrix);

p.x = r.x;
p.y = r.y + r.height;
var d = p.matrixTransform(matrix);

 

 

A demo where I use that to match up the positions of different SVG elements.

 

See the Pen ZxVmyx by osublake (@osublake) on CodePen

 

 

  • Like 3

Share this post


Link to post
Share on other sites

Awesome, Blake. Is there a way to get that to work for elements inside a foreignObject?

Share this post


Link to post
Share on other sites
40 minutes ago, swampthang said:

Awesome, Blake. Is there a way to get that to work for elements inside a foreignObject?

 

Hmmm... I dunno. Are you still doing electron based apps?

 

What I did above will probably only work for regular SVG elements. However, a new feature is the DOMMatrix, which looks like it was added to Chrome 61. I haven't tried it yet, but that should work for any type of any element. *In theory*

https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix

 

But if you can get a 2d matrix...

matrix(a,b,c,d,e,f);

 

Then you should be able to get a transformed corner like this. You of course would need to do that for every corner.

var x = matrix.a * corner.x + matrix.c * corner.y + matrix.e;
var y = matrix.b * corner.x + matrix.d * corner.y + matrix.f;

 

 

 

  • Like 3

Share this post


Link to post
Share on other sites
8 hours ago, OSUblake said:

Are you still doing electron based apps?

 

Yes. That's what this is gonna be used in. DOMMatrix with DOMPoint looks promising if it will work in the version of Chromium in the version of Electron I'm using for this app. Thanks!

Share this post


Link to post
Share on other sites

Thanks, Blake. I know this is really ugly but I quickly put together something that will give me the data I need, ie, crop-points, pad-points, render-size, etc.

 

See the Pen ZoMQEr?editors=1010 by swampthang (@swampthang) on CodePen

 

For what it's worth, the reason I need all this is because of the way complex filters work in FFMPEG. Order is critical. A complex filter applies each filter and then "sends the results" to the next filter in the chain. So, for example, if a PNG sequence, represented by the green box in the pen, gets rotated, dragged to a new position and resized (in my Electron app) in order to render the sequence to an MOV file, I have to first scale it, then rotate it, then crop it to fit the stage and then add padding where appropriate. Using GSAP to allow manipulation of all these parameters is really an awesome thing. I love this library the more I use it!

Edited by swampthang
Added explanation

Share this post


Link to post
Share on other sites

That works! 

 

The nice thing about using a matrix to get the coordinates is that it will handle other transforms like scale. Maybe @GreenSock will consider adding transform methods like that to the CSSPlugin. :-D

  • Like 1

Share this post


Link to post
Share on other sites
1 hour ago, OSUblake said:

Maybe @GreenSock will consider adding transform methods like that to the CSSPlugin

 

Are you talking about getCorners(), getPoint(), etc.? I couldn't quite tell if you were joking or if you thought there was a good place in CSSPlugin for some new features related to transforms. Open to suggestions - I just always have to be careful about file size and how many people might actually use such features (cost/benefit ratio). 

Share this post


Link to post
Share on other sites

Sometimes I need the matrix, but I hate splitting up a string, so I was thinking it might be helpful if there was a way to get the matrix values from GSAP. And if there was a way to transform a point from that matrix, even better.

 

Didn't you have something like that in the CSSTransform tool?

 

Share this post


Link to post
Share on other sites
58 minutes ago, OSUblake said:

Sometimes I need the matrix, but I hate splitting up a string, so I was thinking it might be helpful if there was a way to get the matrix values from GSAP. And if there was a way to transform a point from that matrix, even better.

 

Didn't you have something like that in the CSSTransform tool?

 

 

Sshhh. There is no "CSSTransform" tool (officially) ;)

 

It's not something that many people showed interest in, and it's a very tricky thing that could turn into a bit of a nightmare to support so it was never released. If it becomes a popular request, I'll definitely consider re-investing time into that eventually.

Share this post


Link to post
Share on other sites

The main thing I need is a quick, reliable way to get the x/y values for each corner of a rotated element's bounding box. 

Share this post


Link to post
Share on other sites
7 hours ago, OSUblake said:

 

The nice thing about using a matrix to get the coordinates is that it will handle other transforms like scale

 

I forked and am trying to factor in scaling the box in another codepen. Now I see what you're talking about, Blake. Not a simple task.

Share this post


Link to post
Share on other sites

Can do it by just resetting the width and height first. Ok, I know that's cheating but it'll do for now. I added a scale field to the settings. Changing any field value will reset everything...

 

See the Pen ELeLzB?editors=1010 by swampthang (@swampthang) on CodePen

 

Share this post


Link to post
Share on other sites

Here's your matrix. Then just transform the points like I showed above.

 

const cos = Math.cos(rotation);
const sin = Math.sin(rotation);
  
matrix.a = cos * scaleX;
matrix.b = sin * scaleX;
matrix.c = -sin * scaleY;
matrix.d = cos * scaleY;
matrix.e = x - matrix.a + matrix.c;
matrix.f = y - matrix.b + matrix.d;

 

 

See the Pen QrVxee by osublake (@osublake) on CodePen

 

  • Like 4

Share this post


Link to post
Share on other sites
4 hours ago, GreenSock said:

 

Sshhh. There is no "CSSTransform" tool (officially) ;)

 

It's not something that many people showed interest in, and it's a very tricky thing that could turn into a bit of a nightmare to support so it was never released. If it becomes a popular request, I'll definitely consider re-investing time into that eventually.

 

 

I can appreciate the difficulty and the amount of support it would involve, but it still has a lot of neat features. The spinning dot wheel demo you made with that tool is really cool. You should make that into a coding challenge. I'd like to see how many people could actually do that.

  • Like 3

Share this post


Link to post
Share on other sites
1 hour ago, OSUblake said:

Here's your matrix.

 

Awesome, Blake! Much simpler than my convoluted approach. Of course, it helps to fully understand the matrix. That gets me well on the road to a much more respectable solution. Thanks again!

 

  • Like 1

Share this post


Link to post
Share on other sites

Understanding how matrices work probably isn't too important. I would focus on how and when to use them. 

 

Using an SVG Matrix. The trick is doing stuff in the correct order.

 

matrix = svg.createSVGMatrix()
  .translate(X, Y)
  .rotate(R)
  .scaleNonUniform(SX, SY);

 

 

See the Pen pVOQJv by osublake (@osublake) on CodePen

 

 

 

 

 

  • Like 3

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 


  • Recently Browsing   0 members

    No registered users viewing this page.

×