Crie um efeito de rolagem paralaxe (com efeito de texto contrastante)

Hora de atualizar nosso conhecimento de paralaxe com um novo exercício, pessoal! No tutorial de hoje, vamos criar uma bela animação de rolagem parallax e contrastar o texto do cabeçalho com a imagem por trás dele.

1. Comece com a marcação HTML

A marcação consistirá em duas seções:

  • A primeira seção do herói incluirá visualmente apenas o cabeçalho e a imagem do perfil. Mas, na realidade, colocaremos um cabeçalho e um elemento wrapper que incluirá a imagem e um clone/duplicado do cabeçalho. Ao dizer clone, queremos dizer que seu conteúdo e aparência serão idênticos ao elemento de destino.
  • A segunda seção incluirá o conteúdo principal da página. Claro, você pode ter muito mais seções em suas próprias páginas.

Aqui está a marcação necessária:

1
 class="section section-hero">
2
   class="h1 hero-title">Visual 
Designer
3
   class="hero-img-wrapper">
4
     width="1308" height="1220" src="man-visual-designer.jpg" alt="">
5
     class="h1 hero-title-clone">
6
      Visual 
Designer
7
    
8
  
9

10
 class="section section-text">
11
  
...
12

2. Adicione o CSS

Vamos agora nos concentrar nos principais estilos.

Começaremos com esses alvos na seção de heróis.

Os estilos iniciais da seção do heróiOs estilos iniciais da seção do heróiOs estilos iniciais da seção do herói
  • O título será branco enquanto o clone salmão.
  • O clone será absolutamente posicionado dentro do elemento wrapper da imagem. Isso é top e left os valores de posição serão definidos por meio de JavaScript; o objetivo final é colocá-lo no topo do título exatamente na mesma posição. Mais sobre isso na próxima seção. Para que isso aconteça, devemos garantir que sua ordem de empilhamento seja maior que a do título. No nosso caso, isso ocorre porque o wrapper vem depois do cabeçalho.
  • O elemento wrapper da imagem terá overflow: hidden então o clone não pode exceder seus limites.

Os estilos associados:

1
/*CUSTOM VARIABLES HERE*/
2
3
.section-hero {
4
  display: flex;
5
  flex-direction: column;
6
  align-items: center;
7
  justify-content: center;
8
  max-width: 1000px;
9
  margin: 0 auto;
10
}
11
12
.section-hero .h1 {
13
  font-size: 20vmin;
14
  line-height: 0.9;
15
  font-weight: bold;
16
  text-align: center;
17
  text-shadow: 2px 2px 10px #1a1423;
18
}
19
20
.section-hero .hero-title-clone {
21
  position: absolute;
22
  color: var(--salmon);
23
}
24
25
.section-hero .hero-img-wrapper {
26
  position: relative;
27
  margin-top: -10vh;
28
  overflow: hidden;
29
}
30
31
.section-hero .hero-img-wrapper img {
32
  border-radius: 10px;
33
}

Em relação aos estilos principais de conteúdo, um aspecto importante é que todas as seções irmãs após a do herói devem ter um valor maior z-index valor. Dessa forma, o cabeçalho de rolagem sempre estará abaixo dessas seções.

No nosso caso, tudo o que temos abaixo é uma imagem de fundo fixa com texto sobre ela. Para garantir que o texto seja legível, colocaremos uma imagem sobreposta.

A seção principalA seção principalA seção principal

Os estilos relevantes:

1
.section-hero ~ .section {
2
  position: relative;
3
  z-index: 2;
4
}
5
6
.section-text {
7
  background: url(man-walking.jpg) no-repeat fixed center right / cover;
8
  margin-top: 20vh;
9
}
10
11
.section-text::before {
12
  content: "";
13
  position: absolute;
14
  top: 0;
15
  left: 0;
16
  right: 0;
17
  bottom: 0;
18
  background: rgba(56, 36, 52, 0.5);
19
}
20
21
.section-text div {
22
  position: relative;
23
  max-width: 700px;
24
  padding: 100px 0;
25
  margin: 0 auto;
26
}
27
28
.section-text p {
29
  margin-top: 20px;
30
}

3. Aplique o JavaScript

A primeira coisa que devemos fazer é colocar o clone no lugar do cabeçalho assim:

Onde o elemento clone deve ser posicionadoOnde o elemento clone deve ser posicionadoOnde o elemento clone deve ser posicionado

Isso deve acontecer quando todos os recursos da página tiverem sido carregados e durante o redimensionamento da janela. Em seus projetos, para evitar esse salto até que o clone fique na posição correta, você pode adicionar um pré-carregador ou algo parecido.

Nesse ponto, vamos chamar o setPos() funcionar e seguir este plano:

  • Pegue o x e y posições do cabeçalho em relação à viewport.
  • Pegue o x e y posições do elemento wrapper da imagem em relação à viewport.
  • Colocou o top e left valores de propriedade do clone subtraindo os valores do título dos valores do wrapper. Especialmente para evitar a disposição de nosso clone quando redimensionamos repentinamente a altura da janela, também temos que subtrair do final top valorize a quantidade de nossa rolagem (explicamos como calcular isso no próximo parágrafo).

dica

Em vez das posições x e y, podemos pegar igualmente os valores superior e esquerdo com qualquer diferença.

Para criar o efeito de paralaxe, enquanto rolamos, usaremos o transform propriedade para mover o título e seu clone ao mesmo tempo e direção para que pareçam um único elemento. A velocidade do movimento será determinada pelo getSpeed() função. Nossa velocidade base será de 1,1, o que significa que os elementos-alvo se moverão 10% mais rápido que os outros elementos. Altere esse valor para ver a diferença no efeito.

Com tudo isso em mente, aqui está todo o código JavaScript de que precisaremos:

1
const sectionHero = document.querySelector(".section-hero");
2
const heroTitle = sectionHero.querySelector(".hero-title");
3
const heroTitleClone = sectionHero.querySelector(".hero-title-clone");
4
const heroImgWrapper = sectionHero.querySelector(".hero-img-wrapper");
5
const speed = 1;
6
7
window.addEventListener("load", setPos);
8
window.addEventListener("resize", setPos);
9
10
function setPos() {
11
  const { x: heroTitleX, y: heroTitleY } = heroTitle.getBoundingClientRect();
12
  const {
13
    x: heroImgWrapperX,
14
    y: heroImgWrapperY
15
  } = heroImgWrapper.getBoundingClientRect();
16
      
17
  heroTitleClone.style.top = `${heroTitleY - getSpeed() - heroImgWrapperY}px`;
18
  heroTitleClone.style.left = `${heroTitleX - heroImgWrapperX}px`;
19
}
20
21
window.addEventListener("scroll", function () {
22
  const speed = `translateY(${getSpeed()}px)`;
23
  heroTitle.style.transform = speed;
24
  heroTitleClone.style.transform = speed;
25
});
26
27
function getSpeed() {
28
  return this.pageYOffset * speed;
29
}

Conclusão

Com menos de 30 linhas de código JavaScript, conseguimos construir esse lindo efeito de paralaxe que é um cenário perfeito para um site de portfólio ou sempre que você quiser criar um contraste entre o texto e seu fundo. Felizmente, você está convencido o suficiente para incorporá-lo em um de seus projetos.

Antes de fechar, vamos olhar novamente para o que criamos hoje:

Como sempre, muito obrigado pela leitura!

Deixe uma resposta