Reputation: 91
I have a project where I am creating some planets and they need to rotate. I am a beginner currently in school. I found some code that rotates but It starts to skip. The alternative is to have it alternate in rotating but then that doesn't look right.
How can I fix this with CSS?
.earth {
width: 300px;
height: 300px;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
overflow: hidden;
border-radius: 50%;
box-shadow: 0 0 20px 20px #000 inset, 0 0 20px 2px #000;
}
.earth:after {
position: absolute;
content: "";
top: 0;
bottom: 0;
left: 0;
right: 0;
box-shadow: -20px -20px 50px 2px #000 inset;
border-radius: 50%;
}
.earth > div {
width: 200%;
height: 100%;
animation: spin 30s linear infinite;
background: url(https://i.sstatic.net/3SLqF.jpg);
/*orginal image at https://upload.wikimedia.org/wikipedia/commons/thumb/c/c4/Earthmap1000x500compac.jpg/640px-Earthmap1000x500compac.jpg */
background-size: cover;
}
@keyframes spin {
to {
transform: translateX(-50%);
}
}
<div class="earth">
<div></div>
</div>
Here is the GIF image of the issue: https://imgur.com/a/f7nUtrW//
Upvotes: 6
Views: 4064
Reputation: 95
You can see my attempt here, and the accompanying article! Here is the pug (sass is hundreds of lines)
- const randomNumber = ({ min, max }) => Math.floor(Math.random() * (max - min + 1)) + min;
- const planetDiameter = 50;
- const cloudLayers = 3;
- const earth = [{"label": "Africa", "layers": 20, "diameter": 26 * (50 / 42), "rotation": -8, "z-rotation": 14, "position": 10, "components": 1},{"label": "Asia", "layers": 20, "diameter": 38 * (50 / 42), "rotation": -4, "z-rotation": -45, "position": 1919, "components": 7},{"label": "Europe", "layers": 20, "diameter": 21 * (50/42), "rotation": 0, "z-rotation": 10, "position": 520, "components": 8},{"label": "America", "layers": 20, "diameter": 41 * (50/42), "rotation": 20, "z-rotation": 140, "position": 560, "components": 4},{"label": "Australasia", "layers": 20, "diameter": 24 * (50 / 42), "rotation": -10, "z-rotation": -89, "position": 1, "components": 24}];
- const clouds = [{"label": "A", "randomY": randomNumber({min: 0, max: 36}) * 10, "randomZ": randomNumber({min: -50, max: 50}), "center-to-apex": -95, "width": "632.15px", "height": "271.38px"}, {"label": "B", "randomY": randomNumber({min: 0, max: 36}) * 10, "randomZ": randomNumber({min: -50, max: 50}), "center-to-apex": 0, "width": "762.01px", "height": "301.12px"}, { "label": "C","randomY": randomNumber({min: 0, max: 36}) * 10, "randomZ": randomNumber({min: -50, max: 50}), "center-to-apex": 0, "width": "737.64px", "height": "409.58px"}, {"label": "D", "randomY": randomNumber({min: 0, max: 36}) * 10, "randomZ": randomNumber({min: -50, max: 50}), "center-to-apex": 0, "width": "778.11px", "height": "406.46px"}, {"label": "E", "randomY": randomNumber({min: 0, max: 36}) * 10, "randomZ": randomNumber({min: -50, max: 50}), "center-to-apex": 130, "width": "750.41px", "height": "391.78px"}];
- const cloudsComputed = Array(randomNumber({ min: 10, max: 20 })).fill("").map(() => { const randomZ = randomNumber({ min: -50, max: 50 }); const randomY = randomNumber({ min: 0, max: 36 }) * 10; const randomCloud = clouds[randomNumber({ min: 0, max: clouds.length - 1 })].label; const randomScale = randomNumber({ min: 21, max: 30 }); return { randomZ, randomY, randomCloud, randomScale };});
.Earth
.Earth__Earth-Container
.Planet.Planet--Earth
.Sphere
.Hemisphere
each continent in earth
div(class=`Island Island--${continent.label}`)
- var layers = continent.layers - 1;
while layers > 0
- layers--
.Plate
div
- var components = continent.components;
while components > 0
- components--
.Land
.Earth__Clouds
each cloud in cloudsComputed
div(class=`Planet Planet--Clouds Planet--Clouds--y-rotation--${cloud.randomY}`)
.Sphere
div(class="Hemisphere" style={"transform": `rotateY(${cloud.randomY}deg) rotateZ(${cloud.randomZ}deg)`})
div(class=`Island Cloud Cloud--${cloud.randomCloud} Cloud--scale-${cloud.randomScale}`)
- var layers = cloudLayers;
while layers > 0
- layers--
div
Upvotes: 0
Reputation: 273626
You need to make the width 400%
and not 200%
and instead of cover
use auto 100%
.
I have optimized the code a little so you can easily adjust the dimension and keep the circular shape:
.earth {
width: 300px;
display:inline-block;
margin: 5px;
overflow: hidden;
border-radius: 50%;
box-shadow: 0 0 20px 20px #000 inset, 0 0 20px 2px #000;
position:relative;
}
.earth:after {
position: absolute;
content: "";
top: 0;
bottom: 0;
left: 0;
right: 0;
box-shadow: -20px -20px 50px 2px #000 inset;
border-radius: 50%;
}
.earth::before {
content: "";
display: block;
width: 400%;
padding-top:100%;
animation: spin 3s linear infinite;
background: url(https://github.com/BHouwens/SolarSim/blob/master/images/earthmap1k.jpg?raw=true);
background-size: auto 100%;
}
@keyframes spin {
to {
transform: translateX(-50%);
}
}
<div class="earth">
</div>
<div class="earth" style="width:200px">
</div>
<div class="earth" style="width:100px">
</div>
Also like below with less of code and no pseudo element:
.earth {
--d:300px;
width: var(--d);
height:var(--d);
display:inline-block;
margin: 5px;
border-radius: 50%;
box-shadow: -20px -20px 50px 2px #000 inset, 0 0 20px 2px #000;
background:
url(https://i.sstatic.net/3SLqF.jpg)
0/auto 100%;
animation: spin 3s linear infinite;
}
@keyframes spin {
to {
background-position:200% 0;
}
}
<div class="earth">
</div>
<div class="earth" style="--d:200px">
</div>
<div class="earth" style="--d:100px">
</div>
Upvotes: 5
Reputation: 41
You can add two stages to the keyframe specifying the x-position, as such:
@keyframes spin{
0% { background-position-x: 0; }
100% { background-position-x: -600px; }
}
I've added an snippet with the result:
.earth {
width: 300px;
height: 300px;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
overflow: hidden;
border-radius: 50%;
box-shadow: 0 0 20px 20px #000 inset, 0 0 20px 2px #000;
}
.earth:after {
position: absolute;
content: "";
top: 0;
bottom: 0;
left: 0;
right: 0;
box-shadow: -20px -20px 50px 2px #000 inset;
border-radius: 50%;
}
.earth > div {
width: 200%;
height: 100%;
animation: spin 5s linear infinite;
background: url(https://github.com/BHouwens/SolarSim/blob/master/images/earthmap1k.jpg?raw=true);
/*orginal image at https://upload.wikimedia.org/wikipedia/commons/thumb/c/c4/Earthmap1000x500compac.jpg/640px-Earthmap1000x500compac.jpg */
background-size: cover;
}
@keyframes spin{
0% { background-position-x: 0; }
100% { background-position-x: -600px; }
}
<div class="earth">
<div></div>
</div>
Upvotes: 2