JavaScriptとCSSアニメーションを組み合わせると、短いコードでも「動くミニデモ」を作れます。今回は、バスケットボールが床に当たってバウンドする表現を作ります。
アニメーションの本体はCSSの@keyframesで作り、JavaScriptではボタンを押した時にバウンド速度を変えるだけにします。CodePenへ貼って動かせるコードも用意しました。
作るもの
- バスケットボールが上下にバウンドするデモ
- 床に近い時だけボールが少し潰れる表現
- 影の大きさと透明度がボールの高さに合わせて変わる表現
- Slow / Normal / Fastボタンで速度を切り替える操作
- prefers-reduced-motionで動きを減らす設定にも対応
実装の考え方
ボールの上下移動はtransform: translateY()で表現します。床に当たる瞬間だけscale(1.08, .92)のように横へ少し広げ、縦へ少し潰すと、軽い弾性が出ます。
@keyframes bounce {
0%, 100% {
transform: translate(-50%, 0) scale(1.08, .92);
}
55% {
transform: translate(-50%, -250px) scale(1);
}
}
影はボールとは逆に、高く跳ねている時ほど小さく薄くします。これだけで、床との距離がかなり分かりやすくなります。
CodePen
JavaScriptの役割
JavaScriptでは、ボタンのdata-speedを読み取り、CSSカスタムプロパティ--durationを書き換えています。動きそのものをJavaScriptで毎フレーム計算するより、CSSアニメーションへ任せる方がシンプルです。
const speeds = {
slow: '1.2s',
normal: '.88s',
fast: '.58s',
};
ball.style.setProperty('--duration', speeds.fast);もっと自然に見せる調整
- 最高到達点:
translateY(-250px)の値を大きくすると高く跳ねます。 - 速度:
--durationを短くするとテンポが速くなります。 - 重さ:床に当たる時間を短くし、上昇・落下を速くすると重く見えます。
- 影:高い時に小さく薄く、低い時に大きく濃くすると距離感が出ます。
- 床ライン:ボールの接地点にラインや影を置くと、着地位置が分かりやすくなります。
よくある失敗
- topやbottomをアニメーションする:レイアウト計算が発生しやすいので、基本は
transformを使います。 - 影を固定したままにする:ボールだけ動いて見え、浮遊感が弱くなります。
- ボールの模様を複雑にしすぎる:小さい表示では潰れるので、線は少なめで十分です。
- 速度切り替えをJSだけで作る:CSS変数へ渡すと、CSS側のアニメーション設計を保てます。
- 動きを止める配慮がない:
prefers-reduced-motionでアニメーションを停止できるようにします。
まとめ
バウンド表現は、上下移動、着地時の潰れ、影の変化を合わせると一気にそれっぽくなります。JavaScriptは速度変更などの状態管理に絞り、実際の動きはCSSアニメーションへ任せると、コードも読みやすくなります。
CodePenで試す時は、まず高さと速度を触ってみてください。少し値を変えるだけでも、軽いボール、重いボール、コミカルな動きなど、かなり印象が変わります。
