Учитывая тот факт, что вы хотите медленно показывать контент, я бы тогда использовал другой способ для достижения аналогичного эффекта, чем непрозрачность. Я хотел бы рассмотреть наложение над элементом, который я скрываю, используя другую анимацию.
Идея заключается в том, чтобы использовать анимацию с теми же метриками, чтобы синхронизировать ее с анимацией движителя и показывать элемент только в необходимой точке пространства.
Для этого я рассмотрю псевдоэлемент, ширина которого будет равна ширине пути (90vmin - 0vmin = 90vmin
), который будет анимирован в противоположном направлении. этот элемент будет иметь градиентную окраску, и эта окраска создаст magic .
Вот пример:
.mover, .marker {
position: relative;
width: 10vmin;
height: 10vmin;
z-index:0;
overflow:hidden;
color:#fff;
}
.mover:before {
content:"";
position:absolute;
z-index:99;
top:-1px;
bottom:-1px;
left:0;
width:90vmin;
background:linear-gradient(to right,#fff 33%,transparent);
animation: fader 10s infinite;
animation-timing-function:inherit;
}
.mover {
background: red;
animation: mover 10s infinite;
}
.marker {
background: blue;
left: 30vmin;
}
@keyframes mover {
from {
left: 0vmin;
}
to {
left: 90vmin;
}
}
@keyframes fader {
to {
transform:translateX(-100%);
}
}
<div class="mover" style="animation-timing-function: linear;">1</div>
<div class="mover" style="animation-timing-function: ease-in;">2</div>
<div class="mover" style="animation-timing-function: ease-out;">3</div>
<div class="marker"></div>
Чтобы лучше понять, что происходит, давайте изменим окраску и уберем лишний поток:
.mover, .marker {
position: relative;
width: 10vmin;
height: 10vmin;
z-index:0;
color:#fff;
/*overflow:hidden;*/
}
.mover:before {
content:"";
position:absolute;
z-index:99;
top:-1px;
bottom:-1px;
left:0;
width:90vmin;
background:linear-gradient(to right,green 33%,transparent);
animation: fader 10s infinite;
animation-timing-function:inherit;
}
.mover {
background: red;
animation: mover 10s infinite;
}
.marker {
background: blue;
left: 30vmin;
}
@keyframes mover {
from {
left: 0vmin;
}
to {
left: 90vmin;
}
}
@keyframes fader {
to {
transform:translateX(-100%);
}
}
<div class="mover" style="animation-timing-function: linear;">1</div>
<div class="mover" style="animation-timing-function: ease-in;">2</div>
<div class="mover" style="animation-timing-function: ease-out;">3</div>
<div class="marker"></div>
Мы ясно видим, что псевдоэлемент не движется, потому что он просто движется в противоположном направлении, как основной элемент, и с той же скоростью. С нашей точки зрения это исправлено. Затем мы окрашиваем элемент до 33%
, то есть 30vmin
, поэтому наш элемент начнет отображаться в этот момент.
Добавляя переполнение и используя тот же цвет, что и основной фон, мы создаем иллюзию угасания. Конечно, если основной фон не сплошной, трюк не сработает.
Другая идея состоит в том, чтобы полагаться только на фон, настраивая и анимируя background-size
/ background-position
, таким образом, псевдоэлемент будет просто иметь тот же размер, что и основной элемент:
.mover, .marker {
position: relative;
width: 10vmin;
height: 10vmin;
z-index:0;
overflow:hidden;
color:#fff;
}
.mover:before {
content:"";
position:absolute;
z-index:99;
top:-1px;
bottom:-1px;
left:0;
right:0;
background-image:linear-gradient(to right,#fff 33%,transparent);
background-size:90vmin 100%;
background-position:left;
animation: fader 10s infinite;
animation-timing-function:inherit;
}
.mover {
background: red;
animation: mover 10s infinite;
}
.marker {
background: blue;
left: 30vmin;
}
@keyframes mover {
from {
left: 0vmin;
}
to {
left: 90vmin;
}
}
@keyframes fader {
to {
background-position:right;
}
}
<div class="mover" style="animation-timing-function: linear;">1</div>
<div class="mover" style="animation-timing-function: ease-in;">2</div>
<div class="mover" style="animation-timing-function: ease-out;">3</div>
<div class="marker"></div>
И чтобы контролировать эффект затухания, мы увеличиваем background-size
на любой множитель 90vmin
.mover, .marker {
position: relative;
width: 10vmin;
height: 10vmin;
z-index:0;
overflow:hidden;
color:#fff;
}
.mover:before {
content:"";
position:absolute;
z-index:99;
top:-1px;
bottom:-1px;
left:0;
right:0;
background-image:linear-gradient(to right,#fff 33%,transparent);
background-size:calc(var(--m,1)*90vmin) 100%;
background-position:left;
animation: fader 10s infinite;
animation-timing-function:inherit;
}
.mover {
background: red;
animation: mover 10s infinite;
}
.marker {
background: blue;
left: 30vmin;
}
@keyframes mover {
from {
left: 0vmin;
}
to {
left: 90vmin;
}
}
@keyframes fader {
to {
background-position:right;
}
}
<div class="mover" style="animation-timing-function: linear;">1</div>
<div class="mover" style="animation-timing-function: ease-in;--m:5">2</div>
<div class="mover" style="animation-timing-function: ease-out;--m:20">3</div>
<div class="marker"></div>
Чем больше размер, тем ближе мы к эффекту непрозрачности.
UPDATE
Вот еще одна идея, где вы можете иметь прозрачность, но без эффекта затухания. Хитрость заключается в том, чтобы использовать clip-path
, который мы анимируем, чтобы показать элемент в нужной позиции.
.mover, .marker {
position: relative;
width: 10vmin;
height: 10vmin;
color:#fff;
}
.mover {
background: red;
animation: mover 10s infinite,
fader 10s infinite;
}
.marker {
background: blue;
left: 30vmin;
}
@keyframes mover {
from {
left: 0vmin;
}
to {
left: 90vmin;
}
}
@keyframes fader {
from {
clip-path:polygon(30vmin 0%, 100vmin 0%,
100vmin 100%,
30vmin 100% );
}
to {
clip-path:polygon(-60vmin 0%, 10vmin 0%,
10vmin 100%,
-60vmin 100% );
}
}
html {
background:radial-gradient(pink,yellow);
}
<div class="mover" style="animation-timing-function: linear;">1</div>
<div class="mover" style="animation-timing-function: ease-in;">2</div>
<div class="mover" style="animation-timing-function: ease-out;">3</div>
<div class="marker"></div>
Вот иллюстрация, чтобы лучше понять, что происходит:
Оранжевый прямоугольник - это область обрезки. Он должен начинаться с маркера (30vmin
) и заканчиваться на end с учетом ширины элемента (90vmin + 10vmin = 100vmin
). Это означает, что изначально мы не увидим элемент.
Эта область должна оставаться фиксированной для нашей перспективы, чтобы видеть элемент только тогда, когда он достигает маркера, поэтому мы должны переместить его в противоположном направлении, и для этого мы просто изменим clip-path
.
После завершения анимации мы получим следующее:
Обрезанная область должна заканчиваться в конце элемента (10vmin
), и она должна сохранять тот же размер, поэтому она должна начинаться с (-60vmin).
Теперь мы можем увеличить область clip-path
, как мы сделали с background-size
, чтобы управлять эффектом fading , и мы можем добавить анимацию непрозрачности и приблизиться к начальному требованию.
.mover, .marker {
position: relative;
width: 10vmin;
height: 10vmin;
color:#fff;
}
.mover {
background: red;
animation: mover 10s infinite,
fader 10s infinite;
}
.marker {
background: blue;
left: 30vmin;
}
@keyframes mover {
from {
left: 0vmin;
}
to {
left: 90vmin;
}
}
@keyframes fader {
from {
clip-path:polygon(300vmin 0%, 1000vmin 0%, /* x10*/
1000vmin 100%,
300vmin 100% );
opacity:0;
}
to {
clip-path:polygon(-600vmin 0%, 100vmin 0%,
100vmin 100%,
-600vmin 100% );
opacity:1;
}
}
html {
background:radial-gradient(pink,yellow);
}
<div class="mover" style="animation-timing-function: linear;">1</div>
<div class="mover" style="animation-timing-function: ease-in;">2</div>
<div class="mover" style="animation-timing-function: ease-out;">3</div>
<div class="marker"></div>
Стоит отметить, что путь клипа все еще не поддерживается широко (https://caniuse.com/#search=clip-path) ивам нужно добавить префикс -webkit-
, чтобы закрыть браузер Safari.