Есть ли способ, чтобы градиент сохранил начальную ширину элемента, к которому он применяется? - PullRequest
4 голосов
/ 28 марта 2020

Я знаю, что градиенты просто соответствуют размерам любого элемента, к которому они применяются. Хотя есть ли способ визуально сделать градиент stati c и замаскировать части, которые не должны быть видны?

Мое намерение состоит в том, чтобы таймер обратного отсчета становился темнее по мере приближения к концу своей эволюции. В настоящее время мой градиент сохраняет левый и правый цвет, просто уменьшая цвета между ними:

(function() {
  function resetCountdown() {
    window.requestAnimationFrame(function() {
      document.getElementById("countdown-evolution").classList.remove("countdown-reset");
      window.requestAnimationFrame(function() {
        document.getElementById("countdown-evolution").classList.add("countdown-reset");
      });
    });
  }
  resetCountdown();
  document.getElementById("countdown-evolution").addEventListener("transitionend", resetCountdown);
})();
/* Background */

#countdown-background {
  height: 50px;
  width: 100%;
  box-sizing: border-box;
  border: 1px solid #ebebeb;
  background-color: #ffffff;
}


/* Fill */

#countdown-evolution {
  height: 100%;
  width: 100%;
  transform-origin: left;
  background: linear-gradient(to right, #6419cd, #3273fa);
}


/* Reset */

.countdown-reset {
  transition: transform 15s linear;
  transform: scaleX(0);
}


/* Reference */

.fixed-background {
  height: 50px;
  width: 100%;
  box-sizing: border-box;
  border: 1px solid #ebebeb;
  background: linear-gradient(to right, #6419cd, #3273fa);
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Countdown</title>
</head>

<body>
  <div id="countdown-background">
    <div id="countdown-evolution"></div>
  </div>
  <div class="fixed-background"></div>
</body>

</html>

Я уже пытался сделать countdown-background градиент и countdown-evolution solid цвет, что в основном и является тем, к чему я стремлюсь. Однако это вызывает больше проблем, чем решает; потому что теперь мне нужно исправить таймер обратного отсчета, и я не могу заставить его выглядеть так же, как раньше:

(function() {
  function resetCountdown() {
    window.requestAnimationFrame(function() {
      document.getElementById("countdown-evolution").classList.remove("countdown-reset");
      window.requestAnimationFrame(function() {
        document.getElementById("countdown-evolution").classList.add("countdown-reset");
      });
    });
  }
  resetCountdown();
  document.getElementById("countdown-evolution").addEventListener("transitionend", resetCountdown);
})();
/* Background */

#countdown-background {
  height: 50px;
  width: 100%;
  box-sizing: border-box;
  border: 1px solid #ebebeb;
  background: linear-gradient(to right, #6419cd, #3273fa);
}


/* Fill */

#countdown-evolution {
  height: 100%;
  width: 100%;
  transform-origin: left;
  background-color: #ffffff;
}


/* Reset */

.countdown-reset {
  transition: transform 15s linear;
  transform: scaleX(0);
}


/* Reference */

.fixed-background {
  height: 50px;
  width: 100%;
  box-sizing: border-box;
  border: 1px solid #ebebeb;
  background: linear-gradient(to right, #6419cd, #3273fa);
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Countdown</title>
</head>

<body>
  <div id="countdown-background">
    <div id="countdown-evolution"></div>
  </div>
  <div class="fixed-background"></div>
</body>

</html>

Я ценю любое предложение, которое может помочь мне достичь описанного результата. Спасибо.

Ответы [ 2 ]

4 голосов
/ 28 марта 2020

Использование другого элемента в качестве занавеса и абсолютного позиционирования вместе с css ключевыми кадрами:

document
.querySelector("#countdown-evolution-curtain")
.addEventListener('animationend', () => {
  console.log('Animation ended');
});
/* Background */

#countdown-background {
  height: 50px;
  width: 100%;
  box-sizing: border-box;
  border: 1px solid #ebebeb;
  background-color: #ffffff;
  position: relative;
}

#countdown-background div {
  position: absolute;
  right: 0;
  top: 0;
}


/* Fill */

#countdown-evolution-curtain {
  background: #fff;
  height: 100%;
  width: 0%;
  animation: reveal 10s linear;
}

#countdown-evolution {
  height: 100%;
  width: 100%;
  background: linear-gradient(to right, #6419cd, #3273fa);
}

@keyframes reveal {
  0% {
    width: 0%;
  }
  100% {
    width: 100%;
  }
}
<div id="countdown-background">
  <div id="countdown-evolution"></div>
  <div id="countdown-evolution-curtain"></div>
</div>
1 голос
/ 28 марта 2020

Существуют разные способы достижения этого только с одним элементом:

  1. Использование дополнительного белого слоя на приведенном выше примере с другим градиентом
  2. Использование фиксированного значения для градиента, цвет останавливается
  3. Использование background-clip для обрезки фона в области содержимого с помощью анимации заполнения
  4. Использование mask layer
  5. Использование псевдоэлемента в качестве дополнительного слоя

/* Reference */
.reference {
  height: 50px;
  border: 1px solid #ebebeb;
  background: linear-gradient(to right, #6419cd, #3273fa);
}

/* (1) */
.first {
  background: 
    linear-gradient(#fff,#fff) right no-repeat,
    linear-gradient(to right, #6419cd, #3273fa);
  animation:first 5s linear forwards;
} 
@keyframes first{
  from {
    background-size:0% 100%,auto;
  }
  to {
    background-size:100% 100%,auto;
  }
}
/* (2) */
.second {
  background:linear-gradient(to right, #6419cd 0, #3273fa 100vw) left no-repeat;
  animation:second 5s linear forwards;
} 
@keyframes second{
  from {
    background-size:100% 100%;
  }
  to {
    background-size:0% 100%;
  }
}

/* (3) */
.third {
  background-clip:content-box;
  animation:third 5s linear forwards;
} 
@keyframes third{
  from {
    padding-right:0%;
  }
  to {
    padding-right:100%;
  }
}
/* (4) */
.fourth {
  -webkit-mask:linear-gradient(#fff,#fff) left no-repeat;
          mask:linear-gradient(#fff,#fff) left no-repeat;
  animation:fourth 5s linear forwards;
} 
@keyframes fourth{
  from {
    -webkit-mask-size:100% 100%;
            mask-size:100% 100%;
  }
  to {
    -webkit-mask-size:0% 100%;
            mask-size:0% 100%;
  }
}
/* (5) */
.fifth{
  position:relative;
} 
.fifth::before {
  content:"";
  position:absolute;
  background:#fff;
  top:0;
  right:0;
  bottom:0;
  animation:fifth 5s linear forwards;
}
@keyframes fifth{
  from {
    left:100%;
  }
  to {
    left:0%;
  }
}
<div class="first reference"></div>
<div class="second reference"></div>
<div class="third reference"></div>
<div class="fourth reference"></div>
<div class="fifth reference"></div>

<div class="reference"></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...