Изменение цвета фона страницы сайта и его элементов

Хочу реализовать такую анимацию.
Снизу страницы поднимается вода, которая меняет цвет фона страницы и цвет ее элементов. По мере того как вода заполняет страницу, она как бы окрашивает ее элементы (цвет шрифта меняется на другой). Вопрос абстрактный т.к. не могу найти в сети примеры. Собственно хочу узнать в какую сторону копать. Мои поиски пока не увенчались успехом. Предполагаю, что это работа с svg масками. Буду благодарен ссылкам на какие-то примеры и документацию.


Ответы (2 шт):

Автор решения: Alexandr_TT

Могу предложить пример заполнения текста волной с изменением цвета букв.

Этот пример можно использовать, как для шапки сайта, так и для оформления визуальных эффектов веб страниц.

Можно подобрать на ваш вкус любую картинку для фона, текст, изменить цвет букв с помощью градиента.

  1. Для реализации волны используется path svg

  2. Анимация волны достигается перемещением path

<animateTransform attributeName="transform" type="translate" begin="0s" dur="1.5s" from="0,0" to="40,0" repeatCount="indefinite" />
  1. Паттерн c анимированной волной применяется к тексту

Смотрите комментарии в коде, надеюсь они помогут понять основные моменты

body,html{margin:0;padding:0;height:100%;}
body{
  background:url('https://i.stack.imgur.com/Csgbl.jpg');
  background-size:cover;
  font-family: 'Cabin Condensed', sans-serif;
  display:flex;
  flex-direction:column;
  justify-content:center;
  align-items:center;
}
svg{font-weight:bold;max-width:600px;height:auto;}
<svg viewbox="0 0 100 20">
  <defs>
    <linearGradient id="gradient" x1="0" x2="0" y1="0" y2="1">
      <stop offset="5%" stop-color="#326384"/>
      <stop offset="95%" stop-color="#123752"/>
    </linearGradient>
    <pattern id="wave" x="0" y="0" width="120" height="20" patternUnits="userSpaceOnUse">
      <path id="wavePath" d="M-40 9 Q-30 7 -20 9 T0 9 T20 9 T40 9 T60 9 T80 9 T100 9 T120 9 V20 H-40z" fill="url(#gradient)"> 
      
      <!-- Анимация волны достигается перемещением path  -->
     
     <animateTransform attributeName="transform" type="translate" begin="0s" dur="1.5s" from="0,0" to="40,0" repeatCount="indefinite" />
      </path>
    </pattern>
  </defs>
      <!-- Паттерн c анимированной волной применяется к тексту -->
  <text text-anchor="middle" x="50" y="15" font-size="17" fill="url(#wave)"  fill-opacity="0.9">MY  SITE</text>
  <text text-anchor="middle" x="50" y="15" font-size="17" fill="url(#gradient)" fill-opacity="0.3">MY  SITE</text>
</svg>

Второй пример, с другой фоновой картинкой, цветами градиента, более удлиненным текстом.
То есть, я хочу сказать, что вы легко сможете подобрать цветовую гамму по своему вкусу
.

body,html{margin:0;padding:0;height:100%;}
body{
  background:url('https://i.stack.imgur.com/HnYTh.jpg');
  background-size:cover;
  font-family: 'Cabin Condensed', sans-serif;
  display:flex;
  flex-direction:column;
  justify-content:center;
  align-items:center;
}
svg{font-weight:bold;max-width:600px;height:auto;}
<svg viewbox="0 0 100 20">
  <defs>
    <linearGradient id="gradient" x1="0" x2="0" y1="0" y2="1">
      <stop offset="5%" stop-color="#151515"/>
      <stop offset="95%" stop-color="#white"/>
    </linearGradient>
    <pattern id="wave" x="0" y="0" width="130" height="20" patternUnits="userSpaceOnUse">
      <path id="wavePath" d="M-40 9 Q-30 7 -20 9 T0 9 T20 9 T40 9 T60 9 T80 9 T100 9 T120 9 V20 H-40z" fill="url(#gradient)"> 
        <animateTransform attributeName="transform" type="translate" begin="0s" dur="1.5s" from="0,0" to="40,0" repeatCount="indefinite" />
      </path>
    </pattern>
  </defs>
  <text text-anchor="middle" x="52" y="15" font-size="17" fill="url(#wave)"  fill-opacity="0.8">MY  SITE</text>
  <text text-anchor="middle" x="52" y="15" font-size="17" fill="url(#gradient)" fill-opacity="0.2">MY  SITE</text>
</svg>

→ Ссылка
Автор решения: Александр Курмояров

Добился необходимого эффекта при помощи clip-path. Кому интересно вот ссылка. Добавил заполнение по клику на кнопку. Однако не уверен пока что это именно правильный подход.

const buttonFirst = document.querySelector('.button-first');
const buttonSecond = document.querySelector('.button-second');
const containerSecond = document.querySelector('.second');

buttonFirst.addEventListener('click', () => {
  containerSecond.classList.remove('draining');
  containerSecond.classList.toggle('fill-water');
  setTimeout(() => {
    containerSecond.classList.add('filled');
  }, 2500)
});

buttonSecond.addEventListener('click', () => {
  containerSecond.classList.toggle('fill-water');
  containerSecond.classList.toggle('draining');
  setTimeout(() => {
    containerSecond.classList.remove('filled');
  }, 2500)
});
html, body { height: 100%; }
body {
    display: flex;
    justify-content: center;
    align-items: center;
}

.first, .second {
  position: absolute;
  display: flex;
  justify-content: center;
  align-items: center;
}

.button {
  padding: 20px;
  cursor: pointer;
  font-size: 72px;
  border: none;
  outline: none;
}

.button-first {
  color: white;
  background: #007ba7;
}

.button-second {
  color: #007ba7;
  background: white;
}

.second {
    width: 100%;
    height: 280px;
  background: #007ba7;
  clip-path: polygon(0% 95%, 100% 95%, 100% 100%, 0% 100%);
}

.fill-water {
  animation: water 3s linear 1;
}

.filled {
  clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
}

.draining {
  animation: draining 3s linear 1;
}

@keyframes water {
  from {
    clip-path: polygon(0% 95%, 100% 95%, 100% 100%, 0% 100%);
  }
  
  to {
    clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
  }
}

@keyframes draining {
  from {
    clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
  }
  
  to {
     clip-path: polygon(0% 95%, 100% 95%, 100% 100%, 0% 100%);
  }
}
<div class="first">
  <button class="button button-first">Push me</button>
</div>

<div class="second">
  <button class="button button-second">Push me</button>
</div>

→ Ссылка