¿Quieres saber cómo se hace esta animación?
¿O esta otra?
¿O quizás esta?
Es un efecto parallax aplicado en una web.
¿Qué? ¿No sabes qué es?
Pues tranquilo, quédate hasta el final del vídeo, voy a explicártelo todo, paso a paso.
Empecemos por el principio.
Aquí tienes el código disponible de lo que veremos en codepen:
See the Pen
Parallax with JS (basicScroll.js) by animaticss (@animaticss)
on CodePen.
¿Que es el efecto parallax en el mundo web?
El parallax, o también llamado paralaje, apenas se aprecia, pero ocurre a diario en nuestras vidas y constituye uno de los fundamentos de la percepción espacial.
Al mover nuestra visión de un punto a otro, se puede ver cómo cambia la posición relativa de los objetos en el campo de visión.
Los objetos más cercanos se mueven ante los objetos más alejados y los ocultan.
Cuanto más cerca de nuestro punto de vista, más desplazamiento apreciamos en los objetos.
Y cuanto más lejos, menos.
Fíjate en los árboles más cercanos a nuestro punto de vista, parece que se desplazan muy rápido.
En cambio, las montañas del fondo apenas se aprecia el desplazamiento.
El parallax, en el mundo web, es un recurso para aplicar animaciones a diferentes elementos del documento creando una sensación de profundidad espacial entre los diferentes ítems en un plano bidimensional y este efecto se crea al aprovechar los efectos de la percepción humana.
Se puede aplicar una animación de parallax basada en el scroll de la web, pero también podría ser generado, por ejemplo, en función del movimiento del ratón.
Para explicarte el parallax lo haré con un ejercicio basado en el scroll de la web.
La intención del parallax es mejorar la experiencia de usuario y es un arma de doble filo.
Ya que si no está bien aplicado o se abusa de su uso, puede dar un efecto contraproducente en la propia web.
El parallax consiste en aplicar una animación de desplazamiento a un nodo o a varios, pero a una distancia diferente de la normal.
Es decir, cuando haces un scroll de `100px`
hacia el final del documento en la web, todo se desplaza `100px`
hacia arriba, pero el nodo deseado se moverá a una distancia diferente del resto.
Por ejemplo, en vez de moverse los `100px`
que se han hecho de scroll en el navegador, mover ese nodo `140px`
en total.
En el ejercicio que puedes ver en el codepen, en el ejemplo de las cajas:
Cuando hago un scroll de `X`
px, las cajas 1 y 2 se mueven a la distancia normal del scroll realizado.
Pero las cajas 3 y 4 se mueven a una posición diferente.
La caja 3 se ha movido a una distancia superior a la del scroll realizado, es decir, va más rápido.
La caja 4 se ha movido a una distancia inferior a la del scroll realizado, es decir, va más lento.
Ahora bien, todo esto también ocurrirá cuando haces scroll hacia el principio del documento.
El parallax se aplica en ambos sentidos del scroll.
Es un recurso muy utilizado hoy en día, muchas webs con un buen diseño suelen aplicar animaciones de parallax.
Pero no es un recurso que haya sido creado hace poco, de hecho el concepto de parallax lo inventó Disney para dotar a sus películas de profundidad.
En este vídeo puedes ver al detalle la explicación sobre cómo aplica este concepto Disney
También tienes este link con algo más de teoría sobre este concepto y más ejemplos de parallax usados en diferentes webs.
El efecto de parallax también se puede aplicar a imágenes de fondo.
En el ejemplo del codepen, puedes verlo en la segunda sección.
Es la imagen de fondo la que está aplicando un desplazamiento diferente al resto de nodos.
En este caso estoy usando una imagen que está sobrepasando su contenedor padre, pero tiene un `overflow: hidden;`
y recorta la imagen.
Realmente está haciendo el mismo efecto, pero al aplicarlo sobre una caja delimitada y con el recorte del `overflow`
, da una sensación diferente. Pero se alimenta del mismo principio.
Aunque en este caso no se basa en que capa está más cerca de nosotros para moverla a más velocidad, simplemente se basa en mover la imagen a una posición diferente para darle ese efecto visual.
Como ves puedes jugar de diferentes maneras con los desplazamientos sin seguir la regla de que capa está más cerca de nosotros para desplazarla más rápida.
Y ahora mira esta sección (es la tercera sección del codepen):
Este ejemplo sí que sigue las reglas de parallax como tal.
Las capas más cercanas a nuestro punto de vista se mueven más rápido y las capas más alejadas, se mueven más despacio.
Te voy a enseñar como está creado este escenario.
Tenemos 5 capas diferentes, mira:
Voy a ir desde la capa más alejada a nuestro punto de vista hacia a la capa más cercana.
La capa más alejada es el fondo.
Después, más cerca de nuestro punto de vista y por encima de esa capa, tenemos las estrellas. (Realmente es transparente, pero he aplicado un color de fondo para que veas las estrellas).

