78

I am creating a rotating earth effect in CSS. I have created the globe in CSS :

body {
  background-color: #111;
}

#earth {
    width: 300px;
    height: 300px;
    background: url(https://web.archive.org/web/20150807125159if_/http://www.noirextreme.com/digital/Earth-Color4096.jpg);
    border-radius: 50%;
    background-size: 610px;
    box-shadow: inset 8px 36px 80px 36px rgb(0, 0, 0),
    inset -6px 0 12px 4px rgba(255, 255, 255, 0.3);
    animation-name: rotate;
    animation-duration: 12s;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
    -webkit-animation-name: rotate;
    -webkit-animation-duration: 12s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-timing-function: linear;
}

@keyframes rotate {
    from { background-position: 0px 0px; }
    to { background-position: 500px 0px; }
}
@-webkit-keyframes rotate {
    from { background-position: 0px 0px; }
    to { background-position: 500px 0px; }
}
<div id="earth"></div>

But it stops and then image resets and starts again. I want it to move smoothly without jerking. Thank you very much!

Unmitigated
  • 76,500
  • 11
  • 62
  • 80
  • I believe you are looking for a parallax scrolling effect? – chiapa Jan 05 '15 at 14:46
  • 2
    That's a neat effect, but I'd be cautious with it. It's fairly choppy on Chrome 39.0.2171.95 m (even with the fix, of course) and creates a noticeable load on a CPU. – Tim M. Jan 05 '15 at 22:29
  • 2
    @TimMedora I don't know why, but its running very smoothly on Firefox 34. On GC. it works better with a small sized image, or with hardware acceleration (HW acc increases memory usage significantly). See here a globe with smaller image: [link](http://jsfiddle.net/yd0bnvtj/). – The Pragmatick Jan 06 '15 at 12:58
  • Surprisingly, it is working very smoothly on IE 10! – The Pragmatick Jan 06 '15 at 13:19
  • 1
    @TimMedora I'm on that Chrome version, and it's pretty smooth. – AStopher Jan 06 '15 at 14:39
  • FWIW, Safari on my Macbook Pro was very smooth, although it showed consistent 20% CPU usage (which isn't terrible, but on a slower machine and/or with more complex animations it would become impractical). IE11 moves smoother but shows dithering on the bright spots of the image. Just goes to show how different each of the rendering engines are. Both question and answers have upvotes from me. – Tim M. Jan 06 '15 at 19:13
  • 1
    Beautiful effect! Runs very well on my old HW/SW (Chromium27 on PuppyLinux 5.2.8 which is an all-in-RAM distro based on Ubuntu 10.04) – DocSalvager Jan 07 '15 at 10:37
  • 1
    I've never seen this effect before - this is awesome! Kudos to you – Blake Frederick Jan 22 '15 at 22:48

4 Answers4

94

In background-position: 500px 0px; replace 500px with 610px, which is the background-size

body {
  background-color: #111;
}
#earth {
  width: 300px;
  height: 300px;
  background: url(https://web.archive.org/web/20150807125159if_/http://www.noirextreme.com/digital/Earth-Color4096.jpg);
  border-radius: 50%;
  background-size: 610px;
  box-shadow: inset 8px 36px 80px 36px rgb(0, 0, 0), inset -6px 0 12px 4px rgba(255, 255, 255, 0.3);
  animation-name: rotate;
  animation-duration: 12s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  -webkit-animation-name: rotate;
     -webkit-animation-duration: 12s;
     -webkit-animation-iteration-count: infinite;
     -webkit-animation-timing-function: linear;
}
@keyframes rotate {
  from {
    background-position: 0px 0px;
  }
  to {
    background-position: 610px 0px;
  }
}
@-webkit-keyframes rotate {
  from {
    background-position: 0px 0px;
  }
  to {
    background-position: 610px 0px;
  }
}
<div id="earth"></div>
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
The Pragmatick
  • 5,379
  • 27
  • 44
  • 6
    upvoted, it was a simple issue of having missed one of the position items, if you downvoted please say why so the answerer can improve the answer. – Mauro Jan 05 '15 at 14:41
  • 2
    I don't mean to be just a critic but, isn't the earth supposed to rotate in the same direction all the time? In this answer the rotation stops and starts backwards, to then stop and restart forward – chiapa Jan 05 '15 at 14:48
  • Ah, much better now :) – chiapa Jan 05 '15 at 14:52
  • Thanks for pointing out. I was copying pasting browser specific codes and mistakenly copied that. In GC it worked fine earlier too, so I couldn't see the problem. Thank You. **Chiapa** and **Kaiido**. – The Pragmatick Jan 05 '15 at 14:55
