Jump to content
Search Community

How to to move an object to absolute coordinates determined by another object

S. Greft test
Moderator Tag

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

I have implemented a simple GSAP SVG drag/drop snippet where a user can drag an SVG object o1, and when o1 is dropped while overlapping another SVG object o2 (tested with hitTest), o1 moves until it "docks" onto o2 (with TweenLite.to).

 

I managed to do this with the help of getBoundingClientRect. I use the function to determine the coordinates of o2, substract the <svg> elem.getBoundingClientRect.x/y coordinates and use the result as input for TweenLite.to.

 

I have some questions:

 

Is my approach the recommended way to move an object to absolute coordinates determined by another object?

 

Is there an alternative to using getBoundingClientRect?

 

I assume getBBox cannot be used? getBBox.x and .y are always 0. I think it is because TweenLite.set and TweenLite.to use transforms. Correct?

 

Is getBoundingClientRect an established method? According to
https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect#Browser_compatibility
it is not supported by all major browsers?

Link to comment
Share on other sites

getBoundingClientRect won't provide you accurate position inside the svg, it will only you position according to screen. Ya it is really well supported, just some browsers don't x and y properties but you can use left and top instead.

 

Here is demo by @OSUblake showing how you can use getBBox using a custom function to get correct position inside svg.

 

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

 

Similar thread if you wanna read more:

 

  • Like 1
Link to comment
Share on other sites

But the custom getBBox function looks very complicated.

 

So, why not just determine the position of o2 like that:

 

var o2Rect = o2.getBoundingClientRect;

var svgRect = svgContainer.getBoundingClientRect; // the <svg> container element

var x = o2Rect.x - svgRect.x;

var y = o2Rect.y - svgRect.y;

 

This seems to be a very simple and working solution. Any objections / caveats?

 

 

 

And, if the custom getBBox function is to be preferred for some reason, then another question arises:

 

It seems to me that determining the correct position of an SVG element is fundamental. So, why is the custom getBBox function not part of the specification, or at least of a library, i.e. GSAP?

Link to comment
Share on other sites

As OSUblake said:

If you have an element at 0,0 and tween it to 100,100 using x and y, and then get it's bounding box, it will say it's still at 0,0. This goes for all transforms, x, y, scale, rotation, etc. Not very useful considering most animations use transforms.

 

So, if you want to move an SVG object o1 to absolute coordinates determined by another SVG object o2, why not just determine the position of o2 like that:

var o2Rect = o2.getBoundingClientRect;

var svgRect = svgContainer.getBoundingClientRect; // the <svg> container element

var x = o2Rect.x - svgRect.x;

var y = o2Rect.y - svgRect.y;

 

This seems to be a very simple and working solution. Any objections / caveats?

Link to comment
Share on other sites

26 minutes ago, S. Greft said:

But in my code getBBox.x and .y are always 0. And I don't see what I am doing wrong

 

Did you check the demo I posted? It uses a custom function to get bounding box similar to getBoundingClientRect but with respect to svg co-ordinate system only.

  • Like 2
Link to comment
Share on other sites

Yes, I checked it and changed my reply  (see above). But you seem to have viewed the original reply.

 

So, this is my new reply:

 

 

But the custom getBBox function looks very complicated.

 

So, why not just determine the position of o2 like that:

 

var o2Rect = o2.getBoundingClientRect;

var svgRect = svgContainer.getBoundingClientRect; // the <svg> container element

var x = o2Rect.x - svgRect.x;

var y = o2Rect.y - svgRect.y;

 

This seems to be a very simple and working solution. Any objections / caveats?

 

And, if the custom getBBox function is to be preferred for some reason, then another question arises:

 

It seems to me that determining the correct position of an SVG element is fundamental. So, why is the custom getBBox function not part of the specification, or at least of a library, i.e. GSAP?

 

 

 

Link to comment
Share on other sites

  • Sahil changed the title to How to to move an object to absolute coordinates determined by another object

I merged your questions to keep discussion in single thread.

 

getBoundingClientRect gives you the position of element with respect to viewport. You don't see any problem with that because you are not using viewbox. Viewbox is attribute determines the SVG's internal co-ordinate system.

 

In following demo you will see that viewbox is 200x200 but svg element is 500x500, so basically SVG is scaled up. Now when you use the getBoundingClientRect the horizontal distance between both rects is 250. Which is incorrect.

 

See the Pen NOmrJP?editors=1010 by Sahil89 (@Sahil89) on CodePen

 

getBBox ignores any transforms. Though I don't know why it isn't part of library or spec. You can read this another thread to learn more about all SVG weirdness:

 

  • Like 5
Link to comment
Share on other sites

5 hours ago, S. Greft said:

But the custom getBBox function looks very complicated.

 

It does exactly what is necessary to calculate the bounds. Nothing more. Nothing less. It is the same calculation that a canvas based library would use.

 

5 hours ago, S. Greft said:

And, if the custom getBBox function is to be preferred for some reason, then another question arises:

 

It seems to me that determining the correct position of an SVG element is fundamental. So, why is the custom getBBox function not part of the specification, or at least of a library, i.e. GSAP?

 

It's not the preferred solution, nor is it needed in every situation. It's something I wrote to solve a particular problem.

 

Feel free to use .getBoundingClientRect() if your SVG does not have a viewBox. 

 

 

  • Like 2
Link to comment
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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...