분할 텍스트 애니메이션 빌드

분할 문자 및 단어 애니메이션을 빌드하는 방법에 대한 기본 개요입니다.

이 게시물에서는 텍스트 분할 애니메이션과 웹용 상호작용이 최소화되고 액세스 가능하며 여러 브라우저에서 작동합니다. 데모 사용해 보기

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph> 데모

동영상을 선호한다면 이 게시물의 YouTube 버전을 참고하세요.

개요

텍스트 분할 애니메이션은 놀랍습니다. 우리는 이 모든 것의 겉핥기보다 이 게시물에서는 애니메이션을 적용할 수 있지만, 실제로 이러한 모델을 시작하겠습니다. 목표는 점진적으로 애니메이션을 적용하는 것입니다. 텍스트는 다음에서 읽을 수 있어야 합니다. 애니메이션이 적용되어 있는 것을 볼 수 있습니다 분할 텍스트 모션 효과로 너무 많아서 혼란을 야기할 수 있으므로 HTML만 조작하거나 사용자가 모션에 동의하면 모션 스타일을 적용합니다.

다음은 워크플로 및 결과에 대한 일반적인 개요입니다.

  1. 감소된 움직임 조건부 준비 CSS 및 JS용 변수입니다.
  2. 텍스트 분할 유틸리티 준비 있습니다.
  3. 페이지에서 조건문 및 유틸리티 조정 있습니다.
  4. CSS 전환 및 애니메이션 쓰기 단어와 단어의 조합 (획기적인 부분!)입니다.

다음은 조건부 결과의 미리보기입니다.

<ph type="x-smartling-placeholder">
</ph> Elements 패널이 열려 있고 축소된 모션이 &#39;축소&#39;로 설정된 Chrome DevTools의 스크린샷 h1은 분할되지 않은 상태로 <ph type="x-smartling-placeholder">
</ph> 사용자가 작은 움직임을 선호함: 텍스트를 읽을 수 있음 / 분할되지 않음

사용자가 모션을 줄이고 싶은 경우 HTML 문서는 그대로 두고 애니메이션을 적용할 수 있습니다. 움직임이 괜찮다면 조각으로 자릅니다. 이 JavaScript가 텍스트를 문자별로 분할한 후 HTML의 미리보기입니다.

<ph type="x-smartling-placeholder">
</ph> Elements 패널이 열려 있고 축소된 모션이 &#39;축소&#39;로 설정된 Chrome DevTools의 스크린샷 h1은 분할되지 않은 상태로 <ph type="x-smartling-placeholder">
</ph> 사용자가 움직임에 문제가 없음 텍스트가 여러 개로 분할됨 <span> 요소

모션 조건문 준비 중

편리하게 사용 가능한 @media (prefers-reduced-motion: reduce) 미디어 쿼리는 CSS 및 JavaScript를 반환합니다. 이 미디어 쿼리는 결정할 수 있습니다. CSS 미디어 쿼리는 보류하는 데 사용됩니다. 자바스크립트 미디어 쿼리는 HTML 조작을 보류합니다.

CSS 조건부 준비

저는 PostCSS를 사용하여 미디어 쿼리 레벨 5의 문법을 사용 설정했습니다. 변수로 변환합니다.

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

JS 조건부 준비하기

JavaScript에서 브라우저는 미디어 쿼리를 확인하는 방법을 제공합니다. 해체하는 를 사용하여 미디어 쿼리 확인에서 불리언 결과를 추출하고 이름을 바꿉니다.

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

그런 다음 motionOK를 테스트하고 사용자가 변경하지 않은 경우에만 문서를 변경할 수 있습니다. 동작 축소를 요청했습니다.

if (motionOK) {
  // document split manipulations
}

PostCSS를 사용하여 @nest 구문을 중첩 초안 1. 이렇게 하면 애니메이션에 관한 모든 로직과 한곳에서 관리할 수 있습니다.

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

PostCSS 맞춤 속성과 자바스크립트 불리언을 사용하여 조건부로 효과를 업그레이드합니다 그러면 다음 섹션으로 넘어가서 문자열을 요소로 변환하기 위해 JavaScript를 분석합니다.

텍스트 분할

텍스트 문자, 단어, 선 등은 CSS 또는 JS로 개별적으로 애니메이션 처리할 수 없습니다. 효과를 얻으려면 상자가 필요합니다. 각 문자에 애니메이션을 적용하려면 각 문자는 요소여야 합니다. 각 단어에 애니메이션을 적용하고 싶다면 단어는 요소여야 합니다.

  1. 문자열을 요소로 분할하는 JavaScript 유틸리티 함수 만들기
  2. 이러한 유틸리티 사용량 조정
를 통해 개인정보처리방침을 정의할 수 있습니다.

문자 분할 유틸리티 함수

문자열을 가져와 각각을 반환하는 함수부터 재미있게 시작할 수 있습니다. 문자입니다.

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

확산 구문이 이 작업을 신속하게 수행하는 데 큰 도움이 되었습니다.

단어 분할 유틸리티 함수

문자 분할과 마찬가지로 이 함수는 문자열을 가져와 각 단어를 반환합니다. 배열에 포함됩니다.

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

split() 드림 메서드를 사용하면 슬라이스할 문자를 지정할 수 있습니다. 단어 간 분할을 나타내는 빈 공백을 전달했습니다.

상자 유틸리티 함수 만들기

효과는 각 문자에 상자가 필요하며, 이러한 함수에서 map() 드림 span() 함수로 호출됩니다. 다음은 span() 함수입니다.

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

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

  return node
}

