Анимированный фон на основе времени

#javascript #html #css #animation

#javascript #HTML #css #Анимация

Вопрос:

Здесь у меня есть некоторый код, который анимирует целый день (от восхода солнца до заката): (демо)

Мне любопытно узнать, возможно ли сделать это еще более динамичным, чтобы анимация перемещалась со временем суток.

Например: если сейчас полдень, солнце должно быть в самой высокой точке неба. И наоборот, если сейчас полночь, луна будет в самой высокой точке неба.

У меня есть подозрение, что это можно сделать с помощью нескольких строк javascript:

 <script type="text/javascript">
var currentTime = new Date().getHours();
if (document.html) {
    '''psuedo_code'''
    while true
        for hour in day
            move sun and moon according to currentTime
}
</script>
  

HTML и CSS:

 <html>
<div class="canvas">
    <div class="cloud"></div>
    <div class="cloud a"></div>
    <div class="cloud b"></div>
    <div class="cloud c"></div>
    <div class="land">
        <div class="tree"></div>
        <div class="tree a"></div>
        <div class="tree b"></div>
        <div class="tree c"></div>
        <div class="tree d"></div>
    </div>
    <div class="star"></div>
    <div class="star a"></div>
    <div class="star b"></div>
    <div class="star c"></div>
    <div class="star d"></div>
    <div class="wind"></div>
<!-- <div class="swirly-wind">
  <span></span>
  <span></span>
  <span></span>
</div>
<div class="swirly-wind a"></div>
<div class="swirly-wind b"></div> -->
    <div class="eclipse">
        <div class="sun"></div>
        <div class="sun a"></div>
        <div class="moon"></div>
        <div class="moon a"></div>
    </div>
</div>
</html>
  
 <style>
/*body {
    position: relative;
}*/
.canvas {
    width: 600px;
    height: 600px;
    border: 1px solid #000;
    margin: 0 auto;
    position: relative;
    animation-delay: 1s;
    background: #70c4c6;
    animation-name: daylight;
    animation-duration: 20s;
    animation-iteration-count: infinite;
    overflow: hidden;
    animation-timing-function: linear;
}
.eclipse {
    width: 600px;
    height: 600px;
    /*border: 1px solid #000;*/
    position: absolute;
    left:60%;
    top:20%;
    animation-name: time;
    animation-duration: 40s;
    animation-iteration-count: infinite;
    z-index: 0;
    animation-timing-function: linear;
}
.sun {
    width:70px;
    height:70px;
    border-radius: 50%;
    background-color: #ffa;
    position: absolute;
    top: -35px;
    left: -35px;
}
.sun.a {
    bottom: -35px;
    right: -35px;
    left: auto;
    top:auto;
}
.moon {
    position: absolute;
    top: -35px;
    right: -35px;
    width:70px;
    height:70px;
    border-radius: 50%;
    background-color: #fff;
}
.moon.a {
    bottom: -35px;
    left: -35px;
    top:auto;
    right: auto;
}
.cloud {
    width: 50px;
    height: 45px;
    border-radius: 50%;
    background-color: #fff;
    position: absolute;
    top:20px;
    left: -20%;
    animation-name: cloud;
    animation-duration: 70s;
    animation-iteration-count: infinite;
    z-index: 1;
}
.cloud::before {
    content:'';
    width: 35px;
    height: 30px;
    background-color: #fff;
    margin-left: -20px;
    margin-top: 10px;
    display: block;
    border-radius: 50%;
}
.cloud::after {
    content:'';
    width: 20px;
    height: 20px;
    background-color: #fff;
    position: absolute;
    right: -10px;
    top: 17px;
    border-radius: 50%;
}
.cloud.a {
    top:150px;
    animation-duration: 55s;
}
.cloud.b {
    top:100px;
    left:-15%;
    animation-duration: 38s;
}
.cloud.c {
    top:250px;
    left:-10%;
    animation-duration: 25s;
}
.land {
    width: 100%;
    height: 320px;
    position: absolute;
    left:-50px;
    bottom: -120px;
    background-color: #83a81c;
    border-radius: 50%;
    z-index: 1;
    animation-name: land;
    animation-duration: 20s;
    animation-iteration-count: infinite;
}
.land::before {
    width: 100%;
    height: 200px;
    content: '';
    position: absolute;
    left: 40%;
    top: 20%;
    border-radius: 50%;
    background-color: #96be29;
    transform: rotate(-15deg);
    animation-name: land1;
    animation-duration: 20s;
    animation-iteration-count: infinite;
}
.tree {
    width:10px;
    height:40px;
    background-color: #766257;
    left: 200px;
    position: absolute; 
}
.tree::before {
    content: '';
    position: absolute;
    bottom: 125%;
    left: -7px;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 20px 43px 20px;
    border-color: transparent transparent #bfde3b transparent;
    z-index: 1;

    animation-name: windy;
    animation-duration: 5s;
    animation-iteration-count: infinite;
}
.tree::after {
    content: '';
    position: absolute;
    bottom:100%;
    left:-25px;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 30px 60px 30px;
    border-color: transparent transparent #93ae29 transparent;  
}
.tree.a {
    transform: scale(0.5);
    left: 250px;
}
.tree.b {
    transform: scale(0.75);
    left: 280px;
}
.tree.c {
    transform: scale(1.5);
    left:450px;
    top: 100px;
}
.tree.d {
    transform: scale(1.25);
    left: 530px;
    top: 80px;
    z-index: 0;
}
.star {
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background-color: #fff;
    position: absolute;
    top: 50px;
    left: 100px;
    animation-name: fader;
    animation-duration: 20s;
    animation-iteration-count: infinite;
}
.star::before {
    content: '';
    width:3px;
    height:3px;
    border-radius: 50%;
    background-color: #fff;
    position: absolute;
    left:20px;
    top:20px;
    animation-name: blinker;
    animation-duration: 20s;
    animation-iteration-count: infinite;
}
.star::after {
    content: '';
    width:2px;
    height:2px;
    border-radius: 50%;
    background-color: #fff;
    position: absolute;
    left:-200px;
    top:50px;
    animation-name: blinker;
    animation-duration: 20s;
    animation-iteration-count: infinite;    
}
.star.a {
    top:30px;
    left:90%;
}
.star.b {
    top:120px;
    left:70%;
}
.star.c {
    top:100px;
    left:65%;
}
.star.d {
    top:200px;
    left:15%;
}
.swirly-wind {
    position: absolute;
    top:30%;
  animation-name: wind;
    animation-duration: 12s;
    animation-iteration-count: infinite;    
    animation-timing-function: linear;
}
.swirly-wind > span {
  width: 150px;
    background-color: #eee;
    height: 2px;
  display: block;
  position: relative;
}
.swirly-wind > span:first-child {
  width: 200px;
}
.swirly-wind > span:nth-child(1)::before {
  display: none;
}
.swirly-wind > span:nth-child(2) {
  margin-top: -10px;
  float: right;
}
.swirly-wind > span:nth-child(3) {
  margin-top: 15px;
  width: 75px;
  float: right;
}
.swirly-wind span::before {
  content: '';
  position: absolute;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: #fff 2px solid;
  bottom: calc(100% - 2px);
  right: -15px;
  -webkit-clip-path: polygon(100% 0, 100% 100%, 50% 100%, 0 0);
  clip-path: polygon(100% 0, 100% 100%, 50% 100%, 0 0);
}
.swirly-wind > span:nth-child(3)::before  {
  top: calc(100% - 2px);
  -webkit-clip-path: polygon(100% 0, 100% 100%, 14% 100%, 35% 0);
clip-path: polygon(100% 0, 100% 100%, 14% 100%, 35% 0);
}

