Jump to content


Problem with initially set transform matrix and transformOrigin (CSS)

Recommended Posts

Hey GSAP enthusiasts, I have a problem with the following scenario:


I have two image elements:

.el {
  position: absolute;
  width: 100px;
  height: 100px;  
.el1 {
  transform: matrix(1, 0, 0, 1, 100, 100);  

.el2 {
  transform-origin: 0 0;
  transform: matrix(0, 1, -1, 0, 400, 100);

The second element "el2" has an initial rotation applied and also the transformOrigin set.


Now I use gsap to animate both elements like this:

gsap.to('.el', {
  delay: 2, repeat: -1, yoyo: true,
  transformOrigin: '50% 50%',
  scale: 2


When running in the browser I see the second element "el2" making a jump to the right, before the animation starts.

I know that it's not the best practice to set transforms/origin in CSS instead of initialising these properties via gsap.set(...).

But in my scenario the code (Markup and CSS) is being generated, so I don't have control over it. 

Is there anything I am missing or is this an unsupported edge case?


(Not 100% sure if this comment might be related: 



Thanks in advance and keep up the amazing work. (BTW: loving the new ScrollTrigger :)


See the Pen yLeONrE by simonwidjaja (@simonwidjaja) on CodePen

Link to comment
Share on other sites

Hey Simon. There's literally nothing that GSAP could do to fix this jump because in one instant you want it to have a transformOrigin of 0 0 and the next instant you want it to have a transformOrigin of 50% 50%. Does that make sense?


Are you wanting to animate the transformOrigin from the old value to the new one? If so, will the start and end values always be known in the JS or can the start value be different?


15 minutes ago, SimonWidjaja said:

Not 100% sure if this comment might be related

That's a bit dated. GSAP 3 doesn't use matrices by default. 

Link to comment
Share on other sites

Thanks Zach for the feedback. I was afraid so...

I basically just want the element to scale around its current center (whatever that may be).

So let's assume I want to achieve that by getting rid of the transformOrigin in CSS. I would have to alter the matrix transform accordingly, right? Do you have any hint how to do that the right way?


.el2 {
  transform: matrix(0, 1, -1, 0, 300, 100);

That would do the trick. But how can I safely alter the matrix like this so that get to these values even if there are more complex rotations etc involved? Are there any good libraries out there you can recommend?


Thanks again!

Link to comment
Share on other sites

Sure, here's a helper function that you can feed elements to (and the new origin) and it'll adjust their x/y values to make it appear seamless: 

function smoothOrigin(targets, origin) {
  gsap.utils.toArray(targets).forEach(target => {
    let bounds1 = target.getBoundingClientRect();
    gsap.set(target, {transformOrigin: origin});
    let bounds2 = target.getBoundingClientRect();
    gsap.set(target, {
      x: "+=" + (bounds1.left - bounds2.left),
      y: "+=" + (bounds1.top - bounds2.top)

A fork of your demo:

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


Does that help? 

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