Transición de imágenes modificando atributos filter

A description of my image.

Empiezo por decir que la animación de filters CSS no he dado soporte a pantallas pequeñas. La animación se lanza con eventos de mousewheel y flechas arriba y abajo.

La animación se ha aplicado a:

  • Sobre las imágenes aplicando keyframes: transform: scale() y filter: blur() drop-shadow()
  • Usando transition sobre elemento decorativo bajo las imágenes clip-path()

Las diferentes imágenes son colcadas una sobre otra y cambiando su z-index en función del elemento activo

En este PEN se puede ver ejemplo. Como he comentado, sólo lo hice para desktop

See the Pen Transición de imágenes modificando atributos filter by Iván Albizu (@ivan_albizu) on CodePen.

Animación keyframes sobre las imágenes

El keyframes image-current se aplica en la primera parte de la animación a la imagen que actualmente se esté viendo, la animación consiste en hacer desaparecer la imagen cambiando su scale desde el estado normal hasta 0 y aplicando blur de 20px. La imagen tiene asociada un drop-shadow() que se convierte en transparente al finalizar la primera parte de la animación

La segunda parte de la animación esta basada en el keyframes image-next, se aplica a la imagen que entra. Inicialmente parte del mismo estado final de la imagen anterior para terminar con el estado por defecto, es decir, sin difuminar blur(0px), sin cambiar su tamaño scale(1) y con sombra drop-shadow(0px 20px 30px rgba(0,0,0,.9))

Las animaciones son disparadas cuando hemos añadido con javascript la clase “animating”

@keyframes image-current {
  from {
    filter: blur(0) drop-shadow(0px 20px 30px rgba(0,0,0,.9));
    transform: scale(1);
  }
  to {
    filter: blur(60px) drop-shadow(0px 20px 30px rgba(0,0,0,0));
    transform: scale(0);
  }
}
@keyframes image-next {
  from {
    filter: blur(60px) drop-shadow(0px 20px 30px rgba(0,0,0,0));
    transform: scale(0);
  }
  to {
    filter: blur(0) drop-shadow(0px 20px 30px rgba(0,0,0,.9));
    transform: scale(1);
  }
}

.animating {
  .content--active {
    img {
      animation: image-current .35s linear 0s forwards;
    }
  }
  .content--next {
    img {
      animation: image-next .35s linear .35s;
    }
  }
}

Animación con transition de clip-path

En la cara inferior de las imágenes se colocan dos “capas” con pseudo elementos before y after. Estos elementos contienen los colores y se irá cambiando su visibilidad mediante modificación de clip-path de elemento que sale y elemento que entra, básicamente es la misma idea que con las imágenes, pero sin keyframes y con transition

.grid {
  color: #fff;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: min-content 1fr;
  gap: 0px;
  grid-template-areas:
    "nav nav"
    "left right";
  height: 100vh;
  background: linear-gradient(to right, $color-3 50%, $color-1 50%);
  overflow: hidden;
  &__nav {
    grid-area: nav;
    padding: 10px 15px;
  }
  &__left {
    grid-area: left;
    display: grid;
    grid-template-columns: 60px repeat(2, 1fr) 60px;
    grid-template-rows: 1fr 13vw;
    gap: 0;
    height: 100%;
    .content {
      grid-area: 1 / 1 / 3 / 5;
      z-index: -1;
      display: grid;
      grid-template-columns: 60px repeat(2, 1fr) 60px;
      grid-template-rows: 1fr 13vw;
      padding-top: 30px;
      img {
        z-index: 5;
        grid-area: 1 / 1 / 3 / 5;
        justify-self: center;
        max-height: calc(100vh - 120px);
        transform: scale(0);
      }
      &::before,
      &::after {
        content: '';
        display: block;
      }
      &::before {
        grid-area: 2 / 1 / 3 / 3;
        clip-path: polygon(0 0, 100% 0, 100% 0, 0 0); //no se ve
        transition: clip-path .5s ease-in-out .2s;
      }
      &::after {
        grid-area: 2 / 3 / 3 / 5;
        clip-path: polygon(100% 0%, 100% 0%, 100% 100%, 100% 100%); //no se ve
        transition: clip-path .7s ease-in-out;
      }
      transition: clip-path .7s ease-in-out;
      &--active {
        z-index: 2;
        img {
          transform: scale(1);
          filter: blur(0) drop-shadow(0px 20px 30px rgba(0,0,0,.9));
        }
        &::before {
          clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); //se ve completo
        }
        &::after {
          clip-path: polygon(0 0, 100% 0%, 100% 100%, 0% 100%); //se ve completo
        }
      }
      &--next {
        z-index: 3;
        &::before {
          clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%); //se ve completo
        }
        &::after {
          clip-path: polygon(0 0, 100% 0%, 100% 100%, 0% 100%); //se ve completo
          transition: clip-path .7s ease-in-out;
        }
      }
      &--1 {
        &::before {
          background-color: #843577;
        }
        &::after {
          background-color: #53607A;
        }
      }
      &--2 {
        &::before {
          background-color: #357C97;
        }
        &::after {
          background-color: #F9DA4D;
        }
      }
      &--3 {
        &::before {
          background-color: #4D9B58;
        }
        &::after {
          background-color: #F27F30;
        }
      }
    }
    .pagination {
      grid-area: 1 / 1 / 3 / 2;
      place-self: center;
    }
  }
  &__right {
    grid-area: right;
    padding: 60px 50px 20px;
  }
}

Hay mucho más código, puede verse completo en mi GitHub