Можно ли использовать CSS translateX (100%) для создания движущейся анимации? - PullRequest
1 голос
/ 21 июня 2020

В моей анимации я люблю использовать трансформацию. Это также возможно сделать со свойством left/right. Но мне нравится использовать трансформацию. Мне нужно переместить freeze-loading-bar 100% вправо, и это должно быть бесконечное l oop.

Как я могу переместить loading-bar вправо на 100% / полностью?

*,
*::before,
*::after {
  box-sizing: border-box;
}

.app-view {
  height: 200px;
  max-width: 300px;
  margin: 1rem auto;
  background-color: #fff;
  box-shadow: -2px 2px 4px 0 #e0e0e0ad, 1px -1px 9px 0 #dddddd2e;

  padding: 2rem;

  display: flex;
  align-items: center;
  justify-content: center;
}

.freeze-loading {
  position: relative;
  width: 100%;
  height: 5px;
  box-shadow: inset 1px 0px 4px 0 #ddd;
  
  /** disual purpose **/
  /** overflow: hidden; **/
  
}

.freeze-loading-bar {
  position: absolute;
  left: 0;
  width: 80px;
  height: 100%;
  background-color: rgb(0, 132, 255);
  animation: freeze-loading-bar 2s linear infinite;
}

@keyframes freeze-loading-bar {
    from {
        transform: translateX(-100px);
    }

    to {
        transform: translateX(100%);
    }
}
<div class="app-view">
  <div class="freeze-loading">
    <div class="freeze-loading-bar"></div>
  </div>
</div>

Ответы [ 5 ]

4 голосов
/ 21 июня 2020

Сохраняйте ширину элемента на всю ширину (используя влево / вправо), затем используйте градиент для окраски, чтобы окрасить только его часть. Теперь вы можете положиться на translateX(100%), какая бы ширина окраски ни была:

.freeze-loading {
  position: relative;
  width: 100%;
  max-width: 300px;
  margin: 1rem auto;
  height: 5px;
  box-shadow: inset 1px 0px 4px 0 #ddd;
  overflow: hidden;
}

.freeze-loading-bar {
  --w:80px;  /* the width of coloration */

  position: absolute;
  left: calc(-1*var(--w));
  right: 0;
  height: 100%;
  background:
   linear-gradient(rgb(0, 132, 255) 0 0) 
   0 / var(--w) 100%  
   no-repeat;
   animation: freeze-loading-bar 2s linear infinite;
}

@keyframes freeze-loading-bar {
  to {
    transform: translateX(100%);
  }
}
<div class="freeze-loading">
  <div class="freeze-loading-bar"></div>
</div>

<div class="freeze-loading">
  <div class="freeze-loading-bar" style="--w:150px;"></div>
</div>

Другой вид анимации:

.freeze-loading {
  position: relative;
  width: 100%;
  max-width: 300px;
  margin: 1rem auto;
  height: 5px;
  box-shadow: inset 1px 0px 4px 0 #ddd;
  overflow: hidden;
}

.freeze-loading-bar {
  --w:80px; /* the width of coloration */

  position: absolute;
  left: 0;
  right: var(--w);
  height: 100%;
  background:
   linear-gradient(rgb(0, 132, 255) 0 0) 
   0 / var(--w) 100%  
   no-repeat;
   animation: freeze-loading-bar 1s linear infinite alternate;
}

@keyframes freeze-loading-bar {
  to {
    transform: translateX(100%);
  }
}
<div class="freeze-loading">
  <div class="freeze-loading-bar"></div>
</div>

<div class="freeze-loading">
  <div class="freeze-loading-bar" style="--w:150px;"></div>
</div>

Другой синтаксис:

.freeze-loading {
  position: relative;
  width: 100%;
  max-width: 300px;
  margin: 1rem auto;
  height: 5px;
  box-shadow: inset 1px 0px 4px 0 #ddd;
  overflow: hidden;
}

.freeze-loading-bar {
  --w:80px;  /* the width of coloration */

  position: absolute;
  left: 0;
  right: 0;
  height: 100%;
  background:
   linear-gradient(rgb(0, 132, 255) 0 0) 
   0 / var(--w) 100%  
   no-repeat;
  animation: freeze-loading-bar 2s linear infinite;
  transform: translateX(calc(-1*var(--w)));
}

@keyframes freeze-loading-bar {
  to  {
     transform: translateX(100%);
  }
}
<div class="freeze-loading">
  <div class="freeze-loading-bar"></div>
</div>

<div class="freeze-loading">
  <div class="freeze-loading-bar" style="--w:150px;"></div>
</div>

И еще один:

.freeze-loading {
  position: relative;
  width: 100%;
  max-width: 300px;
  margin: 1rem auto;
  height: 5px;
  box-shadow: inset 1px 0px 4px 0 #ddd;
  overflow: hidden;
}