.swirly-wind.a {
  top:20%;
  width: 75px;
    animation-duration: 8s;
}
.swirly-wind.b {
  top:45%;
  width: 120px;
    animation-duration: 15s;
  height :1px;
}
.swirly-wind.b::before {
  border: #fff 1px solid;
  bottom: calc(100% - 1px);
}
.wind {
    width: 150px;
    background-color: #eee;
    height: 2px;
    position: absolute;
    top:30%;
    animation-name: wind;
    animation-duration: 8s;
    animation-iteration-count: infinite;    
    animation-timing-function: linear;
}
.wind::before {
    content: '';
    position: absolute;
    left: 200px;
    width: 100px;
    height: 1px;
    background-color: #eee;
    top:100px;
}
.wind::after {
    content: '';
    position: absolute;
    left: 400px;
    width: 180px;
    height: 1px;
    background-color: #eee;
    top:30px;
}
@keyframes time {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}
@keyframes daylight {
    0% {  background-color: #70c4c6; }
    15% {  background-color: #524b64; }
    40% { background-color: #354a4a; }
    70% { background-color: #354a4a; }
    80% {  background-color: #e2b553; }
    100% {  background-color: #70c4c6;}
}
@keyframes land {
    40% { background-color: #4d6932; }
    70% { background-color: #4d6932;}
}
@keyframes land1 {
    40% { background-color: #5b793e; }
    70% { background-color: #5b793e;}
}
@keyframes cloud {
    0% { transform: translateX(0); }
    100% { transform: translateX(850px); }
}
@keyframes rotate {
    0% { transform: rotate(0); }
    100% { transform: rotate(360deg); }
}
@keyframes fader {
    0% { opacity: 0; }
    15% { opacity: 0; }
    40% { opacity: 1; }
    60% { opacity: 0.4; }
    70% { opacity: 1; }
    80% {  opacity: 0; }
    100% { opacity: 0; }
}
@keyframes blinker {
    0% { opacity: 0; }
    18% { opacity: 0; }
    25% { opacity: 1; }
    40% { opacity: 0; }
    60% { opacity: 1; }
    70% {  opacity: 0; }
    100% { opacity: 0; }    
}
@keyframes blinker-1 {
    0% { opacity: 0; }
    30% { opacity: 0; }
    40% { opacity: 1; }
    60% { opacity: 1; }
    80% {  opacity: 0; }
    100% { opacity: 0; }    
}
@keyframes windy {
    15% {  transform: translateX(5px); transform: rotate(5deg); }
    80% {  transform: translateX(7px); transform: rotate(7deg);}
    80% {  transform: translateX(5px); transform: rotate(5deg);}
}
@keyframes wind {
    0% {  left: -800px; opacity: 0 }
    15% { opacity: 1; }
    70% { left: 800px; opacity: 1;}
    80% {  left: 800px; opacity: 0;}
    100% {  left: -1000px; opacity: 0;}
}


@keyframes snowday {
    0% {
        top: 0;
    }
    100% {
        top: 100%;
    }
}
.snow {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: #fff;
    position: absolute;
    top: 0;
}
.snow.fall {
    animation-name: snowday ;
    animation-duration: 5s;
}
</style>
  

Комментарии:

1. Если вы хотите, чтобы он перемещался в «реальном времени», он будет настолько медленным, что будет незаметным 🙂 Вы могли бы легко просто обновлять позицию даже один раз каждые 5 минут вместо необходимости непрерывной анимации

2. @FluffyKitten Я согласен, и если человек не собирается находиться на странице очень долго, вы можете вообще не обновляться (после первоначального рендеринга). Если человек находится там всего минуту или около того, он даже не заметит разницы.

3. Однако для обновления я бы использовал простую функцию, вызываемую window.setInterval(update_position(), 100).