--index라는 맞춤 속성이 배열 위치입니다. 문자 애니메이션을 위한 상자를 갖는 것도 좋지만, CSS에 사용할 색인을 추가하는 것은 겉보기에는 적지만 큰 영향을 미치는 것처럼 보입니다. 이러한 큰 영향에서 가장 주목할 만한 것은 시차하지 않습니다. 시차를 두고 애니메이션을 오프셋하는 방법으로 --index를 사용할 수 있습니다. 보여드리겠습니다

유틸리티 결론

완성된 splitting.js 모듈:

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)

다음은 이러한 byLetter()byWord() 함수를 가져오고 사용하는 것입니다.

분할 조정

분할 유틸리티를 사용할 준비가 되었다면, 이를 모두 합치면 다음과 같은 이점이 있습니다.

  1. 분할할 요소 찾기
  2. 텍스트를 분할하고 텍스트를 HTML로 대체

그런 다음 CSS가 인계되어 요소 / 상자에 애니메이션을 적용합니다.

요소 찾기

속성과 값을 사용해 텍스트 분할 방법을 설명합니다. 저는 이러한 선언적 옵션을 을 HTML에 삽입합니다. split-by 속성은 JavaScript에서 요소를 만들고 문자나 단어에 대한 상자를 만들 수 있습니다. 속성 letter-animation 또는 word-animation는 CSS에서 요소를 타겟팅하는 데 사용됩니다. 하위 요소를 생성하고 변환과 애니메이션을 적용할 수 있습니다.

다음은 두 속성을 보여주는 HTML 샘플입니다.

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

JavaScript에서 요소 찾기

속성 존재에 대한 CSS 선택자 문법을 사용하여 요소:

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

CSS에서 요소 찾기

또한 CSS의 속성 정보 선택기를 사용하여 모든 문자 애니메이션을 제공했습니다. 동일한 기본 스타일을 사용할 수 있습니다. 나중에 속성 값을 사용하여 사용하여 효과를 얻을 수 있습니다.

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

제자리에서 텍스트 분할

JavaScript에서 찾은 분할 타겟 각각에 대해 텍스트를 각 문자열을 <span>에 매핑합니다. 우리는 그런 다음 요소의 텍스트를 앞에서 만든 상자로 바꿉니다.

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)
  }
})

오케스트레이션 마무리

index.js 완료:

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)
  })
}

이 JavaScript는 다음 영어로 읽을 수 있습니다.

  1. 도우미 유틸리티 함수를 가져옵니다.
  2. 사용자의 움직임이 괜찮은지 확인합니다. 아무런 변화가 없으면 아무 조치도 취하지 않습니다.
  3. 분할하려는 각 요소
    1. 원하는 분할 방식에 따라 분할하세요.
    2. 텍스트를 요소로 대체합니다.

애니메이션 및 전환 분할

위의 분할 문서 조작을 통해 방금 수많은 잠재적인 애니메이션과 효과를 살펴보겠습니다. 몇 가지 링크가 있습니다. 를 참조하세요.

이제 이 기능으로 무엇을 할 수 있는지 보여주세요. 4가지 CSS 기반 애니메이션과 사용할 수 있습니다. 🤓

문자 분할

분할 문자 효과의 기반으로 다음 CSS가 도움이 됩니다. 모든 전환과 애니메이션을 모션 미디어 쿼리 뒤에 배치하고 그런 다음 각각의 새 하위 문자 span에 표시 속성과 원하는 스타일을 지정합니다. 공백과 관련된 항목:

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

공백 스타일은 공백만 있는 범위, 레이아웃 엔진에서 접히지 않습니다. 이제 재미있는 스테이트풀(Stateful)로 넘어갑니다.

전환 분할 문자 예

이 예에서는 텍스트 분할 효과로 CSS 전환을 사용합니다. 전환의 경우 엔진에 애니메이션을 적용하기 위한 상태가 필요하므로 세 가지 상태를 선택했습니다. 마우스 오버, 문장 내 마우스 오버, 문자 위로 마우스를 가져갑니다.

사용자가 컨테이너라고 하는 문장 위로 마우스를 가져가면 마치 아이들이 아이를 더 멀리 떨어뜨린 것처럼 말이죠. 그런 다음 사용자가 전달하겠습니다.

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

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

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

분할 문자 애니메이션 예시

이 예에서는 사전 정의된 @keyframe 애니메이션을 사용하여 각각을 무한으로 애니메이션 처리합니다. 인라인 맞춤 속성 색인을 활용하여 있습니다.

@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;
  }
}
드림

단어 분할

다음 예에서 Flexbox는 컨테이너 유형으로 작동했습니다. ch 단위를 건강한 간격 길이로 활용합니다.

word-animation {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 1ch;
}
드림 <ph type="x-smartling-placeholder">
</ph>
단어 사이의 간격을 보여주는 Flexbox devtools

단어 전환 예시

이 전환 예에서는 마우스 오버를 다시 사용합니다. 효과가 처음에는 클릭하기만 하면 상호작용과 스타일이 오직 마우스 오버로만 할 수 있습니다.

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

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

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

단어 분할 애니메이션 예시

이 애니메이션 예에서는 CSS @keyframes를 다시 사용하여 지그재그로 지그재그로 한 개의 일반적인 텍스트 단락의 무한 애니메이션

[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;
  }
}

결론

이제 내가 어떻게 했는지 알았으니 어떻게 하면 어떨까?! 🙂

접근방식을 다각화하고 웹에서 빌드하는 방법을 모두 알아보겠습니다. Codepen을 만들거나 데모를 호스트하고 트윗해 주시면 커뮤니티 리믹스 섹션을 참조하세요.

소스

더 많은 데모 및 아이디어

커뮤니티 리믹스