.freeze-loading-bar {
  --w:80px;  /* the width of coloration */

  position: absolute;
  right: 0;
  width:calc(100% + var(--w));
  height: 100%;
  background:
   linear-gradient(rgb(0, 132, 255) 0 0) 
   0 / var(--w) 100%  
   no-repeat;
  animation: freeze-loading-bar 2s linear infinite;
}

@keyframes freeze-loading-bar {
  to  {
     transform: translateX(100%);
  }
}
<div class="freeze-loading">
  <div class="freeze-loading-bar"></div>
</div>

<div class="freeze-loading">
  <div class="freeze-loading-bar" style="--w:150px;"></div>
</div>
3 голосов
/ 21 июня 2020

Что касается отзывчивости, используйте %, а не px, тогда математика проста,

Если ширина полосы равна 20 % (1 / 5 родительского) translateX от -100% до 500% (100% * 5 )

*,
*::before,
*::after {
  box-sizing: border-box;
}

.app-view {
  height: 200px;
  max-width: 300px;
  margin: 1rem auto;
  background-color: #fff;
  box-shadow: -2px 2px 4px 0 #e0e0e0ad, 1px -1px 9px 0 #dddddd2e;
  padding: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
}

.freeze-loading {
  position: relative;
  width: 100%;
  height: 5px;
  box-shadow: inset 0 0px 4px 0 #ddd;
  overflow: hidden;
}

.freeze-loading-bar {
  position: relative;
  top: 0;
  width: 20%;
  height: 100%;
  background-color: rgb(0, 132, 255);
  animation: freeze-loading-bar 2s linear infinite;
}

@keyframes freeze-loading-bar {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(500%);
  }
}
<div class="app-view">
  <div class="freeze-loading">
    <div class="freeze-loading-bar"></div>
  </div>
</div>
0 голосов
/ 21 июня 2020

Ваш пример не совсем работает, потому что процент в преобразовании относится к ширине полосы загрузки, т.е. 100% от 80 пикселей вместо 100% от родительского (который имеет предполагаемую длину полосы загрузки).

Чтобы исправить это, вы можете использовать элемент ::after, чтобы сделать движущуюся полосу на всю ширину, но отображать только часть движущейся полосы:

*,
*::before,
*::after {
  box-sizing: border-box;
}

.app-view {
  height: 200px;
  max-width: 300px;
  margin: 1rem auto;
  background-color: #fff;
  box-shadow: -2px 2px 4px 0 #e0e0e0ad, 1px -1px 9px 0 #dddddd2e;

  padding: 2rem;

  display: flex;
  align-items: center;
  justify-content: center;
}

.freeze-loading {
  display:block;
  position: relative;
  width: 100%;
  height: 5px;
  box-shadow: inset 1px 0px 4px 0 #ddd;
  
  /** disual purpose **/
  overflow: hidden;
  
}

.freeze-loading-bar {
  --loading-bar-width: 80px;
  position: relative;
  width: 100%;
  height: 100%;
  background-color: transparent;
  animation: freeze-loading-bar 2s linear infinite;
}

.freeze-loading-bar::after {
  content: '';
  display: block;
  --loading-bar-width: 80px;
  position: absolute;
  left: 0;
  width: var(--loading-bar-width);
  height: 100%;
  background-color: rgb(0, 132, 255);
  
}

@keyframes freeze-loading-bar {
    from {
        transform: translateX(calc(var(--loading-bar-width) * -1));
    }

    to {
        transform: translateX(100%);
    }
}
<div class="app-view">
  <div class="freeze-loading">
    <div class="freeze-loading-bar"></div>
  </div>
</div>
0 голосов
/ 21 июня 2020
.freeze-loading {
  position: relative;
  width: 100%;
  height: 5px;
  box-shadow: inset 1px 0px 4px 0 #ddd;
  overflow: hidden;  // <== LOOK HERE
  
  /** disual purpose **/
  /** overflow: hidden; **/
  
}

.freeze-loading-bar {
  position: absolute;
  left: 0; // <= LOOK HERE 
  width: 80px;
  height: 100%;
  background-color: rgb(0, 132, 255);
  animation: freeze-loading-bar 2s linear infinite;
}


@keyframes freeze-loading-bar {
    from {
        left: -80px; // <== HERE
    }

    to {
        left: calc(100% + 80px); // AND HERE
    }
}
0 голосов
/ 21 июня 2020

Конечно, вам нужно добавить немного javascript, если вам нужна плавная анимация. Но CSS тоже работает нормально.

    @keyframes freeze-loading-bar {
    from {
        transform: translateX(-100%);
    }

    to {
        transform: translateX(100%);
    }
}

Это может решить вашу проблему.

...