Анимированный CSS фоновый узор, скользящий бесконечно

Я считаю, что проблема со всеми существующими идеями заключается в том, что они , вероятно, уникальны, но не определенно уникальны (как указано в ответе Дариуша Вальчака на loletech). У меня есть решение, которое на самом деле уникально. Это требует, чтобы ваш скрипт имел какую-то память. Для меня это база данных SQL. Вы также можете просто записать в файл где-нибудь. Существуют две реализации:

Первый метод: имеет два поля, а не 1, которые обеспечивают уникальность. Первое поле - это идентификационный номер, который не является случайным, но является уникальным (первый идентификатор равен 1, второй 2 ...). Если вы используете SQL, просто определите поле ID с свойством AUTO_INCREMENT. Второе поле не является уникальным, но случайным. Это может быть сгенерировано с помощью любых других техник, о которых уже говорили люди. Идея Скотта была хорошей, но md5 удобна и, вероятно, достаточно хороша для большинства целей:

$random_token = md5($_SERVER['HTTP_USER_AGENT'] . time());

Второй метод: в основном та же идея, но изначально выбирает максимальное количество строк, которые когда-либо будут созданы. Это может быть просто очень большое количество, как триллион. Затем сделайте то же самое, сгенерируйте идентификатор, но ноль положите его так, чтобы все идентификаторы имели одинаковое количество цифр. Затем просто конкатенируйте идентификатор со случайной строкой. Это будет достаточно случайным для большинства целей, но раздел ID гарантирует, что он также уникален.

4
задан Temani Afif 27 February 2019 в 16:03
поделиться

1 ответ

Правильная формула должна быть (20px / cos(45deg)) * N. Затем вы можете просто сделать background-size 200% 100% (вдвое больше, чем элемент) и легко анимировать слева направо:

li {
  display: inline-block;
  width: calc( (20px / 0.707) * 3); /*cos(45deg) = 0.707*/
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}

.alt li {
  width: calc( (20px / 0.707) * 6);
}
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>
[ 1191]

Вы можете рассмотреть любую степень и скорректировать формулу по мере необходимости. (20px / cos(90deg - |Xdeg|)) * N с X между -90deg и 90deg

Пример с -60deg

li {
  display: inline-block;
  width: calc((20px / 0.866) * var(--n,3)); /*cos(30deg) = 0.866*/
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(-60deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}

.alt li {
  --n:6;
}
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>

Пример с 30deg

li {
  display: inline-block;
  width: calc((20px / 0.5) * var(--n,8)); /*cos(60deg) = 0.5*/
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(30deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}

.alt li {
  --n:12;
}
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>

Пример с 80deg

[ 1173]
li {
  display: inline-block;
  width: calc((20px / 0.9848) * var(--n,8)); /*cos(10deg) = 0.9848*/
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(80deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}

.alt li {
  --n:12;
}
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>

Вы можете четко определить тривиальный случай, когда X=+/-90deg (вертикальные полосы) и у нас будет cos(0)=1, таким образом, формула будет 20px * N. Также, когда X=0 (горизонтальные полосы) у нас будет cos(90deg) = 0, и любая ширина будет работать, так как нет вертикального шаблона (формула больше не определяется)

li {
  display: inline-block;
  width: calc(20px * var(--n,8)); 
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(90deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}

.alt li {
 background-image:repeating-linear-gradient(0deg, transparent, transparent 10px, black 10px, black 20px);
}
[ 119]

Как насчет значения за пределами [-90deg,90deg]?

Вышеупомянутый диапазон уже охватывает 180deg, и поскольку мы имеем дело с чем-то симметричным все значения могут быть представлены внутри этого диапазона.

Пример: 110deg совпадает с -70deg

li {
  display: inline-block;
  width: calc((20px / 0.9396) * var(--n,8)); /*cos(20deg) = 0.9396*/
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(110deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}
.alt li {
  --n:12;
  background-image: repeating-linear-gradient(-70deg, transparent, transparent 10px, black 10px, black 20px);
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>
[1156]

Пример: -150deg совпадает с 30deg

li {
  display: inline-block;
  width: calc((20px / 0.5) * var(--n,4)); /*cos(60deg) = 0.5*/
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(-150deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}
.alt li {
  --n:6;
  background-image: repeating-linear-gradient(30deg, transparent, transparent 10px, black 10px, black 20px);
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>

в основном мы добавляем / удаляем 180deg, пока не попадем внутрь [ 1140], чтобы можно было применить формулу.


Проверьте этот ответ для получения более подробной информации о том, как background-size / background-position работает: https://stackoverflow.com/a/51734530/8620333


[1164 ] Другой подход

Вот совершенно другая идея, где вы можете положиться на skew преобразование и псевдоэлемент. Хитрость заключается в том, что вам не нужно определять ширину на основе полос, но полосы будут следовать ширине, которую вы определите, поэтому с ней будет легче работать.

li {
  display: inline-block;
  width: calc( 20px * 3); /* it's only 20px * N */
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  position:relative;
  z-index:0;
  overflow:hidden
}
li::before {
  content:"";
  position:absolute;
  top:0;
  bottom:0;
  left:0;
  width:400%;
  /*we keep 0deg in the gradient*/
  background-image: repeating-linear-gradient(90deg, transparent, transparent 10px, black 10px, black 20px);
  transform:skewX(30deg);
  transform-origin:bottom left;
  animation: loading-slide 4s linear infinite;
}

@keyframes loading-slide {
  to {
    transform: translateX(-50%) skewX(30deg);
  }
}

.alt li {
  width: calc( 20px * 6);
}
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>

Как видите, мы сохраняем вертикальный градиент, определяем ширину элемента на основе ширины градиент Мы делаем псевдоэлемент достаточно большим и применяем к нему перевод. Единственное, что вам нужно отрегулировать - это косое преобразование для контроля степени.

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

Больше примеров:

li {
  display: inline-block;
  width: calc( 20px * var(--n,3)); /* it's only 20px * N */
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  position:relative;
  z-index:0;
  overflow:hidden
}
li::before {
  content:"";
  position:absolute;
  top:0;
  bottom:0;
  left:-400%;
  right:-800%;
  /*we keep 0deg in the gradient*/
  background-image: repeating-linear-gradient(90deg, transparent, transparent 10px, black 10px, black 20px);
  transform:skewX(var(--d,30deg));
  animation: loading-slide 12s linear infinite;
}

@keyframes loading-slide {
  to {
    transform: translateX(-50%) skewX(var(--d,30deg));
  }
}
<ul>
  <li>test</li><li>test</li>
</ul>

<ul style="--n:6;--d:45deg">
  <li>test</li><li>test</li>
</ul>
<ul style="--n:8;--d:-70deg">
  <li>test</li><li>test</li>
</ul>
<ul style="--n:8;--d:30deg">
  <li>test</li><li>test</li>
</ul>

0
ответ дан Temani Afif 27 February 2019 в 16:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: