Jump to content
Search Community

Having trouble understanding smoothOrigin property

ryan_brwn test
Moderator Tag

Recommended Posts

Hey all,

 

Background

I'm trying to understand a little more how svg transform origins, smoothOrigin, and SVGOrigin work.

 

I'm working on an svg animation and I was having trouble with a <path> transforming oddly based of its origin. I know that when using SVG transform origins do not behave the same as they do with regular DOM elements and I realized that GSAP adds some extra sauce to account for this discrepancy (When I inspected the transformed path there's an data-svg-origin attribute applied.)

 

When trying to solve the issue I ran across the smoothOrigin property in the gsap documentation and was able to apply smoothOrigin: false to get my desired result. However, I guess I dont understand how smoothOrigin works because I would have thought smoothOrigin: true would have fixed it.

 

Demo

Here's a minimal demo of the issue I was having and how smoothOrigin: false fixed it.

 

Question

- So my question is, does gsap currently try to account for the svg origin issue by default now (in other words is smoothOrigin:true the default)?

- And was this the cause of my <path> transform origin issue and if so why?

- Also I've read about a gsap featured called SVGOrigin and want to know if it's the same thing as smoothOrigin or if it has a different use.

 

Thanks so much!

 

 

See the Pen 348ed13ae46b4ce70bc20b1f16d755d3??editors=0010 by ryankbrown (@ryankbrown) on CodePen

Link to comment
Share on other sites

Heya!

 

So smoothOrigin shouldn't be needed in your case at all. Smooth Origin is only for when you're animating between positions that have separate centers of transformation (transform origins) It basically moves the origin point to wherever the transformed element has moved to, so that there aren't jumps.

 What you've likely got confused about is that the set call is instant, you can't see that transformation happen, so you can't see that the center of origin is different in that set call than in your tween.

What's actually happening here is this... You're scaling down the arrow head to the top left corner of it's bounding box, then scaling it up from the bottom left. 

With smoothOrigin this 'bottom left' position  is moved to align with the new position of the arrowhead, so when it scales up, it's in a different place, here's a demo.

See the Pen bGmPJoE?editors=0010 by GreenSock (@GreenSock) on CodePen



This is just an added layer of confusion here because you don't need this behaviour at all, there's no need for you to be animating between different origin points. It sounds like you're just trying to scale the arrow up in the right place right?
 

---

 

So let's look at transforms.

 

An origin point is basically the center of rotation or transform. Spinning or rotation is easier to visualise, so let's talk about spinning for now.

You can think of it like if you were to put a pin in a post it note and spin the paper around, the paper would spin around the place where you've put the pin. The origin.

The difference between transformOrigin and SVGOrigin is to do with which bounding box is used for the origin point. You can choose to spin around a point on the element itself, or somewhere on the SVG canvas.

Here -  You can see one is spinning around it's own top left corner, and the other is spinning around the top left corner of the SVG.

 

you can add overflow visible on the SVG to see, I just kept it hidden for now as it's a little tidier

See the Pen YzJoMbK by GreenSock (@GreenSock) on CodePen

 

For your example, all you need to do is animate using the correct center or transformation, so something like this?
 

.from(`.ray__arrow--right`, {
  scale: 0,
  transformOrigin: 'bottom center',
  ease: "none"
})

 
@Carl recently did a video on transformOrigin so that might be a good one to check out if you're still a bit baffled!
 


addendum - in terms of SVG vs HTML, the main thing is that HTML dom elements spin around their own center, whereas SVG elements, by default, spin around the top left corner of the SVG canvas. With GSAP the default is the top left corner of the element itself.

Hope this helps!

  • Like 4
Link to comment
Share on other sites

Ahhhh! So let me try and say back to you what I understood. Let me know if I got it correct.

 

smoothOrigin

Use when you want to apply a tween with a different origin than the previous set or tweened origin and you dont want the new origin to shift the element's transformation from the previous tween at the start of the new tween.

 

SVGOrigin

Normally when specifying transform-origin on an svg element the origin is relative to the SVG's bounding box. Using SVGOrigin calculates the transform origin relative to the specified svg child element. 

 

My Issue

My previous demo (which was a little whack when I went back and looked at it) was using .set() to set the scale but not specifying a transformOrigin, which defaulted to the "top left".

// Issue in the previous code
tl
.set('.ray__arrow--right', { 
	scale: 0
})
.to('.ray__arrow--right', { 
	scale: 1, 
	transformOrigin: "bottom left"
}) 

Then in my .ray__arrow--right tween when arrowhead was scaling in the transformOrigin was defaulted to "top left" from the set (and ignoring or miscalculating my transformOrigin: "bottom left" in the tween?).  Is this correct? Is this what was happening?

 

Solution

So based on your rec, I .set() the proper transform origins to the appropriate arrowheads and viola! (I realized your rec was to use a .from() instead of .set() and a .to() but my production code has to go with the later method.

 

See the Pen eae014d9db1663102cb5e51005a2cca0?editors=1010 by ryankbrown (@ryankbrown) on CodePen

 

 

 

Link to comment
Share on other sites

Not exactly

Quote

 

SVGOrigin

Normally when specifying transform-origin on an svg element the origin is relative to the SVG's bounding box. Using SVGOrigin calculates the transform origin relative to the specified svg child element. 

 

 

SVGOrigin - use the SVG as the reference box for the transform. (spin around a point on the SVG canvas)

 

transformOrigin - use the element itself as the reference box for the transform.  (spin around a point on the element)

 

And not quite

Quote

Then in my .ray__arrow--right tween when arrowhead was scaling in the transformOrigin was defaulted to "top left" from the set (and ignoring or miscalculating my transformOrigin: "bottom left" in the tween?).  Is this correct? Is this what was happening?

 

You had two different transformOrigins, so smoothOrigin was moving the transform to the new origin position. This is the just the purpose of smoothOrigin, Nothing was being ignored or miscalculated.


This might help -
 

 

Quote

 

Solution

So based on your rec, I .set() the proper transform origins to the appropriate arrowheads and viola! (I realized your rec was to use a .from() instead of .set() and a .to() but my production code has to go with the later method.

 

Glad you got it sorted! Seems odd that you can't use from, but if it works it works!

  • Like 1
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...