文字に簡単な動きをつける(HTML/CSS/JS)

前書き

文字に簡単な動きをつける方法(テキストアニメーション)を掲載しています。

目次

  1. まとめて動きをつける
  2. 目隠し → 文字表示
  3. 複数行に線を引く
  4. 複数の線を引く
  5. 下から徐々に表示する
  6. 真ん中から開く
  7. 色を反転する
  8. 縁取り → 塗りつぶし
  9. 1文字ずつ動きをつける
  10. 飛び出す
  11. そっと置く
  12. 引き上げる
  13. 降ってくる
  14. 滑り込み
  15. 回転
  16. ランダム
  17. アニメーションを繋げる
  18. その他
  19. 影を縞模様にして動かす
  20. 文字を円形に配置して回転させる
  21. 縁取りの線の色を変える
  22. 波のアニメーションを文字でマスクする
  23. 参考

まとめて動きをつける

目隠し → 文字表示

犬も歩けば棒に当たる
再開
疑似要素の位置文字の色を変化させています。

<div class="c01 active">犬も歩けば棒に当たる</div>

.c01{
  position: relative; color: transparent;
  &::before{
    content: ""; position: absolute; z-index: 1; top: 0%; right: 100%; bottom: 0%; left: 0%;
    background : #a675a5;
  }
  &.active{
    animation-name: kf_c01a;
    animation-duration: 0s;
    animation-delay: 0.5s;
    animation-fill-mode: forwards;
    &::before{
      animation-name: kf_c01b;
      animation-duration: 1s;
      animation-fill-mode: forwards;
    }
  }
}
@keyframes kf_c01a {
  100%{
    color: inherit;
  }
}
@keyframes kf_c01b {
  50%{
    left: 0%; right: 0%;
  }
  100%{
    left: 100%; right: 0%;
  }
}

複数行に線を引く

論より
証拠
再開
インライン要素に背景を指定して、背景の大きさと位置を変化させています。

<span class="c06 active">論より<br>証拠</span>

