Cómo crear animaciones de texto dividido

Descripción general de cómo crear animaciones con letras y palabras divididas

En esta publicación, compartiré ideas sobre cómo resolver animaciones de texto dividido y interactivas para la Web que son mínimas, accesibles y funcionan en todos los navegadores. Prueba la demostración.

. Demostración

Si prefieres ver un video, aquí tienes una versión de YouTube de esta publicación:

Descripción general

Las animaciones con texto dividido pueden ser sorprendentes. Apenas exploraremos la superficie de potencial de animación en esta publicación, pero proporciona una base para crear . El objetivo es hacer animaciones progresivamente. El texto debe ser legible por de forma predeterminada, con la animación creada en la parte superior. Los efectos de movimiento de texto dividido ser extravagante y potencialmente disruptivo, por lo que solo manipularemos HTML, o aplicar estilos de movimiento si el usuario está bien con el movimiento.

Esta es una descripción general del flujo de trabajo y los resultados:

  1. Preparar condicional de movimiento reducido variables para CSS y JS.
  2. Prepara utilidades de texto dividido en JavaScript:
  3. Organiza los condicionales y utilidades de la página de carga de trabajo.
  4. Cómo escribir transiciones y animaciones de CSS para letras y palabras (la parte rad).

A continuación, se muestra una vista previa de los resultados condicionales que vamos a obtener:

captura de pantalla de las Herramientas para desarrolladores de Chrome con el panel de Elements abierto y un movimiento reducido en “reduce” y el h1 se muestra sin dividir
El usuario prefiere reducir el movimiento: el texto es legible o no está dividido

Si un usuario prefiere reducir el nivel de movimiento, dejamos el documento HTML tal como está y no hacemos nada. animación. Si el movimiento está bien, vamos a dividirlo en pedazos. Este es un vista previa del HTML después de que JavaScript dividió el texto por letra.

captura de pantalla de las Herramientas para desarrolladores de Chrome con el panel de Elements abierto y un movimiento reducido en “reduce” y el h1 se muestra sin dividir
El usuario está bien con el movimiento. texto dividido en varios <span> elementos

Cómo preparar condicionales de movimiento

Se usará la consulta de medios disponible @media (prefers-reduced-motion: reduce) de CSS y JavaScript en este proyecto. Esta consulta de medios es nuestro condicional principal para decidir dividir el texto o no. La consulta de medios de CSS se usará para retener transiciones y animaciones, mientras que la consulta de medios de JavaScript se usará para retener la manipulación de HTML.

Cómo preparar el condicional de CSS

Usé PostCSS para habilitar la sintaxis de las consultas de medios de nivel 5, donde puedo almacenar un valor booleano de consulta de medios en una variable:

@custom-media --motionOK (prefers-reduced-motion: no-preference);

Prepara el condicional de JS

En JavaScript, el navegador proporciona una forma de verificar las consultas de medios. Utilicé desestructuración para extraer y cambiar el nombre del resultado booleano de la verificación de consulta de medios:

const {matches:motionOK} = window.matchMedia(
  '(prefers-reduced-motion: no-preference)'
)

Entonces, puedo probar motionOK y solo cambiar el documento si el usuario no solicitar que se reduzca el movimiento.

if (motionOK) {
  // document split manipulations
}

Puedo verificar el mismo valor usando PostCSS para habilitar la sintaxis @nest de Borrador de Nesting 1. Esto me permite almacenar toda la lógica de la animación y los requisitos de estilo de la padres e hijos en un solo lugar:

letter-animation {
  @media (--motionOK) {
    /* animation styles */
  }
}

Con la propiedad personalizada de PostCSS y un booleano de JavaScript, estamos listos para actualizar el efecto de forma condicional. Eso nos lleva a la siguiente sección, en la que desglosar JavaScript para transformar cadenas en elementos.

División del texto

Las letras de texto, palabras, líneas, etc., no se pueden animar individualmente con CSS o JS. Para lograr el efecto, necesitamos cajas. Si queremos animar cada letra, entonces cada letra debe ser un elemento. Si queremos animar cada palabra, entonces cada la palabra debe ser un elemento.

  1. Crear funciones de utilidad de JavaScript para dividir cadenas en elementos
  2. Organiza el uso de estas utilidades

Función de utilidad de división de letras

Un lugar divertido para comenzar es con una función que toma una cadena y devuelve cada una letra en una matriz.

