SVG で描くマンダラ — stroke-dashoffset アニメーション
SVG の stroke-dashoffset を使ってパスが自己描画するマンダラアニメーションを作る手法を解説します。
作品
ページを開いた瞬間、中心から外に向かってパスが順番に描かれていきます。 描き終わると、六角形のペアが互いに逆方向へゆっくり回転し続けます。
核心技術 — 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° = 真上から開始
)
SVG の Y 軸は下向きが正です。-90° を開始角にすると頂点が真上に来て、幾何学的に自然な形になります。
CSS 前作との比較
| 手法 | 本記事 (SVG stroke) | 前作 CSS (gradient) |
|---|---|---|
| 動き | 描画アニメーション | 脈動・軌道回転 |
| 形状の精度 | 数学的に正確 | 近似的 |
| インタラクティブ性 | パスごとに制御可能 | 要素単位 |
| コード量 | 多め | 少なめ |