Правильная формула должна быть (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>
Вы можете учитывать любую степень и корректировать формулу по мере необходимости.(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
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);
}
<ul>
<li>test</li><li>test</li>
</ul>
<ul class="alt">
<li>test</li><li>test</li>
</ul>
Как насчет значения вне [-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>
Пример: -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
, пока не попадем внутрь [-90deg,90deg]
, чтобы можно было применить формулу.
Проверьте этот ответ для более подробной информации о том, как background-size
/ background-position
работает: https://stackoverflow.com/a/51734530/8620333
Другой подход
Вот совершенно другая идея, на которую вы можете положиться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>