← 記事一覧へ

SVG で描くマンダラ — stroke-dashoffset アニメーション

SVG の stroke-dashoffset を使ってパスが自己描画するマンダラアニメーションを作る手法を解説します。

作品

ページを開いた瞬間、中心から外に向かってパスが順番に描かれていきます。 描き終わると、六角形のペアが互いに逆方向へゆっくり回転し続けます。

Drawing Mandala — SVG stroke-dashoffset & counter-rotation クリック / タップで再生

核心技術 — stroke-dashoffset

SVG のパスには「破線のオフセット」を制御する stroke-dashoffset プロパティがあります。 これを使って「未描画 → 描画済み」を表現するのが、このアニメーションの核心です。

pathLength で長さを正規化

すべてのパス(円・多角形・線)の長さはバラバラです。 pathLength="100" を指定すると、ブラウザがそのパスの総長さを 100 として扱ってくれます。

<circle pathLength="100" cx="200" cy="200" r="172" />

これで stroke-dasharray: 100; stroke-dashoffset: 100 が「全部隠れた状態」、 stroke-dashoffset: 0 が「全部描かれた状態」と統一できます。

.draw {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;            /* 初期:全部隠す */
  animation: draw 1s ease forwards;  /* → 0 まで動かして描く */
}

@keyframes draw {
  to { stroke-dashoffset: 0; }
}

遅延で順番を制御

animation-delay に CSS カスタムプロパティ(--d)を使い、要素ごとに描画タイミングをずらします。

<!-- 中心から外に向かって遅延を増やす -->
<circle class="draw" style="--d: 0s;   --t: 0.6s" r="24" />   <!-- 中心リング -->
<circle class="draw" style="--d: 0.8s; --t: 1.0s" r="100" />  <!-- 中間リング -->
<circle class="draw" style="--d: 2.5s; --t: 1.2s" r="172" />  <!-- 外側リング -->

12本の放射線も個別に遅延をずらして、「扇形に広がる」演出をしています。

const radialLines = Array.from({ length: 12 }, (_, i) => ({
  delay: 0.4 + i * 0.04,  // 0.04秒ずつずらす
}))

六角形の逆回転

描き終わった後、2つの六角形(30° ずらして重ねた Star of David 状のペア)が逆方向に回り続けます。

各六角形を <g> で包み、transform-origin を SVG 中心(200px 200px)に設定します。

.spin-cw  { animation: spin-cw  18s linear infinite; }
.spin-ccw { animation: spin-ccw 18s linear infinite; }

@keyframes spin-cw  { to { transform: rotate(360deg);  } }
@keyframes spin-ccw { to { transform: rotate(-360deg); } }

ポイントは animation-delay: 4.2s で描画アニメーション終了まで回転を待つことです。 <g>animation-delay と子要素の描画 animation-delay は独立しているため、互いに干渉しません。


座標の計算

マンダラは「円の上に等間隔で点を打つ」繰り返しです。 JavaScript の三角関数で座標を求めます。

const pt = (r: number, deg: number) => ({
  x: CX + r * Math.cos((deg * Math.PI) / 180),
  y: CY + r * Math.sin((deg * Math.PI) / 180),
})

// 正六角形(頂点6個、60°間隔)
const hexPoints = Array.from({ length: 6 }, (_, i) =>
  pt(100, -90 + i * 60)  // -90° = 真上から開始
)
✓ TIP

SVG の Y 軸は下向きが正です。-90° を開始角にすると頂点が真上に来て、幾何学的に自然な形になります。


CSS 前作との比較

手法本記事 (SVG stroke)前作 CSS (gradient)
動き描画アニメーション脈動・軌道回転
形状の精度数学的に正確近似的
インタラクティブ性パスごとに制御可能要素単位
コード量多め少なめ