Как анимировать background-position используя проценты, когда background-size равен 100%? - PullRequest
0 голосов
/ 02 марта 2019

Возьмите следующий пример:

html {
    height: 100%;
}

body {
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: black;
    height: 100%;
    margin: 0;
}

#main {
    background: #222222;
    position: relative;
    flex: 640px 0 0;
    height: 360px;
}

@keyframes stars {
	0% {
        background-position: 0 0;
    }
	100% {
        background-position: -100% 0;
    }
}

#stars {
    animation: stars 10s linear infinite;
    background-image: url('https://i.imgur.com/nyFndCj.png');
    background-size: 100% 100%;
    background-repeat: repeat repeat;
    position: absolute;
    width: 100%;
    height: 100%;
}
<div id="main">
  <div id="stars"></div>
</div>

Идея заключается в том, чтобы анимировать звезды, движущиеся с одной стороны на другую, путем изменения положения фона с использованием процентов .Я могу заставить это работать, используя, например, px, но это требует, чтобы я заранее знал ширину (в данном случае 640px), и если я хочу изменить ширину / высоту #main, мне нужно изменитьЗначения анимации, и я хочу избежать этого, таким образом, проценты.Кроме того, я хочу сделать это только с помощью CSS, без JavaScript вообще.

1 Ответ

0 голосов
/ 02 марта 2019

Уменьшите размер фона и используйте масштаб, чтобы исправить это, увеличив размер контейнера.Тогда вы сможете анимировать фон, как вы хотите:

body {
  background-color: black;
  height: 100vh;
  margin: 0;
}

#main {
  background: #222222;
  position: relative;
  width: 100%;
  height: 360px;
  overflow: hidden;
}

#stars {
  animation: stars 10s linear infinite;
  background-image: url('https://i.imgur.com/nyFndCj.png');
  background-size: 50% 100%;
  position: absolute;
  left: 0;
  right: 0;
  height: 100%;
  transform: scaleX(2);
}

@keyframes stars {
  0% {
    background-position: left;
  }
  100% {
    background-position: right;
  }
}
<div id="main">
  <div id="stars"></div>
</div>

Вот еще одна идея без масштаба, где вы также увеличиваете элемент в два раза, используя right:-100% или left:-100% или width:200%

body {
  background-color: black;
  height: 100vh;
  margin: 0;
}

#main {
  background: #222222;
  position: relative;
  width: 100%;
  height: 360px;
  overflow: hidden;
}

#stars {
  animation: stars 10s linear infinite;
  background-image: url('https://i.imgur.com/nyFndCj.png');
  background-size: 50% 100%;
  position: absolute;
  left: 0;
  right: -100%;
  height: 100%;
}

@keyframes stars {
  0% {
    background-position: left;
  }
  100% {
    background-position: right;
  }
}
<div id="main">
  <div id="stars"></div>
</div>

Вот еще одно упрощение, касающееся псевдоэлемента:

body {
  background-color: black;
  height: 100vh;
  margin: 0;
}

#main {
  position: relative;
  width: 100%;
  height: 360px;
  overflow: hidden;
  z-index:0;
}
#main:before {
  content:"";
  position:absolute;
  z-index:-1;
  top:0;
  left:0;
  right:-100%;
  bottom:0;
  animation: stars 10s linear infinite;
  background: 
    url('https://i.imgur.com/nyFndCj.png') left/50% 100%,
    #222222;
}

@keyframes stars {
  100% {
    background-position: right;
  }
}
<div id="main">
</div>

Во всех случаях трюк состоит в том, чтобы избежать наличия 100% 100% в background-size, иначе будет невозможно анимировать, используя процент.


Я использовал left / right для упрощения, что эквивалентно 0% 50% / 100% 50%.Просто переключайтесь между ними, чтобы изменить направление.

Подробнее здесь: https://stackoverflow.com/a/51734530/8620333


И так как мы увеличили размер контейнера, мы также можем анимировать его с помощью translateиметь лучшую производительность:

body {
  background-color: black;
  height: 100vh;
  margin: 0;
}

#main {
  position: relative;
  width: 100%;
  height: 360px;
  overflow: hidden;
  z-index:0;
}
#main:before {
  content:"";
  position:absolute;
  z-index:-1;
  top:0;
  left:0;
  right:-100%;
  bottom:0;
  animation: stars 10s linear infinite;
  background: 
    url('https://i.imgur.com/nyFndCj.png') left/50% 100%,
    #222222;
}

@keyframes stars {
  100% {
    transform: translateX(-50%);
  }
}
<div id="main">
</div>

С масштабированием:

body {
  background-color: black;
  height: 100vh;
  margin: 0;
}

#main {
  position: relative;
  width: 100%;
  height: 360px;
  overflow: hidden;
  z-index:0;
}
#main:before {
  content:"";
  position:absolute;
  z-index:-1;
  top:0;
  left:0;
  right:0;
  bottom:0;
  transform:scaleX(2);
  transform-origin:left;
  animation: stars 10s linear infinite;
  background: 
    url('https://i.imgur.com/nyFndCj.png') left/50% 100%,
    #222222;
}

@keyframes stars {
  100% {
    transform:scaleX(2) translateX(-50%);
  }
}
<div id="main">
</div>

В другом направлении

body {
  background-color: black;
  height: 100vh;
  margin: 0;
}

#main {
  position: relative;
  width: 100%;
  height: 360px;
  overflow: hidden;
  z-index:0;
}
#main:before {
  content:"";
  position:absolute;
  z-index:-1;
  top:0;
  left:0;
  right:0;
  bottom:0;
  transform:scaleX(2);
  transform-origin:right;
  animation: stars 10s linear infinite;
  background: 
    url('https://i.imgur.com/nyFndCj.png') left/50% 100%,
    #222222;
}

@keyframes stars {
  100% {
    transform:scaleX(2) translateX(50%);
  }
}
<div id="main">
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...