.c06{
  background-image: linear-gradient(to top, #a675a5 3px, transparent 3px);
  background-position: left bottom;
  background-repeat: no-repeat;
  background-size: 0% 100%;
  &.active{
    animation-name: kf_c06a, kf_c06b;
    animation-duration: 1s, 0s;
    animation-delay: 0s, 0.5s;
    animation-fill-mode: forwards;
  }
}
@keyframes kf_c06a {
  50%{
    background-size: 100% 100%;
  }
  100%{
    background-size: 0% 100%;
  }
}
@keyframes kf_c06b {
  100%{
    background-position: right bottom;
  }
}

複数の線を引く

花より団子
再開
複数の背景を指定して、背景の大きさと位置を変化させています。

<div class="c07 active">花より団子</div>

.c07{
  padding: 26px 26px;
  background-image:
    linear-gradient(to bottom, transparent 10px, #a675a5 10px, #a675a5 13px, transparent 13px),
    linear-gradient(to left,   transparent 10px, #a675a5 10px, #a675a5 13px, transparent 13px),
    linear-gradient(to top,    transparent 10px, #a675a5 10px, #a675a5 13px, transparent 13px),
    linear-gradient(to right,  transparent 10px, #a675a5 10px, #a675a5 13px, transparent 13px);
  background-repeat: no-repeat;
  background-size: 0% 100%, 100% 0%, 0% 100%, 100% 0%;
  background-position: top left, top left, right bottom, right bottom;
  &.active{
    animation-name: kf_c07a, kf_c07b;
    animation-duration: 1.5s, 0s;
    animation-delay: 0s, 0.75s;
    animation-timing-function: linear;
    animation-fill-mode: forwards,
  }
  @keyframes kf_c07a {
    50%{
      background-size: 100% 100%, 100% 100%, 100% 100%, 100% 100%;
    }
    100%{
      background-size: 0% 100%, 100% 0%, 0% 100%, 100% 0%;
    }
  }
  @keyframes kf_c07b {
    100%{
      background-position: right bottom, right bottom, top left, top left;
    }
  }
}

下から徐々に表示する

憎まれっ子世にはばかる
再開
背景をグラデーションにして文字でマスクしています。背景の位置を変化させています。

<div class="c02 active">憎まれっ子世にはばかる</div>

.c02{
  background-image: linear-gradient(to bottom, rgba(#333,0) 0%, rgba(#333,1) 50%);
  background-size: 100% 200%;
  background-position: 0% -100%;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  &.active{
    animation-name: kf_c02;
    animation-duration: 2s;
    animation-fill-mode: forwards;
  }
}
@keyframes kf_c02 {
  100%{
    background-position: 0% 100%;
  }
}

真ん中から開く

骨折り損のくたびれ儲け
再開
クリップパスを変化させています。

下記サイトを利用しています。

CSS clip-path maker

<div class="c03 active">骨折り損のくたびれ儲け</div>

.c03{
  color: #e7d4e3; background: #a675a5;
  clip-path: polygon(0 50%, 100% 50%, 100% 50%, 0 50%);
  &.active{
    animation-name: kf_c03;
    animation-duration: 1s;
    animation-fill-mode: forwards;
  }
}
@keyframes kf_c03 {
  100%{
    clip-path: polygon(0 100%, 100% 100%, 100% 0, 0 0);
  }
}

色を反転する

屁をひって尻つぼめる
再開
疑似要素に文字を入れて、文字と背景の色を変えて、重ねて配置しています。
疑似要素のクリップパスを変化させています。

<div class="c04 active" data-text="屁をひって尻つぼめる" >屁をひって尻つぼめる</div>

.c04{
  position: relative; color: #a675a5; background: #e7d4e3;
  &::after{
    content: attr(data-text);
    position: absolute; z-index: 1; top: 0; left: 0; width: 100%; height: 100%;
    color: #e7d4e3; background: #a675a5;
    clip-path: circle(0% at 50% 50%);
  }
  &.active{
    &::after{
      animation-name: kf_c04b;
      animation-duration: 1.5s;
      animation-fill-mode: forwards;
    }
  }
}
@keyframes kf_c04b {
  100%{
    clip-path: circle(75% at 50% 50%);
  }
}

縁取り → 塗りつぶし

年寄りの冷や水
再開
SVG画像に文字を入れて、縁取りの線の開始位置文字の色を変化させています。

下記ページを参考にしています。

SVG アニメーション(SMIL を使ったアニメーション)

<svg viewbox="0 0 720 90">
  <text class="s01 active" x="0" y="10">年寄りの冷や水</text>
</svg>

.s01{
  text-anchor: start; dominant-baseline: hanging;
  &.active{
    stroke-dasharray: 500; //線の間隔
    stroke: #333;
    animation-name: kf_s01;
    animation-duration: 2s;
    animation-fill-mode: forwards;
  }
}
@keyframes kf_s01 {
  0%{
    stroke-dashoffset: 500; //線の開始位置
    stroke-width: 1px;
    fill: transparent;
  }
  40% {
    fill: transparent;
  }
  60% {
    stroke-width: 1px;
  }
  90% {
    stroke-dashoffset: 0;
  }
  100% {
    stroke-width: 0px;
    fill: #333;
  }
}

1文字ずつ動きをつける

GSAP(GreenSock社が開発しているJavaScriptライブラリ)を使用しています。
こちらのページからダウンロード出来ます。

GSAP Installation
当ページでは、2つのファイルを読み込んでいます。

import { gsap } from './gsap_3.6.1/esm/gsap-core.js';
import { CSSPlugin } from './gsap_3.6.1/esm/CSSPlugin.js';

飛び出す

再開

<!-- GSAPの各見本共通(クラス名は都度変更) -->
<div class="wrap">
  <div class="js-g01">い</div>
  <div class="js-g01">ろ</div>
  <div class="js-g01">は</div>
  <div class="js-g01">に</div>
  <div class="js-g01">ほ</div>
  <div class="js-g01">へ</div>
  <div class="js-g01">と</div>
</div>

// GSAPの各見本共通
.wrap{ display: flex; flex-wrap: wrap; }

document.querySelectorAll(".js-g01").forEach((item, i) => {
  gsap.from(item, {
    opacity: 0,
    scale: 0,
    yPercent: 150,
    ease: "back",
    duration: 0.5,
    delay: i * 0.05
  });
});

そっと置く

再開

document.querySelectorAll(".js-g02").forEach((item, i) => {
  gsap.from(item, {
    opacity: 0,
    scale: 2,
    yPercent: -75,
    ease: "power1",
    duration: 0.5,
    delay: i * 0.05
  });
});

引き上げる

再開

document.querySelectorAll(".js-g03").forEach((item, i) => {
  gsap.from(item, {0.5
    opacity: 0,
    rotation: 100,
    yPercent: 150,
    ease: "back",
    duration: 0.5,
    delay: i * 0.05
  });
});

降ってくる

再開

document.querySelectorAll(".js-g04").forEach((item, i) => {
  gsap.from(item, {
    opacity: 0,
    rotation: -100,
    yPercent: -150,
    ease: "bounce",
    duration: 0.5,
    delay: i * 0.1,
  });
});

滑り込み

再開

document.querySelectorAll(".js-g05").forEach((item, i) => {
  gsap.from(item, {
    opacity: 0,
    rotation: 100,
    xPercent: 300,
    ease: "back",
    duration: 0.5,
  });
});

回転

再開

document.querySelectorAll(".js-g06").forEach((item, i) => {
  gsap.from(item, {
    opacity: 0,
    rotationX: 360,
    ease: "power1",
    duration: 0.5,
    delay: i * 0.05
  });
});

ランダム

再開

document.querySelectorAll(".js-g07").forEach((item, i) => {
  gsap.from(item, {
    opacity: 0,
    xPercent: "random(-100, 100, 20)", // -100から100になるまで20ずつ足した数字の中からランダムに一つ選択。
    yPercent: "random(-100, 100, 20)",
    scale: "random(0, 2, 0.2)",
    rotation: "random(-360, 360, 72)",
    rotationX: "random(-360, 360, 72)",
    rotationY: "random(-360, 360, 72)",
    skewX: "random(-25, 25, 5)",
    skewY: "random(-25, 25, 5)",
    ease: "power1",
    duration: 0.5,
    delay: "random(0, 0.5, 0.05)",
  });
});

アニメーションを繋げる

再開

document.querySelectorAll(".js-g08").forEach((item, i) => {
  const tl = gsap.timeline({
    delay: i * 0.1,
  });
  tl.from(item, { opacity: 0, scale: 0, duration: 0.5, ease: "back", })
    .to(item, { yPercent: -50, duration: 0.25, ease: "back", }, "+=0.4") //0.4秒後
    .to(item, { yPercent: 0, duration: 0.25, ease: "back", })
});

その他

影を縞模様にして動かす

塵積もって山となる
疑似要素に文字を入れて、背景を縞模様にして、文字でマスクして、位置をずらしています。
疑似要素の背景の位置を変化させています。

下記ページを参考にしています。

CSS Dashed Shadow

<div class="c05" data-text="塵積もって山となる" >塵積もって山となる</div>

.c05{
  position: relative; color: #a675a5;
  &::before, &::after{
    content: attr(data-text); position: absolute;
  }
  &::before{
    z-index: -1; top: 0.03em; left: 0.03em; color: #e7d4e3;
  }
  &::after{
    z-index: -2; top: 0.08em; left: 0.08em;
    background-image: repeating-linear-gradient(45deg, transparent 0 1px ,#dfccc2 1px 4px);
    background-size: 125% 100%;
    background-position: 100% 0;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    animation-name: kf_c05;
    animation-duration: 10s;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  }
}
@keyframes kf_c05 {
  100%{
    background-position: 0 0;
  }
}

文字を円形に配置して回転させる

律儀者の子沢山● 律儀者の子沢山● 律儀者の子沢山●
再開
SVG画像に文字を入れて、円形のパスに沿って配置しています。
タイミングをずらして、それぞれ回転させています。

<svg viewbox="0 0 500 500">
  <defs>
    <path id="svg04-path01" d="M   0 250 a 250 250 0 1 1 500 0 a 250 250 0 1 1 -500 0" />
    <path id="svg04-path02" d="M 100 250 a 150 150 0 1 1 300 0 a 150 150 0 1 1 -300 0" />
    <path id="svg04-path03" d="M 175 250 a  75  75 0 1 1 150 0 a  75  75 0 1 1 -150 0" />
  </defs>

  <text class="s04 s0401 active" x="0" y="0">
    <textPath class="s04tp" href="#svg04-path01" textLength="1645">律儀者の子沢山●</textPath>
    <!-- textLength = 直径 × 円周率 + フォントサイズ -->
  </text>
  <text class="s04 s0402 active" x="0" y="0">
    <textPath class="s04tp" href="#svg04-path02" textLength="992">律儀者の子沢山●</textPath>
  </text>
  <text class="s04 s0403 active" x="0" y="0">
    <textPath class="s04tp" href="#svg04-path03" textLength="501">律儀者の子沢山●</textPath>
  </text>
</svg>

.s04tp{
  text-anchor:start; dominant-baseline:hanging;
}
.s04{
  &.active{
    transform: rotate(0deg);
    transform-origin: center center;
    animation-name: kf_s04;
    animation-duration: 2s;
    animation-fill-mode: forwards;
  }
}
.s0401{
  font-size: 75px; animation-delay: 0.5s;
}
.s0402{
  font-size: 50px; animation-delay: 0.25s;
}
.s0403{
  font-size: 30px; animation-delay: 0s;
}
@keyframes kf_s04 {
  100% {
    transform: rotate(360deg);
  }
}

縁取りの線の色を変える

盗人の昼寝
SVG画像に文字を入れて、文字を重ねて、縁取りの線の色をそれぞれ指定して、線の開始位置を変化させています。

下記ページを参考にしています。

Animated text fill with svg text practice

<svg viewBox="0 0 720 90">
  <defs>
    <text id="svg02-text" class="s02t" x="0" y="10">盗人の昼寝</text>
  </defs>

  <use class="s02u" xlink:href="#svg02-text"></use>
  <use class="s02u" xlink:href="#svg02-text"></use>
  <use class="s02u" xlink:href="#svg02-text"></use>
</svg>

.s02t{
  text-anchor:start; dominant-baseline:hanging;
}
.s02u{
  $colors: #e94d15, #f8b633, #a74535;
  $max: length($colors);
  $dash: 80;
  $dash-gap: 3;
  $dash-space: $dash * ($max - 1) + $dash-gap * $max;
  $time: 8s;
  $time-step: $time/$max;

  fill: transparent;
  stroke-width: 3;
  stroke-linejoin: round;
  stroke-dasharray: $dash $dash-space;
  stroke-dashoffset: 0;
  animation-name: kf_s02;
  animation-duration: $time;
  animation-iteration-count: infinite;
  animation-timing-function: linear;

  @for $item from 1 through $max {
    &:nth-child(#{$max}n + #{$item}) {
      $color: nth($colors, $item);
      stroke: $color;
      animation-delay: -($time-step * $item);
    }
  }
  @keyframes kf_s02 {
    100% {
      stroke-dashoffset: -($dash + $dash-gap) * $max;
    }
  }
}

波のアニメーションを文字でマスクする

老いては子に従え
SVG画像に波を描いて、重ねて配置して、それぞれ動かして、文字でマスクしています。

下記ページを参考にしています。

Wave text effect (with SVG/blend mode)

<svg viewBox="0 0 720 90">
  <defs>
    <path id="svg03-path" d="M -40 10 Q -30 20 -20 10 Q -10  0 0 10 Q 10 20 20 10 Q 30  0 40 10 Q 50 20 60 10 Q 70 20 80 10 V 94 H -40 Z"></path>
    <pattern id="svg03-pt-a" x="0" y="5" width="40" height="100" patternUnits="userSpaceOnUse" patternTransform="scale(5,2)">
      <use class="s03-fill" href="#svg03-path" />
      <animate attributeName="x" dur="2s" repeatCount="indefinite" values="0; -40"/>
    </pattern>
    <pattern id="svg03-pt-b" x="0" y="5" width="40" height="100" patternUnits="userSpaceOnUse" patternTransform="scale(5,2)">
      <use class="s03-fill" href="#svg03-path" />
      <animate attributeName="x" dur="2.5s" repeatCount="indefinite" values="0; -40"/>
    </pattern>
    <pattern id="svg03-pt-c" x="0" y="5" width="40" height="100" patternUnits="userSpaceOnUse" patternTransform="scale(7,3)">
      <use class="s03-fill" href="#svg03-path" />
      <animate attributeName="x" dur="3s" repeatCount="indefinite" values="0; -40"/>
    </pattern>
    <text id="svg03-text" class="s03-text" x="0" y="10">老いては子に従え</text>
    <mask id="svg03-text-mask">
      <use x="0" y="0" xlink:href="#svg03-text" fill="#fff"/>
    </mask>
  </defs>

  <use  class="s03-mbm s03-fill" x="0" y="0" xlink:href="#svg03-text" />
  <rect class="s03-mbm" x="0" y="0" width="720" height="100" fill="url(#svg03-pt-a)" mask="url(#svg03-text-mask)"></rect>
  <rect class="s03-mbm" x="0" y="0" width="720" height="100" fill="url(#svg03-pt-b)" mask="url(#svg03-text-mask)"></rect>
  <rect class="s03-mbm" x="0" y="0" width="720" height="100" fill="url(#svg03-pt-c)" mask="url(#svg03-text-mask)"></rect>
</svg>

.s03-text{
  text-anchor: start; dominant-baseline: hanging;
}
.s03-fill{
  fill: #e7d4e3;
}
.s03-mbm{
  mix-blend-mode: multiply;
}

参考

DOCS

SVGで手書き風アニメーションを実装する方法

background-positionプロパティの「%指定値」と「px指定値」を相互変換する計算式

CSS clip-path maker

SVG アニメーション(SMIL を使ったアニメーション)

CSS Dashed Shadow

Circular SVG Text Animation

HTML SVG の基本的な使い方(SVG入門)

Animated text fill with svg text practice

Wave text effect (with SVG/blend mode)

関連記事

GSAP ScrollTriggerを使う(HTML/JS)

CSSで文字に光彩のような効果を加える

マスク、クリップパス(CSS)

色、グラデーション(CSS)

先頭に戻る
ページの先頭に戻る