Jump to content
Search Community

Circular motion

robbue 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

Hello robbue,

 

If you look at this Topic: Rotating items around a rectangle

 

You will see how they discuss animating an element around a path..

 

Here is a cool example by Rodrigo, that shows it in action.. you could fork it and modify it to your needs to make the path more circular:

 

See the Pen kjmDo by rhernando (@rhernando) on CodePen

 

Also here is a link to the BezierPlugin Docs

 

Does that help? :)

  • Like 2
Link to comment
Share on other sites

Yeah, a Bezier path like Jonathan mentioned is certainly a good way.

 

Another "trick" involves adding another DOM element into the mix:

 

http://codepen.io/GreenSock/pen/okEcs

 

Basically the arm rotates one way while the box rotates the other (keeping it vertically oriented)

This technique is great for building ferris wheels: http://codepen.io/GreenSock/pen/wBbKs ;)

  • Like 6
Link to comment
Share on other sites

  • 1 year later...

Actually, with SVG it is even much easier than wrapping an element. You can use the "transform" attribute of SVG to apply multiple Transforms.
The new GSAP 18 can easily tween all parameters in those transform statements and also offers the cylce attribute for the stagger-functions.

 

Imagine this is the SVG object, just 4 small black boxes placed at the center.

<svg width="300" height="300">
  <g transform="translate(125,125)">
  <rect width="50" height="50"/>
  <rect width="50" height="50"/>
  <rect width="50" height="50"/>
  <rect width="50" height="50"/>
  </g>
</svg>

This code will let all boxes circulate like on a ferris wheel, rotating with the radius of 100 around the center they were placed at:

var radius = 100;
TweenMax.staggerFromTo('rect',4,{
  cycle: {
    attr:function(i) {
      var r = i*90;
      return {
        transform:'rotate('+r+') translate('+radius+',0) rotate('+(-r)+')'
      }      
    }
  }  
},{
  cycle: {
    attr:function(i) {
      var r = i*90+360;
      return {
        transform:'rotate('+r+') translate('+radius+',0) rotate('+(-r)+')'
      }      
    }
  },
  ease:Linear.easeNone,
  repeat:-1
});

The cycle attribute is used to shift the rotation 90° further for each box.

 

Here's a codepen:

See the Pen ZWOZBb by anon (@anon) on CodePen

  • Like 4
Link to comment
Share on other sites

Great job and use of cycle Ninili :D

 

Looks like

See the Pen ZWOZBb by anon (@anon) on CodePen

doesn't rotate right in IE11 on Windows 7 (64-bit), but it looks ok on latest Firefox and Chrome. I didn't check MS Edge yet.

 

I wonder if it doesn't rotate in IE11 properly is due to the way transform-origin works or doesn't work properly on SVG in IE.

 

Maybe GSAP svgOrigin can help with this, or in that case maybe GSAP need to be applied with x and rotation properties instead of the transform function string?

 

Taken from the GSAP CSSPlugin Docs:

 

http://greensock.com/docs/#/HTML5/GSAP/Plugins/CSSPlugin/

  • svgOrigin
    [Only for SVG elements] Works exactly like transformOrigin but it uses the SVG's global coordinate space instead of the element's local coordinate space. This can be very useful if, for example, you want to make a bunch of SVG elements rotate around a common point. You can either define an svgOrigin or a transformOrigin, not both (for obvious reasons). So you can do TweenLite.to(svgElement, 1, {rotation:270, svgOrigin:"250 100"}) if you'd like to rotate svgElement as though its origin is at x:250, y:100 in the SVG canvas's global coordinates. Units are not required. It also records the value in a data-svg-origin attribute so that it can be parsed back in. svgOrigin doesn't accommodate percentage-based values.

    See the Pen 06716224865c2c536cee5b4222d771ee by GreenSock (@GreenSock) on CodePen

    .

:)

  • Like 2
Link to comment
Share on other sites

That pen is quite clever. :)

 

Unfortunately, I'm seeing the same thing in Edge as Jonathan mentioned about IE11. I'm also curious about svgOrigin fixing this issue since MS never wants to play nicely with the other kids.

 

I'm debating who I should stare at angrily today about their handling of SVGs - MS or Adobe Illustrator.  :x  :-D  

  • Like 2
Link to comment
Share on other sites

Thank you for the nice feedback :)

 

Yes, IE behaves differently, again!

 

IE seems to shorten translate-attributes in SVG by ommiting the y coordinate if it's value is 0, so "translate(x 0)" becomes "translate(x)".

Setting the second parameter of translate to anything other than 0 solves the problem.

I have updated the codepen to use "translate(-radius, 0.1)" to circumvent that not-so-funny behaviour of IE.

  • Like 1
Link to comment
Share on other sites

Now a client asked for an animation where some items, arranged on a circle, should be rotated around while, of course, staying upright, because underneath each icon, there was a description.

I didn't want to re-write the whole SVG to use my old function, I wanted to rotate alle the icons just as they were, from their initial position in a rotating manner.

 

This is how it all worked out, again usign the wonderful cycle routine:

See the Pen BKQJor by anon (@anon) on CodePen

 

...and using some pen and paper

  • Like 2
Link to comment
Share on other sites

  • 4 years later...
  • 1 year later...

@zzkevinlim the 2 recent solutions above are GSAP 3 solutions. :)

 

There are a bunch of ways you could accomplish this even without MotionPathPlugin. Like put it in a container <div>, set its transformOrigin to the radius, animate the rotation and counter-rotate the rotation of the inner element. 

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

 

If you have quadratic bezier data, you can translate it into cubic bezier data with this helper function: 

function quadToCubic(points) {
  let cubic = [],
      l = points.length - 1,
      i = 1, 
      a, b, c;
  for (; i < l; i+=2) {
    a = points[i-1];
    b = points[i];
    c = points[i+1];
    cubic.push(a, {x: (2 * b.x + a.x) / 3, y: (2 * b.y + a.y) / 3}, {x: (2 * b.x + c.x) / 3, y: (2 * b.y + c.y) / 3});
  }
  cubic.push(points[l]);
  return cubic;
}

And then plug that into a regular MotionPath animation. Here is a fork:

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

 

Does that answer your question? 

  • Like 5
Link to comment
Share on other sites

1 hour ago, GreenSock said:

@zzkevinlim the 2 recent solutions above are GSAP 3 solutions. :)

 

There are a bunch of ways you could accomplish this even without MotionPathPlugin. Like put it in a container <div>, set its transformOrigin to the radius, animate the rotation and counter-rotate the rotation of the inner element. 

 

 

 

If you have quadratic bezier data, you can translate it into cubic bezier data with this helper function: 


function quadToCubic(points) {
  let cubic = [],
      l = points.length - 1,
      i = 1, 
      a, b, c;
  for (; i < l; i+=2) {
    a = points[i-1];
    b = points[i];
    c = points[i+1];
    cubic.push(a, {x: (2 * b.x + a.x) / 3, y: (2 * b.y + a.y) / 3}, {x: (2 * b.x + c.x) / 3, y: (2 * b.y + c.y) / 3});
  }
  cubic.push(points[l]);
  return cubic;
}

And then plug that into a regular MotionPath animation. Here is a fork:

 

 

 

Does that answer your question? 


Yes, thankyou so much!

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