「疾走感」を表現する
速さ・前進感・勢いを視覚的に伝える表現テクニック。車・スポーツ・配達などのWebサイトで頻出。
このページについて
- 「疾走感」とは:速さ・前進感・勢いを視覚で伝える印象。実際に動かさなくても、流れや残像で感じさせる手法が多い。
- こんな時に使う:車LP・スポーツブランド・配達サービス・物流・スピード重視のSaaS製品紹介。
- 関連タグ:🚗 車(準備中)🎉 躍動感(準備中)
- AIへの伝え方のコツ:「疾走感」だけでは曖昧。「後方へ流れる」「振動」「視線移動」「タイヤ回転」など具体的な動きと組み合わせると伝わりやすい。
表現の引き出し
🎨 左右に往復するアニメ
📝 表現の語彙
💬 AIへの指示テンプレ
🎯 似合うシーン
配達サービス・物流LP・電車・通勤関連・子供向けサイト
🔧 実装手法
CSS @keyframes の ease-in-out で left を往復し、折り返しで scaleX(-1) 反転。上下のゆれ・影の伸縮・タイヤ回転は周期の異なる別アニメーションを重ねる
📄 コード例を見る
<div class="drive-stage">
<div class="cloud cloud-1"></div>
<div class="cloud cloud-2"></div>
<div class="cloud cloud-3"></div>
<div class="road"></div>
<div class="car">
<div class="car-bounce">
<svg viewBox="0 0 64 40" width="64" height="40">
<rect x="14" y="6" width="28" height="16" rx="7" fill="#e8916f" />
<rect x="19" y="9" width="11" height="8" rx="2" fill="#fff3ea" />
<rect x="2" y="16" width="60" height="16" rx="8" fill="#e07856" />
<circle cx="59" cy="22" r="2" fill="#ffd9a0" />
<g class="wheel w1">
<circle cx="16" cy="32" r="6" fill="#33283b" />
<circle cx="16" cy="32" r="2.6" fill="#e7dde9" />
<line x1="16" y1="29.4" x2="16" y2="34.6" stroke="#33283b" stroke-width="1.2" />
</g>
<g class="wheel w2">
<circle cx="48" cy="32" r="6" fill="#33283b" />
<circle cx="48" cy="32" r="2.6" fill="#e7dde9" />
<line x1="48" y1="29.4" x2="48" y2="34.6" stroke="#33283b" stroke-width="1.2" />
</g>
</svg>
</div>
<div class="car-shadow"></div>
</div>
</div>.drive-stage {
position: relative;
height: 180px;
border-radius: 8px;
overflow: hidden;
background: linear-gradient(180deg, #fde8d7 0%, #f3d5e8 60%, #e2d5f3 100%);
}
.road {
position: absolute;
bottom: 0; left: 0; right: 0;
height: 24px;
background: rgba(96, 72, 108, 0.14);
border-top: 1px solid rgba(96, 72, 108, 0.35);
}
/* 夕日に染まる雲。blur と周期違いの漂いで空気感を出す */
.cloud { position: absolute; border-radius: 9999px; filter: blur(3px); }
.cloud-1 { top: 22px; left: 12%; width: 72px; height: 16px; background: #fff8f0; opacity: .8;
animation: cloudDrift 40s ease-in-out infinite alternate; }
.cloud-2 { top: 58px; left: 58%; width: 52px; height: 12px; background: #ffe9d6; opacity: .7;
animation: cloudDrift 30s ease-in-out infinite alternate-reverse; }
.cloud-3 { top: 38px; left: 80%; width: 40px; height: 10px; background: #fff; opacity: .5;
animation: cloudDrift 36s ease-in-out infinite alternate; animation-delay: -12s; }
@keyframes cloudDrift {
from { transform: translateX(0); }
to { transform: translateX(-34px); }
}
/* 往復。ease-in-out なので端に近づくと自然に減速する */
.car {
position: absolute;
bottom: 20px; left: 12px;
width: 64px; height: 40px;
animation: drive 8s ease-in-out infinite;
}
@keyframes drive {
0% { left: 12px; transform: scaleX(1); }
44% { left: calc(100% - 76px); transform: scaleX(1); }
46% { left: calc(100% - 76px); transform: scaleX(1) rotate(-2deg); } /* 重心移動 */
50% { left: calc(100% - 76px); transform: scaleX(-1); } /* 向きを反転 */
94% { left: 12px; transform: scaleX(-1); }
96% { left: 12px; transform: scaleX(-1) rotate(-2deg); }
100% { left: 12px; transform: scaleX(1); }
}
/* ゆったりした上下のゆれ(周期は往復とずらす) */
.car-bounce { animation: carBounce 1.3s ease-in-out infinite alternate; }
@keyframes carBounce {
from { transform: translateY(1.2px); }
to { transform: translateY(-1.6px); }
}
/* タイヤの回転(回転自体は等速が正しい) */
.wheel { animation: wheelSpin 0.7s linear infinite; }
.w1 { transform-origin: 16px 32px; }
.w2 { transform-origin: 48px 32px; }
@keyframes wheelSpin { to { transform: rotate(360deg); } }
/* 影はゆれと連動して伸縮(車が浮くと影が小さく) */
.car-shadow {
position: absolute;
bottom: -4px; left: 6px;
width: 52px; height: 6px;
background: rgba(40, 30, 50, 0.28);
border-radius: 9999px;
filter: blur(2px);
animation: carShadow 1.3s ease-in-out infinite alternate;
}
@keyframes carShadow {
from { transform: scaleX(1); opacity: .3; }
to { transform: scaleX(.9); opacity: .2; }
}
@media (prefers-reduced-motion: reduce) {
.car, .car-bounce, .car-shadow, .wheel, .cloud { animation: none; }
}🎨 流れる風景(パララックス背景)
📝 表現の語彙
💬 AIへの指示テンプレ
🎯 似合うシーン
車LP・配達サービス・旅行サイト・冒険ゲーム・ロードトリップ系コンテンツ
🔧 実装手法
SVG path の山並みを同一パス2枚連結で translateX(-50%) ループ。レイヤーごとの速度差・blur・透明度で奥行き(空気遠近法)を表現
📄 コード例を見る
<div class="dusk-stage">
<div class="moon"></div>
<!-- 光の粒。周期(11s/13s/17s/19s/23s)と明滅をバラす -->
<div class="glow-dot" style="top: 24px; --drift: 17s; --tw: 3.7s"></div>
<div class="glow-dot" style="top: 48px; --drift: 23s; --tw: 2.9s"></div>
<!-- ...計5個... -->
<!-- 各レイヤーは同一path×2枚連結。-50% 移動で継ぎ目なくループ -->
<div class="mtn-layer mtn-back">
<svg viewBox="0 0 800 180" preserveAspectRatio="none">
<path d="M0,96 Q70,58 140,86 Q210,112 280,78 Q350,52 420,90
Q490,118 560,84 Q630,56 700,92 Q760,114 800,96
L800,180 L0,180 Z" fill="#1f2547" />
</svg>
<svg><!-- 同じpath --></svg>
</div>
<div class="mtn-layer mtn-mid"><!-- 中間の起伏 --></div>
<div class="mtn-layer mtn-front"><!-- シャープな丘 --></div>
</div>.dusk-stage {
position: relative;
height: 180px;
border-radius: 8px;
overflow: hidden;
background: linear-gradient(180deg, #2d3561 0%, #5c5d8d 40%, #c06c84 80%, #f8b195 100%);
}
.moon {
position: absolute;
top: 14px; right: 22px;
width: 26px; height: 26px;
border-radius: 9999px;
background: #ffd9b0;
filter: blur(1px);
box-shadow: 0 0 18px 6px rgba(255, 217, 176, 0.35);
}
.glow-dot {
position: absolute;
width: 3px; height: 3px;
border-radius: 9999px;
background: #fff7ed;
animation-name: driftDot, twinkle;
animation-duration: var(--drift), var(--tw);
animation-timing-function: linear, ease-in-out;
animation-iteration-count: infinite, infinite;
}
@keyframes driftDot { from { left: 104%; } to { left: -4%; } }
@keyframes twinkle { 0%, 100% { opacity: .2; } 50% { opacity: .9; } }
.mtn-layer {
position: absolute;
bottom: 0; left: 0;
display: flex;
width: 200%; height: 100%;
}
.mtn-layer svg { width: 50%; height: 100%; flex-shrink: 0; }
/* 奥ほど遅く・霞ませる(blur+透明度)。手前は速くシャープに */
.mtn-back { animation: scrollLoop 28s linear infinite; filter: blur(2px); opacity: .7; }
.mtn-mid { animation: scrollLoop 16s linear infinite; filter: blur(1px); opacity: .85; }
.mtn-front { animation: scrollLoop 7s linear infinite; }
@keyframes scrollLoop {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}🎨 スピードライン(集中線)
📝 表現の語彙
💬 AIへの指示テンプレ
🎯 似合うシーン
スポーツブランド・格闘技・アニメ系コンテンツ・キャンペーンLP・インパクト重視のヒーロー
🔧 実装手法
SVGの <line> を擬似乱数でバラした放射配置にし、stroke-dasharray + stroke-dashoffset で「線が走る」動き。速度・明るさはCSS変数で線ごとに個別化
📄 コード例を見る
// 36本。シード的な計算で毎回同じだが不規則に見える配置
const lines = Array.from({ length: 36 }, (_, i) => {
const baseAngle = (Math.PI * 2 * i) / 36;
const jitter = ((i * 7919) % 100) / 100; // 擬似乱数 0-1
const jitter2 = ((i * 104729) % 100) / 100;
const angle = baseAngle + (jitter - 0.5) * 0.12; // 角度ジッター
const innerR = 30 + jitter * 35; // 中央の空白を不均一に
const outerR = 90 + jitter2 * 80; // 線の長さもバラす
return {
x1: 100 + Math.cos(angle) * innerR,
y1: 90 + Math.sin(angle) * innerR,
x2: 100 + Math.cos(angle) * outerR,
y2: 90 + Math.sin(angle) * outerR,
width: 0.5 + jitter * 2,
color: ["#dbeafe", "#bfdbfe", "#93c5fd", "#e0e7ff", "#ffffff"][i % 5],
peak: 0.4 + jitter * 0.6, // ピーク時の明るさ
delay: jitter * 1.2,
duration: 0.7 + jitter2 * 0.9,
};
});
<div className="night-stage">
<div className="night-glow" />
<svg viewBox="0 0 200 180" className="speed-lines" preserveAspectRatio="none">
{lines.map((l, i) => (
<line key={i} x1={l.x1} y1={l.y1} x2={l.x2} y2={l.y2}
stroke={l.color} strokeWidth={l.width}
style={{
"--dur": `${l.duration}s`,
"--peak": l.peak,
animationDelay: `${l.delay}s`,
}} />
))}
</svg>
</div>.night-stage {
position: relative;
height: 180px;
border-radius: 8px;
overflow: hidden;
background: radial-gradient(circle at center, #1a2238 0%, #0a0e1a 100%);
}
/* 中央の光だまりで奥行きを出す */
.night-glow {
position: absolute;
inset: 0;
background: radial-gradient(circle at 50% 50%, rgba(255,255,255,0.07) 0%, transparent 55%);
}
.speed-lines { position: absolute; inset: 0; width: 100%; height: 100%; }
/* 点滅ではなく stroke-dashoffset で「線が中央から外へ走る」 */
.speed-lines line {
stroke-dasharray: 60 140;
stroke-linecap: round;
opacity: 0;
animation: lineRun var(--dur) ease-out infinite;
}
@keyframes lineRun {
0% { stroke-dashoffset: 200; opacity: 0; }
15% { opacity: var(--peak); }
60% { opacity: var(--peak); }
100% { stroke-dashoffset: 0; opacity: 0; }
}🎨 タイヤの回転
📝 表現の語彙
💬 AIへの指示テンプレ
🎯 似合うシーン
車LP・配達サービス・物流・モビリティ・自転車・バイク
🔧 実装手法
SVGで車輪と、アーチをくり抜いた車体・ホイールハウスを描き分ける。回転は linear、車輪と車体の上下動は振幅・周期を変えた ease-in-out で別々に重ねる。地面の破線は速度差をつけて左へ流す
📄 コード例を見る
// スポーク5本:先細り(テーパー)の台形ポリゴンを計算で生成
const CX = 60, CY = 60;
const spokes = Array.from({ length: 5 }, (_, i) => {
const a = (Math.PI * 2 * i) / 5 - Math.PI / 2;
const p = a + Math.PI / 2; // 垂直方向
const rIn = 12, rOut = 36, wIn = 5.5, wOut = 2.5;
const pt = (r, w, s) =>
`${CX + Math.cos(a) * r + s * Math.cos(p) * w},${CY + Math.sin(a) * r + s * Math.sin(p) * w}`;
return [pt(rIn, wIn, 1), pt(rOut, wOut, 1), pt(rOut, wOut, -1), pt(rIn, wIn, -1)].join(" ");
});
// ボルト5個を五角形配置
const bolts = Array.from({ length: 5 }, (_, i) => {
const a = (Math.PI * 2 * i) / 5 - Math.PI / 2 + Math.PI / 5;
return { cx: 60 + Math.cos(a) * 6.5, cy: 60 + Math.sin(a) * 6.5 };
});
<div className="asphalt-stage">
{/* 地面の白い破線(速度差をつけて左へ流す) */}
<div className="road-dash" style={{ top: 112, width: 30, animationDuration: "0.55s" }} />
{/* ...計5本... */}
<div className="wheel-shadow" />
{/* 横長SVGを中央配置し、はみ出しはステージの overflow: hidden でクロップ */}
<div className="wheel-unit">
<svg viewBox="0 0 900 180" width="900" height="180">
{/* ホイールハウス(タイヤ奥の暗がり。車体と同期して揺れる) */}
<g className="car-body">
<path d="M388.3,120 A62,62 0 0 1 511.7,120 Z" fill="#1e293b" />
</g>
{/* 車輪 */}
<g transform="translate(390,54)">
<g className="wheel-bob">
<g className="wheel-rotor">
<circle cx="60" cy="60" r="53" fill="none" stroke="#0f172a" strokeWidth="3"
strokeDasharray="5 4" /> {/* トレッド */}
<circle cx="60" cy="60" r="46" fill="none" stroke="#1e293b" strokeWidth="13" /> {/* ゴム */}
<circle cx="60" cy="60" r="39" fill="#cbd5e1" stroke="#94a3b8" strokeWidth="2" /> {/* リム */}
{spokes.map((points, i) => <polygon key={i} points={points} fill="#94a3b8" />)}
<circle cx="60" cy="60" r="10" fill="#475569" /> {/* ハブ */}
{bolts.map((b, i) => <circle key={i} cx={b.cx} cy={b.cy} r="1.8" fill="#cbd5e1" />)}
</g>
</g>
</g>
{/* 車体(タイヤアーチをくり抜いたボディ。画面上端まで覆う) */}
<g className="car-body">
<path d="M0,-4 L900,-4 L900,120 L511.7,120 A62,62 0 0 0 388.3,120 L0,120 Z"
fill="#b91c1c" /> {/* ボディ */}
<path d="M0,22 Q450,14 900,22" fill="none"
stroke="#991b1b" strokeWidth="2" /> {/* キャラクターライン */}
<path d="M0,46 Q450,28 900,46" fill="none"
stroke="rgba(255,255,255,0.22)" strokeWidth="3" /> {/* ハイライト */}
<rect x="0" y="110" width="386" height="10" fill="#7f1d1d" /> {/* サイドスカート */}
<rect x="514" y="110" width="386" height="10" fill="#7f1d1d" />
<line x1="300" y1="8" x2="300" y2="108" stroke="#991b1b" strokeWidth="2" /> {/* ドア継ぎ目 */}
<rect x="266" y="58" width="22" height="5" rx="2.5" fill="#991b1b" /> {/* ドアハンドル */}
<path d="M388.3,120 A62,62 0 0 1 511.7,120" fill="none"
stroke="#1f2937" strokeWidth="5" /> {/* フェンダーリップ */}
</g>
</svg>
</div>
</div>.asphalt-stage {
position: relative;
height: 180px;
border-radius: 8px;
overflow: hidden;
background: linear-gradient(180deg, #bfdbfe 0%, #dbeafe 54%, #94a3b8 56%, #64748b 100%);
}
.road-dash {
position: absolute;
height: 3px;
border-radius: 2px;
background: rgba(255, 255, 255, 0.75);
animation-name: dashFlow; /* 地面の流れは等速(linear)が正しい */
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes dashFlow { from { left: 104%; } to { left: -18%; } }
.wheel-unit {
position: absolute;
left: 50%; bottom: 0;
width: 900px; height: 180px;
margin-left: -450px;
}
/* 車輪の上下動(路面の凹凸感) */
.wheel-bob { animation: roadBump 0.9s ease-in-out infinite alternate; }
@keyframes roadBump {
from { transform: translateY(0); }
to { transform: translateY(-2px); }
}
/* 車体はサスペンションで揺れが減衰:振幅を小さく・周期もずらす */
.car-body { animation: bodyBob 1.15s ease-in-out infinite alternate; }
@keyframes bodyBob {
from { transform: translateY(0.6px); }
to { transform: translateY(-0.8px); }
}
/* 回転自体は等速が正しい。0.5秒で1回転 */
.wheel-rotor {
transform-box: fill-box; /* 自身のバウンディングボックス基準で回す */
transform-origin: center;
animation: rotate 0.5s linear infinite;
}
@keyframes rotate { to { transform: rotate(360deg); } }
/* サスペンション影:上下動と連動して伸縮 */
.wheel-shadow {
position: absolute;
left: 50%; bottom: 10px;
width: 110px; height: 10px; margin-left: -55px;
border-radius: 9999px;
background: rgba(15, 23, 42, 0.35);
filter: blur(3px);
animation: shadowPulse 0.9s ease-in-out infinite alternate;
}
@keyframes shadowPulse {
from { transform: scaleX(1); opacity: .4; }
to { transform: scaleX(.92); opacity: .3; }
}よくある質問
疾走感の表現はやり過ぎると逆効果になりますか?
なります。スピードラインを全画面で常時表示したり、複数の演出を同時に重ねたりすると、視覚的に疲れる原因になります。1ページにつき1〜2つの演出に抑えるか、スクロールに合わせて段階的に表示する設計が無難です。
モバイルでアニメーションのパフォーマンスを保つには?
transform と opacity だけを使うのが鉄則です。width や left を変化させるとレイアウト計算が走り、フレームレートが落ちます。また prefers-reduced-motion のメディアクエリでアニメーション抑制への対応も入れておくと、アクセシビリティ的にも安心です。
「疾走感」を出したいときにアニメーション以外でできることは?
静止画像でも可能です。被写体のブレ(モーションブラー)を入れる、斜めの構図にする、後方にトレイル(光の尾)を残す、彩度の高い色を背景に使う、などが効果的です。動かさずに疾走感を出せると、ページ全体のパフォーマンスにも優しいです。
AI(Claude/ChatGPT等)に「疾走感のあるサイトを作って」と頼むコツは?
「疾走感」という抽象語だけでは曖昧なため、本ページの表現テクニック(左右往復・流れる風景・スピードライン・タイヤ回転)から具体的な動きを1〜2つ指定するのが効果的です。たとえば「ヒーローに流れる風景のパララックスを、その上にスピードラインを重ねて」のように、複数の表現を組み合わせて指示すると伝わります。