CSS アニメーションと SVG で描くアート
CSS @keyframes による太陽系アニメーションと、SVG フィルター・リフレクションを使ったネオン都市の制作過程を解説します。
作品 1 — Solar System
CSS アニメーションだけで動く太陽系です。惑星・軌道・星空・太陽の光量変化をすべて CSS で実現しています。
軌道アニメーションの仕組み
各惑星は「軌道リング(div)が回転し、その端に惑星が貼りついている」という構造です。
/* 軌道リングが中心を原点に回転する */
.orbit-ring {
position: absolute;
top: 50%;
left: 50%;
border-radius: 50%;
animation: spin linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
惑星は軌道リングの上端(top: -半径px)に配置するだけ。リングが回れば惑星が円軌道を描きます。
// 4惑星のデータ定義
const planets = [
{ orbit: 55, period: 2.5, size: 7, color: '#9ca3af' }, // 水星
{ orbit: 88, period: 6, size: 11, color: '#d97706' }, // 金星
{ orbit: 124, period: 11, size: 12, color: '#00DC82' }, // 地球
{ orbit: 162, period: 19, size: 9, color: '#ef4444' }, // 火星
]
animationDelay に負の値を設定することで、ビルド時点での惑星の開始位置をずらせます。
animationDelay: p.delay + 's' // 例: -4.5s → 4.5秒分進んだ状態から開始
太陽の脈動
radial-gradient と filter: blur の組み合わせで自然な光彩を表現し、 animation で明滅させています。
.sun-halo {
background: radial-gradient(circle, rgba(255,180,0,0.35) 0%, transparent 70%);
animation: pulse 3s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { transform: scale(1); opacity: 0.5; }
50% { transform: scale(1.4); opacity: 1; }
}
作品 2 — Neon City
SVG で描いたネオン都市です。<filter> によるウィンドウの発光と、変換行列で作る水面リフレクションが特徴です。
SVG フィルターでネオン発光
<feGaussianBlur> でぼかし画像を生成し、元画像と合成(feMerge)することでグロー効果を作ります。
<filter id="win-glow">
<feGaussianBlur stdDeviation="2.5" result="blur" />
<feMerge>
<feMergeNode in="blur" /> <!-- ぼかした光 -->
<feMergeNode in="SourceGraphic" /> <!-- 元のウィンドウ -->
</feMerge>
</filter>
水面リフレクション
建物・窓を scale(1, -1) で上下反転し、地面ラインを軸に折り返すことで水面の映り込みを表現します。
<!-- translate(0, GROUND*2) で反転後の位置を地面ラインに揃える -->
<g transform="translate(0, 600) scale(1, -1)" mask="url(#reflect-fade)">
<!-- 同じ建物・窓を再描画 -->
</g>
フェードマスクは linearGradient(白→透明)を <mask> で適用して、水面が下に向かうほど薄くなるように制御しています。
ウィンドウの決定論的生成
JavaScript の乱数(Math.random())は SSR とクライアントでズレてハイドレーションエラーになります。
そのため、ビルドインデックスから計算する決定論的な式でウィンドウの点灯パターンを決めています。
const seed = (buildingIndex * 31 + row * 17 + col * 7) % 100
const isLit = seed > 38 // 約 62% が点灯
技術比較
| 手法 | 向いている表現 | 難しい点 |
|---|---|---|
| CSS animation | 繰り返し動作・軌道・脈動 | 複雑な形状の制御 |
| SVG filter | 発光・ぼかし・影 | フィルター定義の記述量 |
| SVG transform | 反転・スケール・鏡像 | 座標計算が必要 |
| CSS radial-gradient | 光源・オーブ・背景 | ブラウザ差異がある場合も |
CSS と SVG を組み合わせると、互いの弱点を補い合えます。アニメーションは CSS、複雑なフィルターは SVG というように使い分けましょう。