export const byLetter = text =>
  [...text].map(span)

El dispersión la sintaxis de ES6 realmente ayudó a que esa tarea fuera una tarea rápida.

Función de utilidad de división de palabras

De manera similar a la división de letras, esta función toma una cadena y devuelve cada palabra en un array.

export const byWord = text =>
  text.split(' ').map(span)

El split() en cadenas de JavaScript nos permite especificar los caracteres que se deben segmentar. Pasé un espacio vacío, que indica una división entre palabras.

Hacer que las cajas funcionen

El efecto requiere cuadros para cada letra, y vemos en esas funciones, que map() se llama con una función span(). Esta es la función span().

const span = (text, index) => {
  const node = document.createElement('span')

  node.textContent = text
  node.style.setProperty('--index', index)

  return node
}

Es fundamental tener en cuenta que una propiedad personalizada llamada --index se configura con la posición del array. Tener los cuadros para las animaciones de letras es genial, tener un índice para usar en CSS es una adición aparentemente pequeña con un gran impacto. Lo más notable en este gran impacto es asombroso. Podremos usar --index como una forma de compensar las animaciones para una imagen escalonada. estilo.

Conclusión de servicios públicos

El módulo splitting.js está completo:

const span = (text, index) => {
  const node = document.createElement('span')

  node.textContent = text
  node.style.setProperty('--index', index)

  return node
}

export const byLetter = text =>
  [...text].map(span)

export const byWord = text =>
  text.split(' ').map(span)

A continuación, importa y usa estas funciones byLetter() y byWord().

Organización de divisiones

Ahora que las utilidades de división están listas para usar, reunir todo significa lo siguiente:

  1. Encuentra qué elementos dividir
  2. Dividir los elementos y reemplazar el texto por HTML

Después de eso, CSS toma el control y animará los elementos y cuadros.

Buscar elementos

Elegí usar atributos y valores para almacenar información sobre la animación y cómo dividir el texto. Me gustó colocar estas opciones declarativas en el archivo HTML. El atributo split-by se usa de JavaScript para buscar y crea cuadros para letras o palabras. El atributo Se usa letter-animation o word-animation desde el CSS hasta el elemento de destino secundarios y aplicar transformaciones y animaciones.

Este es un ejemplo de código HTML que muestra los dos atributos:

<h1 split-by="letter" letter-animation="breath">animated letters</h1>
<h1 split-by="word" word-animation="trampoline">hover the words</h1>

Cómo buscar elementos en JavaScript

Usé la sintaxis del selector CSS en la presencia de atributos para recopilar la lista de elementos que quieren que se divida el texto:

const splitTargets = document.querySelectorAll('[split-by]')

Cómo buscar elementos de CSS

También usé el selector de presencia de atributos en CSS para dar animaciones de todas las letras. los mismos estilos de base. Más adelante, usaremos el valor del atributo para agregar estilos para lograr un efecto.

letter-animation {
  @media (--motionOK) {
    /* animation styles */
  }
}

División del texto en el lugar

Para cada uno de los objetivos de división que encontremos en JavaScript, dividiremos su texto según el valor del atributo y asignar cada cadena a un <span>. Podemos Luego, reemplazamos el texto del elemento con los cuadros que hicimos:

splitTargets.forEach(node => {
  const type = node.getAttribute('split-by')
  let nodes = null

  if (type === 'letter') {
    nodes = byLetter(node.innerText)
  }
  else if (type === 'word') {
    nodes = byWord(node.innerText)
  }

  if (nodes) {
    node.firstChild.replaceWith(...nodes)
  }
})

Conclusión de la organización

index.js completado:

import {byLetter, byWord} from './splitting.js'

const {matches:motionOK} = window.matchMedia(
  '(prefers-reduced-motion: no-preference)'
)

if (motionOK) {
  const splitTargets = document.querySelectorAll('[split-by]')

  splitTargets.forEach(node => {
    const type = node.getAttribute('split-by')
    let nodes = null

    if (type === 'letter')
      nodes = byLetter(node.innerText)
    else if (type === 'word')
      nodes = byWord(node.innerText)

    if (nodes)
      node.firstChild.replaceWith(...nodes)
  })
}

El código JavaScript se puede leer en el siguiente inglés:

  1. Importar algunas funciones auxiliares de utilidad.
  2. Comprueba si el movimiento es correcto para este usuario, si no hacer nada.
  3. Por cada elemento que se desea dividir.
    1. Divídelos según cómo quieren dividirse.
    2. Reemplazar el texto por elementos

