
今回は、SVG パスを使って円弧に沿ったテキストを表示し、そのテキストをアニメーションで回転させる実装方法を、汎用性を前提にして考えてみます。
ここで紹介する SVG コンテンツは、例えばロゴ、バッジ、装飾要素など様々なデザインに活用することを想定しています。
まずは、今回作成するコンテンツのデモをご覧ください。
See the Pen Curve Text on SVG Path by digistate (@digistate) on CodePen.
1. 基本構造と仕組み
まず、このSVGテキスト実装の基本的な仕組みを説明します。
<div class="curve-text">
<svg viewBox="0 0 100 100">
<!-- 円弧のパス定義 -->
<path id="curve" d="M 0 50 A 50 50 0 1 1 0 50.5 z" fill="transparent"></path>
<!-- 回転するテキスト -->
<g class="rotating-text">
<text class="outer" dy="-0.8em">
<textPath href="#curve" textLength="310" xml:space="preserve" startOffset="2">
Best Luxury Interior Design Trends...
</textPath>
</text>
</g>
<!-- 中央のテキスト -->
<text class="inner" x="50" y="50" text-anchor="middle" dominant-baseline="middle">
<!-- テキスト内容 -->
</text>
<!-- 装飾線 -->
<g>
<line class="divider" x1="25" y1="50" x2="75" y2="50"></line>
<circle class="divider-dot" cx="50" cy="50" r="1"></circle>
</g>
</svg>
</div>
ポイント
- SVGの座標系
-
viewBox="0 0 100 100"
で100×100の座標系を定義し、中心は(50, 50)になります。 - パス(円弧)の定義
-
d="M 0 50 A 50 50 0 1 1 0 50.5 z"
は半径50の円弧を定義しています。この円弧は viewBox=”0 0 100 100″ を前提としたものです。
- テキストパス
-
textPath
要素がhref="#curve"
でパスを参照し、テキストをパスに沿って配置します。
2. CSS 変数による汎用性を考慮したカスタマイズ
今回のサンプルの特徴は、CSS変数(カスタムプロパティ)を活用して様々な要素を簡単にカスタマイズできる点です。
CSS には以下のように CSS 変数を用意しています。
// カスタマイズ対象の初期値
.curve-text {
--color: #ccc; /* パスと文字のカラー */
--outer-font-size: 11px; /* 外側のフォントサイズ */
--inner-font-size: 30px; /* 円内のフォントサイズ */
--display-size: 200px; /* 実際の表示サイズ */
--svg-size: 200; /* 表示サイズ(pxなし) */
--svg-base-size: 100; /* viewBoxのサイズ */
--rotation-speed: 20s; /* 回転速度 */
--rotation-direction: normal; /* 回転方向 */
--scale-factor: calc(var(--svg-size) / var(--svg-base-size));
/* 以下省略 */
}
CSS 変数の役割と使い方
- –color
-
この CSS 変数のプロパティの値に HEX 値などのカラーコードを渡すことでテキストやパスの色を一括で変更できます。
- –display-size
-
この要素自体の表示サイズを指定します(幅と高さ両方に適用)。
この変数は
width
,height
の値として渡すため、ピクセル(px)単位付きで指定します。 - –svg-size
-
--display-size
と同じ数字を、単位を除いた数値で指定します(例: 200)。この変数は、
--display-size
がviewBox
に対する割合を算出するための--scale-factor
を割り出すために必要です。 - –outer-font-size
-
円弧に沿って回転するテキストのフォントサイズを指定します(例: 11px)。
- –inner-font-size
-
円弧内に表示するテキストのフォントサイズを指定します(例: 30px)。
- –rotation-speed
-
アニメーションの速度を秒単位で指定します(例: 20s)。
- –rotation-direction
-
normal
(時計回り)またはreverse
(反時計回り)を指定します。
これらの変数は、HTMLのインラインスタイルで簡単に上書きできます:
<div class="curve-text" style="--display-size:300px; --color:#ff0000; --rotation-speed:15s;">
<!-- ここにSVG -->
</div>
3. 自動スケーリングの仕組み
SVG のサイズ変更時に文字や線の太さが適切にスケーリングされる仕組みは、このサンプルの重要なポイントとなります。
--scale-factor: calc(var(--svg-size) / var(--svg-base-size));
// 外周(円弧)のテキスト
text.outer {
font-size: calc(var(--outer-font-size) / var(--scale-factor));
}
// 円弧内のテキスト
text.inner {
font-size: calc(var(--inner-font-size) / var(--scale-factor));
}
スケーリングの解説
- –scale-factor
-
SVGの実際のサイズ(
--svg-size
)とベースサイズ(--svg-base-size
)の比率を計算します。 - フォントサイズの計算
-
フォントサイズをスケールファクターで割ることで、表示サイズ(
--display-size
)が変わっても文字の相対的な大きさが維持されます。 - vector-effect: non-scaling-stroke
-
パスやラインの太さが SVG のサイズ変更に影響されないようにします。
これにより、SVG のサイズを変更しても、すべての要素が適切な比率で表示されます。
4. テキストパスの調整
円弧に沿ったテキストの配置は、細かい調整や配慮が必要となります。
<textPath href="#curve" textLength="310" xml:space="preserve" startOffset="2" lengthAdjust="spacing">
Best Luxury Interior Design Trends and Innovative Decoration Ideas
</textPath>
重要な属性
textPath
に指定している各属性は以下の役割があります。
- textLength=”310″
-
テキストの全体の長さを指定します。
円周の長さ(2πr = 2×3.14×50 ≈ 314)より少し短くすることで、テキストの始点と終点に余白をとり、1文字目と最後の文字の間の間隔がなくならないようにしています。
- xml:space=”preserve”
-
テキスト内の空白を保持します。
- vector-effect: non-scaling-stroke
-
パスやラインの太さが SVG のサイズ変更に影響されないようにします。
- startOffset=”2″
-
テキストの開始位置をパスの始点から少しずらします。
- lengthAdjust=”spacing”
-
テキストの長さを調整する際、文字間のスペースのみを調整し、文字自体の幅は変更しません。
テキストの文字数の調整
テキストが長い場合は文字間が詰まり、短い場合は文字間が空いた状態で自動で調整されます。
- パスの長さを計算(円周 = 2πr)
- テキストの量に応じて、その値より少し小さい値を設定
- 視覚的に確認しながら微調整
5. アニメーションの実装
テキストの回転アニメーションは、CSS アニメーションで実装しています。
.rotating-text {
transform-origin: 50px 50px; /* viewBoxの中心 */
animation: rotate var(--rotation-speed) linear infinite;
animation-direction: var(--rotation-direction);
}
// 反時計回りに回転するキーフレーム
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(-360deg);
}
}
アニメーション(回転テキスト)のポイント
- transform-origin: 50px 50px
-
回転の中心点を SVG の中心に設定。
- animation: rotate var(–rotation-speed) linear infinite
-
linear
: 一定の速度で回転infinite
: アニメーションを無限に繰り返す - animation-direction: var(–rotation-direction)
-
回転方向を変数で制御(
normal
orreverse
)。
回転方向を変更するには、キーフレームの値を調整するか、--rotation-direction
変数をreverse
に設定します。
6. 円弧内の中央テキストの配置
中央のテキストを正確に配置するには、SVGのテキスト配置属性を理解する必要があります。
<text class="inner" x="50" y="50" text-anchor="middle" dominant-baseline="middle">
<tspan x="50" dx="0.14em" dy="-0.72em">INTERIOR</tspan>
<tspan x="50" dy="1.6em">2026</tspan>
</text>
複数行のテキストを中央に配置する場合、最初の行を上に、次の行を下に移動させることで、全体が中央に配置されるようにします。
テキスト配置のポイント
- text-anchor=”middle”
-
テキストを水平方向に中央揃え。
- dominant-baseline=”middle”
-
テキストを垂直方向に中央揃え。
- tspan 要素
-
複数行のテキストを配置するために使用。
- dy=”-0.72em”, dy=”1.6em”
-
行間の微調整(相対的な単位emを使用)。
実際の SVG テキストの表示は、位置が正確(中心)でない場合があるため、その場合のみ目視しながらこれらのプロパティ(
dx
,dy
)を使用して微調整しています。
7. 装飾線のアニメーション
今回のデモでは、円弧内の2行のテキストの間にライン(.divider
)を表示しています。
この中央の装飾線には、表示時にフェードインアニメーションを適用しています。
.divider {
stroke: var(--color);
stroke-width: 0.5px;
vector-effect: non-scaling-stroke;
transform: scaleX(0);
transform-origin: center;
animation: fadeInLine 1.2s ease-out .3s forwards;
}
// 中心から左右にラインが伸びるアニメーション
@keyframes fadeInLine {
0% {
transform: scaleX(0);
}
100% {
transform: scaleX(1);
}
}
アニメーションの解説
- transform: scaleX(0)
-
初期状態では線が見えない(幅が 0)。
- transform-origin: center
-
中央から拡大。
- animation: fadeInLine 1.2s ease-out .3s forwards
-
1.2s
: アニメーション時間ease-out
: 終わりに向かって徐々に遅くなる.3s
: 0.3秒の遅延後に開始forwards
: アニメーション終了後も最終状態を維持
[おまけ]中央テキストを縦書きで表示
中央のテキストを縦書きにする場合は、text
要素に CSS で writing-mode: vertical-rl
または writing-mode: tb
を追加し、x
, y
, dx
, dy
の基準を横書きのときと逆にして微調整します。
See the Pen Curve Vertical Text on SVG Path by digistate (@digistate) on CodePen.
まとめ
SVG を使った円弧に沿ったテキストの実装は、CSS 変数と SVG の特性を活用することで、柔軟にある程度カスタマイズ可能なデザイン要素を作成できます。
- SVG のパスとテキストパスを使用して円弧に沿ったテキストを配置
- CSS 変数による汎用性を考慮した構造
- スケールファクターを使用した適切なサイズ調整
- CSS アニメーションによる回転効果
- 中央テキストの正確な配置(微調整)
今後、これをベースにしたカスタムブロックを「DigiPress Ex – Blocks」プラグインに追加してみようと思います。