Moving an element along a circle

It all started a few months ago, when Chris Coyier casually asked me how would I move an element along a circle, without of course rotating the element itself. If I recall correctly, his solution was to use multiple keyframes, for various points on a circle’s circumference, approximating it. I couldn’t think of anything better at the time, but the question was stuck in the back of my head.

3 months ago, I came up with a first solution. Unfortunately, it required an extra wrapper element. The idea was to use two rotate transforms with different origins and opposite angles that cancel each other at any given time. The first transform-origin would be the center of the circle path and the other one the center of the element. Because we can’t use multiple transform-origins, a wrapper element was needed.

So, even though this solution was better, I wasn’t fully satisfied with it due to the need for the extra element. So, it kept being stuck in the back of my head.

Recently, I suggested to www-style that transform-origin should be a list and accept multiple origins and presented this example as a use case. And then Aryeh Gregor came up with this genius idea to prove that it’s already possible if you chain translate() transforms between the opposite rotates.

I simplified the code a bit, and here it is:

With the tools we currently have, I don’t think it gets any simpler than that.

  • http://twitter.com/ckor Andrew Ckor

    Hahah this translate solution is really SMAAAART!!!

  • Anonymous

    Simply brilliant!

  • http://twitter.com/chriscoyier Chris Coyier

    That’s so crazy awesome. I barely even understand it. =)

    I think back at the time I was asking because I was perturbed that you couldn’t animate/transition two different properties with different easing. I thought if you could animate the top position with ease-in and the left position with ease-out you could animate something along a curve. 

    It looks like you can now do that: http://dabblet.com/gist/1776935

    Back then, I was driven to doing it through jQuery, which did allow it. And ended up with: http://css-tricks.com/examples/Circulate/

  • Shawtie

    Uh, how did you embed your dabblet here? Mind === blown.

  • http://www.musings.it/ Federica

    Wow! This is nice, elegant and smart! My congratulations to you all! I have always something new to learn, and this is the best part of doing this work, thank you :)

  • Binyamin

    Rotating ball in high speed will imaginate like a spinner http://dabblet.com/gist/1778140/

  • Anonymous

    Oh wow! This is so intelligent. And clean! 

  • Anonymous

    Again, with your ninja tricks. I can/could no envision this without JQuery…
    Outstanding

  • http://www.designbyfront.com/ Chuck Neely

    Another version for a loading animation. Forgive the repetition of html code, :before and :after weren’t playing ball, but you get the idea. Seems to run smoothest in firefox for me..  http://dabblet.com/gist/1779040

  • Binyamin

    @twitter-14524173:disqus  you might a bet clean-up your CSS, http://dabblet.com/gist/1779346

  • http://www.designbyfront.com/ Chuck Neely

    hehe I totally agree, can be cleaned up a lot and if I was going to use it i’d refactor it to use :before and :after, just testing the proof of concept  :)

  • Binyamin

    Here is an updated CSS with :nth-child() http://dabblet.com/gist/1779479

  • http://leaverou.me Lea Verou

    Yeah, you can, and it was part of my recent efforts. Not with the predefined keywords, but with cubic beziers with values 0,.5,1 so that they form arcs of a circle. The problem with that is that then you can’t control the easing itself, because you’re using it for the animation path.

  • http://leaverou.me Lea Verou

    Just put it in an iframe, lol

  • Anonymous

    Great stuff Lea, super sexy smart….  (the css is pretty good too!!)

  • http://oirsworld.com/2012/02/rotating-css-elements-have-some-fun-with-css/ Rotating CSS elements – have some fun with CSS! | Oirs World

    [...] February 9, 2012Posted in: CSS Tutorials, Web Design I read a great article today written by Lea Verou, a CSS3 master, about rotating [...]

  • http://web-design-weekly.com/2012/02/10/web-design-weekly-30/ Web Design Weekly #30 | Web Design Weekly

    [...] Moving an element along a circle (lea.verou.me) [...]

  • http://blog.loicg.net/autour-dun-cafe/la-veille-du-week-end-vingt-quatrieme/ La veille du week-end (vingt-quatrième) | LoïcG

    [...] Déplacer un élément le long d’un cercle en CSS3: #fdw #animations #css3 #translate : via @LaFermeDuWeb [...]

  • http://twitter.com/sebmarkbage Sebastian Markbåge

    Yea you can use different timing functions as I described here: http://blog.calyptus.eu/seb/2011/09/csspathanimation/

    However, the lack of hardware acceleration on left/top makes this less desirable than just using two elements.

    This project can calculate all this stuff for you on any arbitrary curve: http://csspathanimation.calyptus.eu/

    If you want to use it on a single elements, just replace translateX/Y with left/top properties and apply the animations on a single element.

    This project uses a constant speed because that’s the base problem that has been solved. It would be easy to adjust the math to use an arbitrary easing as well.

    Of course you wouldn’t manually do these calculations so it’d be better if this was in the spec…

    http://lists.w3.org/Archives/Public/www-style/2011Sep/0295.html

  • Natan Shalva

    Thenks !

  • http://twitter.com/dharmaone jouni helminen

    Nice, for a circle shape that’s really elegant. Something I really miss from Flash though is the ease of animating things on a freeform motion path. Came across this recently 
    http://csspathanimation.calyptus.eu/ - It takes an SVG path and converts that to CSS keyframes

  • Roman Cortes

    Lea, when I was interviewing job candidates with CSS3 animations expertise, I usually asked how to do this as one of my questions/puzzles. It was a good test item as it was not published online, but now I need to create a new one :)

    Good job!

    You should try to add more rotations/translations and different multiples of 360 degrees for each one. You could achieve really interesting complex motions this way, and with very long periods if the 360 degrees multiples you use are coprime when divided by 360.