Cómo dividir animaciones y transiciones

La manipulación de la división de documentos anterior acaba de desbloquear una gran cantidad de posibles animaciones y efectos con CSS o JavaScript. Hay algunos vínculos al final de este artículo para inspirar tu potencial de división.

Es hora de demostrar lo que puedes hacer con esto. Compartiré 4 animaciones basadas en CSS y las transiciones. 🤓

Dividir letras

Como base para los efectos de las letras de división, descubrí que el siguiente CSS tiene las siguientes características: útil. Coloqué todas las transiciones y animaciones detrás de la consulta de medios de movimiento y Luego, asigna a cada letra secundaria nueva span una propiedad de visualización y un estilo para qué con los espacios en blanco:

[letter-animation] > span {
  display: inline-block;
  white-space: break-spaces;
}

El estilo de espacios en blanco es importante para que los intervalos sean solo un espacio, no sean contraídos por el motor de diseño. Ahora pasemos a la diversión con estados.

Ejemplo de letras divididas de transición

En este ejemplo, se usan transiciones de CSS para el efecto de texto dividido. Con las transiciones, necesitan estados entre los que se debe animar el motor y elegí tres estados: no colocar el cursor sobre una oración, colocar el cursor sobre una letra

Cuando el usuario coloca el cursor sobre la oración, es decir, el contenedor, reduzco la escala niños como si el usuario los empujara más lejos. Luego, cuando el usuario coloca el cursor sobre la menciono.

@media (--motionOK) {
  [letter-animation="hover"] {
    &:hover > span {
      transform: scale(.75);
    }

    & > span {
      transition: transform .3s ease;
      cursor: pointer;

      &:hover {
        transform: scale(1.25);
      }
    }
  }
}

Ejemplo de animación de letras divididas

En este ejemplo, se usa una animación @keyframe predefinida para animar cada una de forma infinita y aprovecha el índice de propiedades personalizadas intercalados para crear un flujo escalonado efecto.

@media (--motionOK) {
  [letter-animation="breath"] > span {
    animation:
      breath 1200ms ease
      calc(var(--index) * 100 * 1ms)
      infinite alternate;
  }
}

@keyframes breath {
  from {
    animation-timing-function: ease-out;
  }
  to {
    transform: translateY(-5px) scale(1.25);
    text-shadow: 0 0 25px var(--glow-color);
    animation-timing-function: ease-in-out;
  }
}

Dividir palabras

Flexbox funcionó como tipo de contenedor en estos ejemplos. Aprovecha la unidad ch como una longitud de espacio saludable.

word-animation {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 1ch;
}
Herramientas para desarrolladores de Flexbox que muestran la brecha entre palabras

Ejemplo de palabras divididas de transición

En este ejemplo de transición, vuelvo a usar el cursor sobre un elemento. Como el efecto inicialmente oculta la contenido hasta que coloques el cursor sobre ellos, me aseguré de que la interacción y los estilos solo se aplicaran si el dispositivo pudiera colocar el cursor sobre él.

@media (hover) {
  [word-animation="hover"] {
    overflow: hidden;
    overflow: clip;

    & > span {
      transition: transform .3s ease;
      cursor: pointer;

      &:not(:hover) {
        transform: translateY(50%);
      }
    }
  }
}

Ejemplo de animación de palabras divididas

En este ejemplo de animación, vuelvo a usar CSS @keyframes para crear una imagen animación infinita en un párrafo normal de texto.

[word-animation="trampoline"] > span {
  display: inline-block;
  transform: translateY(100%);
  animation:
    trampoline 3s ease
    calc(var(--index) * 150 * 1ms)
    infinite alternate;
}

@keyframes trampoline {
  0% {
    transform: translateY(100%);
    animation-timing-function: ease-out;
  }
  50% {
    transform: translateY(0);
    animation-timing-function: ease-in;
  }
}

Conclusión

Ahora que sabes cómo lo hice, ¿cómo lo harías? 🙂

Diversifiquemos nuestros enfoques y aprendamos todas las formas de desarrollar en la Web. Crea un CodePen o aloja tu propia demostración, envíame un tweet y la agregaré al Aquí tienes la sección Remixes de la comunidad.

Fuente

Más inspiración y demostraciones

Remixes de la comunidad