Luego estará por encima la capa del planeta. (He aplicado un borde para que veas visualmente el tamaño de la imagen).

Después, tendremos más cerca aún las montañas. (He aplicado un borde para que veas visualmente el tamaño de la imagen).

Y por último y muy cerca de nosotros, el suelo y las rocas. (He aplicado un borde para que veas visualmente el tamaño de la imagen).

Hay que tener en cuenta un detalle muy importante, todas las imágenes ocupan el mismo tamaño.
Si nuestro escenario completo ocupa `2000px`
de ancho y `1000px`
de alto, las diferentes capas tienen que tener también ese tamaño.
Por ejemplo, la imagen del planeta ocupa lo que tiene que ocupar, pero se mantiene el fondo transparente para mantener el mismo tamaño de imagen.
El espacio transparente en esas imágenes es necesario para el parallax.
Lo que haremos por CSS será posicionar el fondo de manera estática y las demás capas de manera absoluta por encima del fondo con la propiedad `z-index`
.
Entonces quedaría así el SCSS.
.c-section{
max-width: 100%;
width: 100%;
display: block;
padding: 0px 20px;
margin: 100px auto;
position: relative;
z-index: 3;
&__scene{
display: flex;
align-items: center;
width: 100%;
height: 100vh;
position: relative;
overflow: hidden;
}
&__layers{
display: block;
width: 100%;
position: relative;
overflow: hidden;
}
&__layer{
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: calc(100% + 100px);
z-index: 1;
&--bg{
position: static;
}
&--stars{
z-index: 2;
transform: translateY( calc( ( var(--ty) * 0.2) ) );
}
&--planet{
z-index: 3;
transform: translateY( calc( ( var(--ty) * 0.5) ) );
}
&--mountain{
z-index: 4;
transform: translateY( calc( ( var(--ty) * 0.8) ) );
}
&--floor{
z-index: 5;
transform: translateY( calc( ( var(--ty) * 1) ) );
}
}
&__layer-image{
width: 100%;
display: block;
height: 100%;
object-fit: cover;
}
}
No te fijes ahora en el `transform`
con la variable de CSS: `--ty`
, después te explicaré qué es esto.
Bien, ya has visto que es el efecto parallax en web y has entendido cómo funciona.
¿Cómo lo aplicas ahora?
Te cuento, siempre puedes hacer tú todos los cálculos, pero también puedes ayudarte con una librería de JavaScript que seguramente habrá sido probada y tendrá mayor soporte que hacerlo tú todo desde 0 ahora mismo.
Pero tú haz lo que prefieras.
Te dejo diferentes librerías de JavaScript que puedes utilizar para ayudarte a aplicar un efecto de parallax:
Yo para este ejemplo he usado la librería BasicScroll.js
Pero tú usa la que más te guste.
Al final da igual lo que uses mientras apliques bien los conceptos.
Te voy a resumir que hace esta librería para no extenderme demasiado y poder seguir el ejercicio.
Esta librería, BasicScroll.js, sirve para obtener un valor en función del scroll realizado.
Pero no sólo eso, también tiene en cuenta desde donde tiene que empezar a calcular y hasta dónde debe terminar de hacer dichos cálculos.
Esto mejorará el rendimiento de la web ya que sólo estarán aplicándose las animaciones de desplazamiento mientras estemos en la sección afectada.
El valor obtenido lo calcula a partir de un valor inicial y uno final que tú decides y en función del porcentaje de scroll que se realice entre dos puntos que tú también defines, te devuelve un valor.
Ese valor lo añade como una variable de CSS3 con el nombre que queramos al nodo deseado.
Por lo que dejamos en nuestro CSS los cálculos necesarios con la variable deseada.
Los cálculos en este ejercicio son con el `transform: translateY();`
con la variable `--ty`
como has visto antes.
Esta variable de CSS irá cambiando el valor en función del scroll realizado, por lo que éste cálculo irá variando su resultado, entonces el propio CSS aplicará la animación del movimiento.
Veamos ahora línea a línea el JavaScript.
let parallax_sections = document.querySelectorAll('.js-parallax-section');
for (let parallax_section of parallax_sections) {
let _from = parallax_section.getAttribute("data-from") || '0px';
let _to = parallax_section.getAttribute("data-to") || '100px';
let instance = basicScroll.create({
elem: parallax_section,
from: 'top-middle',
to: 'bottom-middle',
direct: true,
props: {
'--ty': {
from: _from,
to: _to,
}
}
})
instance.start();
}
Como puedes ver tengo un bucle para recorrer todas las secciones que tengo de parallax y crear una instancia de cada sección.
`elem`
: el elemento al que tiene que afectar. Ese nodo será donde se añadirá la variable de CSS.`direct: true`
, para decir que añada la variable al nodo afectado.`from`
y`to`
aceptan varios argumentos, yo usaré la opción relativa que permite la librería.
Aquí tienes información más detallada sobre `from`
y `to`
:
BasicScroll.js: from and to.
La opción relativa se escribe de esta manera:
Donde `elem`
será el punto del elemento que escojamos y viewport será el punto de nuestra ventana que escojamos.
Por ejemplo, `top-middle`
en `from`
quiere decir que la animación empieza cuando el top del elemento toca el centro de la ventana.
Y para saber cuando termina la animación hacemos lo mismo en la propiedad `to`
.
En este caso `bottom-middle`
, y esto quiere decir que la animación acabará cuando el bottom de nuestro elemento toque con el centro de la ventana.
Y ahora en `props`
podemos pasarle diferentes parámetros.
En este caso solo usaremos una variable, y la llamaremos `--ty`
.
Esto a su vez nos da la opción de declarar el valor de esa variable desde el inicio hasta el final del recorrido.
`from`
: el valor de inicio de nuestra animación. Aquí estoy obteniendo el valor que tiene el atributo data-from para poder asignar los valores desde el propio html.
`to`
: el valor final de nuestra animación. Aquí estoy obteniendo el valor del atributo data-to.
En el ejemplo de las cajas (el primero del codepen), está cogiendo de `0px`
a `100px`
.
Resumiendo y traduciendo todo el código de JavaScript visto a la vez, quiere decir esto:
Cuando cualquier nodo con la clase `js-parallax-section`
entre su parte top en el centro de la pantalla, se empezará a calcular el valor que debe tener la variable `--ty`
, que será entre `0`
y `100px`
en el caso del ejercicio 1, el de las cajas.
`0px`
para el punto inicial de la animación y `100px`
para el punto final de la animación.
El punto final de animación será cuando el `bottom`
del nodo `js-parallax-section`
toque la parte central de la pantalla.
Entonces, por una regla de 3, en el centro de la sección, significa que estaremos en un 50% de nuestra animación.
Según los valores que hemos declarado, esto querrá decir que la variable `--ty`
debería valer `50px`
.
Vale ya sabes cómo funciona esta librería, pues ahora veamos que he hecho para añadir el parallax al escenario del planeta.
Ejemplo del ejercicio del efecto parallax en web del planeta
Lo primero sería añadir las diferentes capas en el HTML, con las imágenes deseadas y como dijimos, deben tener el mismo tamaño todas.
<div class="c-section js-parallax-section" data-from="50px" data-to="-50px">
<div class="c-section__scene">
<div class="c-section__layers">
<div class="c-section__layer c-section__layer--bg">
<img class="c-section__layer-image" src="https://raw.githubusercontent.com/rgldev/sample-images/master/parallax_scene_2/1x/Fondo.png">
</div>
<div class="c-section__layer c-section__layer--stars o-anim-ty">
<img class="c-section__layer-image" src="https://raw.githubusercontent.com/rgldev/sample-images/master/parallax_scene_2/1x/Estrellas.png">
</div>
<div class="c-section__layer c-section__layer--planet o-anim-ty">
<img class="c-section__layer-image" src="https://raw.githubusercontent.com/rgldev/sample-images/master/parallax_scene_2/1x/Planeta.png">
</div>
<div class="c-section__layer c-section__layer--mountain o-anim-ty">
<img class="c-section__layer-image" src="https://raw.githubusercontent.com/rgldev/sample-images/master/parallax_scene_2/1x/Montanas.png">
</div>
<div class="c-section__layer c-section__layer--floor o-anim-ty">
<img class="c-section__layer-image" src="https://raw.githubusercontent.com/rgldev/sample-images/master/parallax_scene_2/1x/Suelo.png">
</div>
</div>
</div>
</div>
En el SCSS, haremos que las capas estén posicionadas de manera absoluta como hemos visto antes:
.o-anim-ty{
will-change: transform;
transition: transform 0.1s linear;
}
.c-section{
max-width: 100%;
width: 100%;
display: block;
padding: 0px 20px;
margin: 100px auto;
position: relative;
z-index: 3;
&__scene{
display: flex;
align-items: center;
width: 100%;
height: 100vh;
position: relative;
overflow: hidden;
}
&__layers{
display: block;
width: 100%;
position: relative;
overflow: hidden;
}
&__layer{
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: calc(100% + 100px);
z-index: 1;
&--bg{
position: static;
}
&--stars{
z-index: 2;
transform: translateY( calc( ( var(--ty) * 0.2) ) );
}
&--planet{
z-index: 3;
transform: translateY( calc( ( var(--ty) * 0.5) ) );
}
&--mountain{
z-index: 4;
transform: translateY( calc( ( var(--ty) * 0.8) ) );
}
&--floor{
z-index: 5;
transform: translateY( calc( ( var(--ty) * 1) ) );
}
}
&__layer-image{
width: 100%;
display: block;
height: 100%;
object-fit: cover;
}
}
`__layers`
tiene `position: relative;`
y `overflow: hidden;`
para recortar las capas si estas sobresalen de este nodo.
La primera capa dentro de `__layers`
será el fondo, que no tendrá animación, y esta capa la dejamos como estática para que su tamaño sea el que determine el ancho y alto del contenedor padre.
Las demás capas estarán una encima de otra, esto lo haremos con la propiedad `z-index`
.
Es decir:
Las estrellas tendrán `z-index: 2;`
.
La capa del planeta `z-index: 3;`
.
Las montañas `z-index: 4;`
.
El suelo con las rocas `z-index: 5;`
.
Además de esto, cada capa se debe mover a una velocidad diferente, entonces dejamos en las capas un calculo en el valor del `transform: translateY();`
.
En este caso lo que hago es poner que la capa de las estrellas se mueva un 20% del valor de `--ty`
.
El planeta un 50%.
Las montañas un 80%.
El suelo un 100% del valor de `--ty`
.
Entonces según este cálculo, la capa del planeta por ejemplo se moverá en total entre `-25px`
y `25px`
.
En cambio, la capa del suelo, se moverá entre `-50px`
y `50px`
, es decir, a mayor velocidad.
Y en JavaScript, sería hacer los cálculos de desplazamiento del scroll, que ya los hace la librería (así me ahorro tener que hacerlo yo a mano).
Yo tan solo le digo que quiero que se desplace de `50px`
a '-50px'
las capas del escenario en el eje Y.
`50px`
será el valor de la variable `--ty`
al inicio de la animación y al final valdrá `-50px`
.
Y listo, ya tendríamos un escenario muy chulo con una buena animación de parallax al hacer scroll.
Recapitulando:
Al moverse un nodo más despacio que el resto, simula estar más lejos de nuestro punto de vista, en cambio al moverse un nodo más deprisa, parece que esté más cerca.
El truco es aplicar diferentes velocidades de desplazamiento según si está el plano más cerca o menos de nosotros.
Aunque puedes simplemente aplicar una animación de desplazamiento a un nodo para crear el efecto visual aunque la capa esté más lejos que otros nodos, como por ejemplo a imágenes de fondo (como hemos visto en el ejemplo 2).
Pero el principio del efecto parallax en web se basa realmente en que está más cerca y que está más lejos para moverlo con mayor o menor velocidad.
Bueno, pues ya está.
Si aplicas esta animación en alguna web envíamelo por Instagram..
Haré una recopilación para enseñar las mejores en otro vídeo.
Si te ha gustado el artículo, apóyame para que traiga más contenido como este.
Dale a like al vídeo y comenta, suscríbete al canal, pero sobretodo, comparte con tus amigos front end, quizás alguno quiera aplicar esta animación en alguna web.
Nos vemos muy pronto.
Un abrazo y … ¡a maquetar!
Si quieres, puedes ver otros artículos como este aquí:
Animaciones web en función del scroll