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/

    • 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://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

  • Shawtie

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

    • http://leaverou.me Lea Verou

      Just put it in an iframe, lol

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

    • 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

  • Anonymous

    Oh wow! This is so intelligent. And clean! 

  • Anonymous

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

  • Anonymous

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

  • Pingback: Rotating CSS elements – have some fun with CSS! | Oirs World

  • Pingback: Web Design Weekly #30 | Web Design Weekly

  • Pingback: La veille du week-end (vingt-quatrième) | LoïcG

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

  • Akshay

    Dunno why but the dabblet solution isn’t working for me :(

    • http://lea.verou.me/ Lea Verou

      WebKit has imposed an additional restriction on animation shorthand syntax since then: The animation-name needs to be first, although the spec does not mandate any such restriction. I fixed the dabblet now and it should be working.

  • http://twitter.com/micjamking Mike King

    This is insanely clever! Great Job.

  • Robert K

    Hi Lea. Just to let you know I linked to your blog post on STackoverflow because it’s a nice example of a rotating element purely by using CSS3 animation… I also added you as the author of this code and linked back to this blog post.

  • Pingback: 5 Use Cases for Icon Fonts | Web Development, Search Engine Optimization, Social Media Marketing Guru

  • Pingback: 5 Use Cases for Icon Fonts | Lunarium Design

  • Pingback: 5 Use Cases for Icon Fonts

  • Pingback: 5 Use Cases for Icon Fonts | CSS-Tricks | Free Tattoo Font Generator Software For Unique Personalized Tattoo Designs

  • Pingback: 5 Use Cases for Icon Fonts « My Portfolio Design

  • Pingback: Moving an element along a circle | OTIS Web Workshop

  • http://www.facebook.com/david.puerto David Puerto

    I am relieved to have found this. I’m just wrapping my head around some things that are possible with CSS3 and this + Sebastian’s reply have made for a good pairing towards coming up with a better solution for an interface I am working on. Bravo!