47

The problem in your code is that the imagesize (610px) and the animation's offset (500px) differ and at the reset of the animation it hops (110px).

A simple trick I like to use instead of defining the animation offset in pixel: Define it in percentages.
Instead of telling it to move 610px, I tell it to move 100%.

The bonus of the 100% method is that if you cange the picture, you dont have to alter all hardcoded values in your CSS, which, IMO, should be the prefered method.

Please note: It seems like moving from 0 to -100% creates a hop. Because we need the rotation to go in the right direction, I tried starting 100% and move it to 0, but at this point the image no longer exists.

@keyframes rotate {
   from { background-position:  100%  0; }
   to {   background-position:    0   0; }
}

Here is the snippet, but with 100% instead of a pixelvalue:
* Please note: The animation still hopped, but I can't test new code because the image no longer exists. The logic works, but this implementation seems not to. The following code is only a demo with the TS's code.

body {
  background-color: #111;
}
#earth {
  width: 300px;
  height: 300px;
  background: url(https://web.archive.org/web/20150807125159if_/http://www.noirextreme.com/digital/Earth-Color4096.jpg);
  border-radius: 50%;
  background-size: 610px;
  box-shadow: inset 8px 36px 80px 36px rgb(0, 0, 0), inset -6px 0 12px 4px rgba(255, 255, 255, 0.3);
  animation-name: rotate;
  animation-duration: 12s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}
@keyframes rotate {
   from { background-position:  100%  0; }
   to {   background-position:    0   0; }
}
<div id="earth"></div>
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
Martijn
  • 15,791
  • 4
  • 36
  • 68
  • 4
    Actually this was the way it was meant to be done. (+1) – The Pragmatick Jan 05 '15 at 16:28
  • 11
    This keeps jumping from China to Mexico on my browser (Safari). – 200_success Jan 06 '15 at 11:43
  • I don't have Safari here, tested this in FF and Chrome as the code seems to be optimised for those :) If you know the solution, feel free to edit the post (or reply here and I'll add it) – Martijn Jan 06 '15 at 11:54
  • 2
    It jumps from China to Mexico for me too. FF 31.2.0 on RHEL 6 – Holloway Jan 06 '15 at 12:19
  • 4
    Hey it isn't even working on FF 34.0.5 (Windows 8)! Your solution is working only on GC. –  Jan 06 '15 at 12:36
  • The percentage solution works, crossbrowser. I know this because I do this on a regular basis for websites I build/animate. If there is an error, it's because of the current css. I've only added the snippet for demo purposes, the solution remains the same :) – Martijn Jan 06 '15 at 12:49
  • I've just checked it in fullpage mode, it hops for me to. The in-page [run snippet] works fine. If I got some spare time, I'll jsfiddle it – Martijn Jan 06 '15 at 12:51
  • 6
    For me both embedded and fullpage are jumping. But why is mine working on Firefox? This's Strange. – The Pragmatick Jan 06 '15 at 13:12
  • I have no clue as to why it's not working. I do this all the time, it should. Again, Don't have the time now to debug this, the code is just for demo purposes, the theory remains the same. – Martijn Jan 06 '15 at 14:27
  • 1
    This Works for me if I change `-100%` to `100%`. IE11 on Win 7 – Ricardo Souza Jan 08 '15 at 09:59
0

body {
  background-color: #111;
}

#earth {
    width: 300px;
    height: 300px;
    background: url(https://zippin.online/wp-content/uploads/2022/02/registration-bg.png);
    border-radius: 50%;
    background-size: 610px;
    box-shadow: inset 8px 36px 80px 36px rgb(0, 0, 0),
    inset -6px 0 12px 4px rgba(255, 255, 255, 0.3);
    animation-name: rotate;
    animation-duration: 12s;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
    -webkit-animation-name: rotate;
    -webkit-animation-duration: 12s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-timing-function: linear;
}

@keyframes rotate {
    from { background-position: 0px 0px; }
    to { background-position: 500px 0px; }
}
@-webkit-keyframes rotate {
    from { background-position: 0px 0px; }
    to { background-position: 500px 0px; }
}
<div id="earth"></div>
0
#earth {
    transform: rotate(23.5deg);
}

don't forget update 'axial tilt earth' :-)