apple-design について
apple-designは、AppleのWWDCデザイントークをもとに、Apple風の滑らかなWebインターフェースを設計するスキルです。ジェスチャーに追従し、速度を引き継ぎ、いつでも中断できる動きを扱います。
主な機能
- 01即時の操作フィードバック
- 02ポインターへの一対一追従
- 03中断可能で速度を考慮したスプリング
- 04運動量の予測とスナップ
- 05空間的一貫性のある遷移
- 06フレーム単位の滑らかな動きの指針
活用シーン
- 01ドラッグ可能なWeb UIの設計
- 02中断可能なドロワーやシートの構築
- 03ジェスチャーに合うスプリング動作の選択
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ emilkowalski/ skills --skill apple-designインストール後、Claude Code で/apple-designを入力して読み込まれたか確認します。
詳細
Apple Design
初回の応答
このスキルが特定の質問なしで最初に呼び出されたときは、次のようにのみ応答してください:
I'm ready to help you build fluid, Apple-style interfaces on the web, my knowledge comes from Apple's WWDC design talks, translated for the web.
ユーザーが質問をするまで、他の情報は一切提供しないでください。
Apple がどのようにして、コンピューターのように感じられず、あなたの延長のように感じられるインターフェースを構築しているのか。この知識は Apple の WWDC デザイントーク、とりわけ Designing Fluid Interfaces(WWDC 2018)に由来し、ウェブプラットフォーム(CSS、Pointer Events、requestAnimationFrame、Motion/Framer Motion などのスプリングライブラリ)向けに蒸留・翻訳されたものです。
一貫するテーマはこうです。動きが現在の画面上の値から始まり、ユーザーの速度を引き継ぎ、慣性を前方に投影し、いつでもつかんで反転できるとき、インターフェースは生きているように感じられる。 スプリングは、これらすべてを自然にするツールです。なぜなら、スプリングは本質的に中断可能で、速度を認識するからです。
中心となる考え方
"When we align the interface to the way we think and move, something magical happens — it stops feeling like a computer and starts feeling like a seamless extension of us."
インターフェースは、物理世界のように振る舞うとき、流動的になります。つまり、物事が即座に反応し、連続的に動き、慣性を伴い、境界で抵抗し、動きの途中で方向転換できるということです。以下はすべて、そこに近づくための方法です。
Apple はデザインを、人間の 4 つのニーズに応えるものとして位置づけています。安全/予測可能性、理解、達成、喜びです。ここにあるすべてのルールは、そのいずれかに奉仕します。
1. 応答 — 遅延を排除する
遅延が現れた瞬間、直接性の感覚は「崖から落ちるように」失われます。応答は、他のすべてがその上に築かれる基盤です。
- ポインターが押された時点で応答し、離された時点ではありません。 押された瞬間にボタンをハイライトします。フィードバックを表示するのに
click/タッチアップを待つと、死んだように感じられます。 - あらゆる遅延に警戒してください。 デバウンス、人工的なタイマー、トランジションの待機、そして約 300ms のタップ遅延を監査します。入力経路にあって本質的でないものはすべて、リグレッションです。
- フィードバックは、最後だけでなく、インタラクションの最中に連続的でなければなりません。 ドラッグ、スライダー、ドロワーでは、UI をジェスチャー全体を通してポインターと 1:1 で更新します。ジェスチャーが完了したときだけアニメーションさせてはいけません。
/* Feedback lives on the press, and it's instant */
.button:active {
transform: scale(0.97);
transition: transform 100ms ease-out;
}
2. 直接操作 — 1:1 のトラッキング
"Touch and content should move together."
ユーザーが何かをドラッグするとき、それは指に貼り付いたままでなければなりません。そして、どこをつかんだかというオフセットを尊重する必要があります。つかんだときに要素の中心にスナップすると、その錯覚はすぐに壊れます。
- Pointer Events を
setPointerCaptureとともに使用して、ポインターが要素の境界を離れてもトラッキングが続くようにします。 - 現在の点だけでなく、短い速度/位置の履歴(直近のいくつかの
pointermoveイベント)を追跡します。離した時点で速度が必要になります。
el.addEventListener('pointerdown', (e) => {
el.setPointerCapture(e.pointerId);
const grabOffset = e.clientY - el.getBoundingClientRect().top; // respect where they grabbed
// ...track position + timestamp history for velocity
});
3. 中断可能性 — 最も重要な原則
「思考とジェスチャーは並行して起こる。」
すべてのアニメーションは、いつでも中断可能で、方向を変えられるものでなければなりません。ユーザーは、アニメーションの完了を待つことなく、動いている要素を空中でつかんで逆方向に動かせる必要があります。ユーザーが再びつかんだ閉じかけのモーダルは、まず閉じきってから再び開くのではなく、指に追従すべきです。
- トランジション中に、入力を決してロックしないでください。
- 常にプレゼンテーション(現在)の値からアニメーションし、ターゲット値からは決して行わないでください。 中断時には、要素の画面上の現在のトランスフォームを読み取り、そこから新しいアニメーションを開始します。論理値/ターゲット値から開始すると、目に見えるジャンプが発生します。
- ジェスチャー駆動のものには CSS トランジションや
@keyframesを避けてください — それらは空中でスムーズにつかんで逆方向に動かすことができません。スプリングはデフォルトで現在の値からアニメーションするため、これはまさに中断が必要とするものです。 - ジェスチャーが逆方向になったときは、速度をブレンドしてください — ハードカットしないでください。 逆方向への切り替え時に、あるアニメーションを別のアニメーションに置き換えると、速度の不連続、つまり「レンガの壁」が生じます。再ターゲットを通じて速度を引き継ぐスプリングライブラリはこれを回避します。(これは iOS の加算アニメーションがネイティブで行っていることです。Web では、現在の速度から再ターゲットするスプリングライブラリを選んでください。)
- 2D の動きは、独立した X と Y のスプリングに分解してください。 2D 距離に対する単一のスプリングは、X と Y が異なる速度を持つ場合に同期がずれます。
4. アニメーションよりも振る舞い — スプリングを使う
「アニメーションは、インターフェースによって規定されたものではなく、あなたとオブジェクトとの対話だと考えてください。」
事前にスクリプト化された固定 duration のアニメーションは、新しい入力に応答できません。スプリングは応答できます — 新しい入力は単にターゲットを変えるだけで、動きは連続性を保ちます。ユーザーが触れられるものには、スプリングを使ってください。
Apple は、物理の三つ組(mass/stiffness/damping)を意図的に、デザイナーに優しい 2 つのパラメータに置き換えました。次のように考えてください:
- ダンピング比 — オーバーシュートを制御します。
1.0= 臨界減衰、バウンスなし、スムーズに収束します。< 1.0= オーバーシュートして振動します。低いほど、よりバウンスします。 - レスポンス — 値がターゲットに到達するまでの速さを秒で表します。低いほど、よりキビキビしています。これは「duration」ではありません — スプリングには固定の duration がなく、その収束時間はパラメータから生じます。
デフォルト:
- ほとんどの UI はダンピング
1.0(臨界減衰)で始めてください — 優雅で気が散りません。 - バウンスを加える(ダンピング ~
0.8)のは、ジェスチャー自体が勢いを伴っていた場合のみ(フリック、スロー、ドラッグのリリース)にしてください。ただフェードインしただけのメニューのオーバーシュートは不自然に感じられ、フリックしたカードのオーバーシュートは正しく感じられます。
Apple が採用している具体的な値:
| インタラクション | ダンピング | レスポンス |
|---|---|---|
| 移動 / 位置変更(例: PiP) | 1.0 | 0.4 |
| 回転 | 0.8 | 0.4 |
| ドロワー / シート | 0.8 | 0.3 |
Web でのマッピング(Motion / Framer Motion): bounce + duration のスプリング API は、Apple のダンピング + レスポンスにほぼ対応します。安全なハウススタイルは、デフォルトでどこでも damping: 1.0 のスプリングを使うことです。バウンスは、勢い駆動の物理的なインタラクションのために取っておいてください。
import { animate } from 'motion';
// Critically damped default (no overshoot)
animate(el, { y: 0 }, { type: 'spring', bounce: 0, duration: 0.4 });
// Momentum interaction — a little bounce, only because a flick preceded it
animate(el, { y: target }, { type: 'spring', bounce: 0.2, duration: 0.4 });
5. 速度の引き継ぎ — ドラッグとアニメーションの間の継ぎ目
ジェスチャーが終わるとき、アニメーションは指の正確な速度で継続しなければならず、ドラッグとアニメーションの間に目に見える継ぎ目があってはなりません。これは、「流動的」と「まあまあ」を最も分ける細部です。
ポインタのリリース速度を、スプリングの初速度として渡します。一部のスプリング API は相対速度を求めます — ターゲットまでの残り距離で正規化してください:
relativeVelocity = gestureVelocity / (targetValue − currentValue)
例: 要素が y=50、ターゲットが y=150(残り 100px)、指が 50px/s で移動 → スプリングの初速度 = 50 / 100 = 0.5。Framer Motion / Motion は絶対 px/s 速度を直接受け取る(velocity オプション)ため、通常は生の値をそのまま渡します。
6. 運動量の投影 — ジェスチャーが向かっている先へアニメーションする
「小さな入力を、大きな出力にする。」
離した地点から最も近い境界にスナップさせてはいけません。速度を使って静止位置を投影します — ちょうどスクロールの減速と同じです — そしてその投影された地点に最も近いターゲットにスナップします。これにより、フリックが要素を投げるように感じられるのです。
Apple の正確な投影関数(Designing Fluid Interfaces のサンプルコードより):
// decelerationRate ≈ 0.998 for normal scroll feel; 0.99 for snappier
function project(initialVelocity /* px/s */, decelerationRate = 0.998) {
return (initialVelocity / 1000) * decelerationRate / (1 - decelerationRate);
}
const projectedEndpoint = currentPosition + project(releaseVelocity);
const target = nearestSnapPoint(projectedEndpoint); // choose target from the projection
animateSpringTo(target, { velocity: releaseVelocity }); // then hand off velocity (§5)
注: 物理学の教科書にある v²/(2·decel) は Apple が採用しているものではありません — 上記の指数減衰の形式を使用してください。これは優れたボトムシートやカルーセル(Vaul、Embla)における標準的な挙動です。
7. 空間的な一貫性 — 対称な経路、基点へのアンカー
「何かがある方向に消えたなら、それが来た場所から現れると期待する。」
- 同じ経路で登場し、退出する。 右からスライドインしたパネルは、右へ閉じなければなりません。右から入って下へ出るのは、つながりがなく混乱を招きます。
- インタラクションをその発生源にアンカーする。 メニュー、ポップオーバー、シートは、それをトリガーした要素から発生すべきです —
transform-originをトリガーに設定し、ボタンとコンテンツの空間的な関係を明確にします。(これは、ポップオーバーが中央ではなくトリガーから拡大するという、同じ原点認識のポイントです。) - 可逆なトランジションではイージングをミラーリングする ことで、往路が復路と一致するようにします(2つの方向に対して逆 cubic-bézier 制御点を使用します)。
8. ジェスチャーの方向にヒントを与える
人間は軌道から最終状態を予測します。中間の動きは、物事がどこへ向かっているかを伝えるべきです — コントロールセンターのモジュールは「あなたの指に向かって成長し、外へ広がります」。中間のフレームが結果を指し示すようにし、ただ盲目的に補間するだけにしないでください。
9. ラバーバンド — やわらかい境界
端では、ハードに止まるのではなく、徐々に抵抗します。ハードな停止は「凍りついた」ように読まれ、連続的な抵抗は「反応しているが、ここにはもう何もない」と読まれます。ユーザーが境界を越えてドラッグするほど増加する減衰を適用します。
// The further past the bound, the less the element follows — real things slow before they stop
function rubberband(overshoot, dimension, constant = 0.55) {
return (overshoot * dimension * constant) / (dimension + constant * Math.abs(overshoot));
}
10. ジェスチャー設計の詳細(「フィール」チェックリスト)
- タップ: タッチダウンでハイライトし(即座に)、タッチアップで確定します。ターゲットの周囲に約10pxのヒステリシス/ヒットパディングを追加し、ドラッグで離れて戻ることによるキャンセルを許可します。
- ドラッグ/スワイプ: 方向を確定する前に小さな移動しきい値(ヒステリシス、約10px)を要求し、その後は1:1で追従します。
- 最初の動きから、考えられるすべてのジェスチャーを並行して検出し、意図が明確になったら負けたものを自信を持ってキャンセルします。最終状態のみを報告する認識器(
swipeleft型のイベント)は避けてください — フィードバックに必要な連続的な追跡を捨ててしまいます。 - 曖昧さ解消の遅延を最小化する。 ダブルタップの検出は避けられずシングルタップを遅延させます。そのコストはダブルタップが本当に存在する場所でのみ支払ってください。
11. フレームレベルの滑らかさ
滑らかさはフレームの中身に関するものであり、単にフレームレートのことではありません。
- 1フレームあたりの位置変化を、ストロボ現象を避けるために知覚しきい値以下に保ちます。
- 非常に速い動きには、微妙なモーションブラー/ストレッチが速度を表現し、硬く鋭い筋よりも良く見えます。
requestAnimationFrameはウェブのディスプレイ同期クロックです(Apple はCADisplayLinkを使用しています)。コンポジタにとって扱いやすいプロパティ —transformとopacity— のみをアニメーションし、動きが差し迫っている場所ではwill-changeでヒントを与えます。
12. マテリアルと奥行き — 半透明が階層を伝える
Apple は半透明のマテリアルを、フォーカスを奪うことなく構造をもたらす浮遊する機能層として使用しています。ウェブでは、backdrop-filter で近似できます。
- ナビ、ツールバー、シートを半透明のレイヤーとして構築する(
backdrop-filter: blur()+ 半透明の背景)。コンテンツはその下をスクロールさせます — 固定の帯を占有する不透明なバーではありません。 - マテリアルの重さが階層を表します: より暗く/重いマテリアルは構造的な領域(サイドバー)を分離します。より軽いマテリアルはインタラクティブな要素(ボタン)に注意を引き寄せます。軽い半透明サーフェスを別の半透明サーフェスの上に重ねないでください — 可読性が崩壊します。
- 大きなサーフェスはより厚く見えるべきです: 小さなチップよりも強いブラー + より深いシャドウにします。コンテキストを考慮したシャドウを検討してください — 密な/テキストコンテンツの上では分離のために重く、単純な背景の上では軽くします。
- フォーカスするために暗くし、流れを保つために分離する。 モーダルなタスクでは、サーフェスを暗くするスクリムと組み合わせ、背景を後ろ/下に押しやります。並行する非ブロッキングのパネルでは、半透明とオフセットをスクリムなしで使用し、流れを中断させません。積み重なったシートでは、親レイヤーごとに段階的に暗くして後ろに押しやります。
- Vibrancy は変化する背景の上でもテキストを読みやすく保ちます。 ぼかした/半透明のサーフェスの上では、平坦なグレーのテキストを使わないでください — より高いコントラスト、わずかに重いウェイト、そして小さなレタースペーシングの追加を使用します。色は不透明なレイヤーに置き、半透明の前景には置きません。
- ハードな区切り線ではなく、スクロールエッジエフェクトを使う。 スティッキーヘッダーの下に 1px のボーダーを置く代わりに、コンテンツがフローティングクロームと出会う場所で小さなブラー/グラデーションのマスクをフェードさせます — フローティング UI が実際にコンテンツと重なる場所にのみ。
- 単にフェードさせるのではなく、マテリアライズする。 ガラス/ブラーのサーフェスでは、ブラー半径とスケールを進入/退出時に一緒にアニメーションさせ、単なる不透明度のフェードではなく、本物のマテリアルが到着するようにサーフェスを読ませます。
.toolbar {
background: rgba(255, 255, 255, 0.6);
backdrop-filter: blur(20px) saturate(180%);
border-top: 1px solid rgba(255, 255, 255, 0.4); /* bright top edge = light catching the material */
}
13. マルチモーダルフィードバック — モーション + サウンド + ハプティクス
五感を組み合わせるための 3 つのルール(Designing Audio-Haptic Experiences より):
- 因果性 — 何がフィードバックを引き起こしたのかが明白でなければなりません。実際の因果イベント(トグルの切り替え、アイテムが所定位置にスナップすること)でトリガーし、その特性をアクションの身体性に一致させます。
- 調和 — ビジュアル、サウンド、ハプティクスは同じフレームで発火しなければなりません。それらの間のレイテンシは錯覚を破壊します。CSS トランジションがオーディオ/ハプティクス(Vibration API)を遅らせないようにしてください。
- 有用性 — フィードバックはそれが価値を持つ場所にのみ追加します。ハプティクス/サウンドは意味のある瞬間(成功、エラー、コミット、スナップ)のために取っておきます。過剰なフィードバックは、ユーザーにすべてを無視するよう訓練します。
14. モーションの低減とアクセシビリティ
モーションの低減はフィードバックなしを意味しません — より穏やかで、前庭に影響を与えない同等のものを意味します。3 つの独立したシグナルに応答し、それらをコンポーネントに組み込んでください:
prefers-reduced-motion: reduce— スライド/スプリング/パララックスを短い不透明度のクロスフェードまたは静的なトランジションに置き換えます。弾力のある/オーバーシュートするものは削除します。理解を助ける不透明度/色の変化は保ちます。prefers-reduced-transparency: reduce— 半透明のサーフェスをより曇った/不透明なものにします: 背景の不透明度を上げ、ブラーを削除します。prefers-contrast: more— 明確でコントラストのあるボーダーを持つ、ほぼ不透明な背景にします。
また: ビューポート全体が動く背景、遅いループ振動(約 0.2 Hz / 5 秒に 1 サイクル付近)、急激な明るさのジャンプ(ダーク↔ライトのテーマ変更をイージングする)は避けてください。大きな移動オブジェクトは移動中に半透明にし、大きなサーフェスは大きな再配置の間はフェードアウトし、落ち着いたら再びフェードインさせます。
@media (prefers-reduced-motion: reduce) {
.sheet { transition: opacity 200ms ease; transform: none !important; }
}
@media (prefers-reduced-transparency: reduce) {
.toolbar { background: white; backdrop-filter: none; }
}
15. タイポグラフィ — オプティカルサイジング、トラッキング、行送り
Apple は文字の形状をサイズに応じて変化させるよう設計しています。同じ原則は Web にも当てはまります。(The Details of UI Typography、WWDC 2020 より。)
- トラッキング(letter-spacing)はサイズ固有のものです — すべてのサイズに単一の値を使ってはいけません。 大きなディスプレイ用テキストには負のトラッキングが適しています(文字が大きくなるほど、字間が広がりすぎて見えます)。小さなテキストには可読性のためにわずかに正のトラッキングが適しています。固定の
letter-spacingはどこかで必ず間違いになります。見出しは詰め、本文は0付近に保ちます。 - 行送り(line-height)はサイズに反比例します。 大きな見出しでは詰め、本文ではよりゆったりとります。アセンダー/ディセンダーが高い書体では行送りを増やし、情報密度の高い UI では詰めます。
- 階層はサイズだけでなく、ウェイト + サイズ + 行送りをひとつのセットとして構築します。 強調にはウェイトを使います — スペースを増やさずに存在感を加えられます。
- ユーザーのテキストサイズ設定(Dynamic Type)を尊重します。 テキストに合わせてレイアウトを拡大縮小します — スペースは固定 px ではなく
rem/emで指定する — ことで、フォントが大きくなってもレイアウトが崩れません。 - カスタム書体よりも、まずプラットフォームのシステムフォントを既定とします。 システムフォントにはすでにオプティカルサイジング、トラッキングテーブル、可読性の調整が備わっています。理由がある場合にのみ上書きします。
:root { font: 100%/1.5 system-ui, sans-serif; } /* body: system font, comfortable leading */
.display {
font-size: clamp(2rem, 5vw, 4rem);
line-height: 1.05; /* tight leading for large text */
letter-spacing: -0.02em; /* negative tracking as it grows */
font-optical-sizing: auto;
}
16. デザインの基盤 — 8つの原則
上記のモーションと作り込みは、Apple の8つのデザイン原則(Principles of Great Design、WWDC 2026)に基づくものです。これらを判断の拠り所となる名称として使用してください。
- 目的。 意図を持って作り、何を作らないかを決めます。あらゆる機能はユーザーの時間、注意、信頼を求めます。その予算は、見返りがあるところにのみ使ってください。
- 主体性。 人を制御下に置きます。選択肢を提示し、単一の道を強制しません。それを寛容さで支えます。うっかりミスには簡単に元に戻せるようにし、確認ダイアログは本当に破壊的で取り返しのつかない操作にのみ使用します(使用は控えめに。使いすぎると、人は確認を読み飛ばすように訓練されてしまいます)。
- 責任。 ユーザーの利益のために行動します。プライバシー:適切なタイミングで、必要なものだけを、透明性をもって尋ねます。安全性:特に AI において、誤用や害を想定します(アレルギー対応のレシピアプリは、有害な食材を提案してはなりません)。プレビュー、確認、免責事項を追加し、リスクが価値を上回る機能は削除します。
- 親しみやすさ。 人がすでに知っているものの上に築きます。直訳的すぎず抽象的すぎないメタファーを使用し(ゴミ箱は削除を意味します)、その物理法則を尊重します。一貫性を保ちます。同じ見た目のものは同じ動作をし、同じ場所に存在しなければなりません(macOS では閉じるボタンは常に左上)。そうすることで、人は次に何が起こるかを予測できます。慣れ親しんだパターンを破るのは、それがより優れていることを証明できる場合だけにし、その場合は想定せずにテストします。
- 柔軟性。 さまざまなコンテキスト、デバイス、あらゆる能力の範囲に対応するよう設計します。プラットフォーム(iPhone = 素早いタッチ、デスクトップ = 精密なポインター操作による深いワークフロー)と状況に適応させます。包括的に設計します(年齢、言語、専門知識、アクセシビリティ)。単一のレイアウトがすべての人に適合しない場合は、パーソナライズを許可します。コントロールを並べ替えたり、使わないものを非表示にしたりできるようにします。
- シンプルさ — ミニマリズムではありません。 不要なものを取り除き、核心的な目的を際立たせます。すべてを1か所に埋め込むのはミニマルに見えますが、シンプルではありません。簡潔にし(平易な言葉、専門用語なし、より少ないステップ)、明確にします(階層 — 順序、間隔、コントラスト — を使い、最も重要なものが最も明白になるようにします)。すべての要素がその場所にふさわしいものでなければなりません。文脈を追加することでシンプルになることもあります(残り時間を表示する動画のスクラバーなど)。よく使う道を最初に見せ、高度なオプションは1階層深くに置きます。
- 作り込み。 細部への妥協のない注意力が信頼を築きます。美しいタイポグラフィ、ライト/ダークに適応する色、明確なアイコン、そして即座で自然なフィードバックを与えるレスポンシブなアニメーション。何もランダムではありません。すべての間隔、タイミング、配置の値は、説明できる意図的な選択です。ぎくしゃくしたスクロール、ずれたアイコン、回転で崩れるレイアウトは、不注意に見えます。作り込みには反復と長寿命化が必要です。機能とハードウェアの変化に合わせてデザインを進化させ続けてください。
- 喜び。 他の7つを正しく行った結果であり、上から貼り付けた紙吹雪ではありません。人が感じてほしい感情(穏やかさ、自信、興奮)を決め、あらゆる判断でそれを強化します。
これらに資する戦術的なルール:
- フィードバックには4種類あります: ステータス、完了、警告、エラー。意味のある操作を確認し、進行中のステータスを明示し、問題の前に警告し、インラインで検証します(送信時ではなく)。
- 道案内。 すべての画面は次の問いに答えるべきです。ここはどこか?どこへ行けるか?何があるか?どうやって抜け出すか?ユーザーを決して閉じ込めてはいけません。
- グループ化とマッピング。 近接は関係を示唆します。コントロールはそれが影響するものの近くに置き、コントロールの配置はそれが変化させるものを反映するようにします。コントロールを説明するのにラベルが必要なら、マッピングが弱い証拠です。
- 直接的で具体的なラベルは、安全で一般的なラベルに勝ります。 ナビ項目は内容に基づいて名付けます(「ホーム」のような曖昧な包括名ではなく、「進捗」「ライブラリ」)。具体性が予測可能性を生みます。
17. プロセス
- インタラクティブにプロトタイプを作成する — インタラクティブなデモは「100万枚の静的デザイン」に値します。 インターフェースは構築して触ってみることで見えてきます。また、動作するプロトタイプは具体的な基準となるため、最終実装が凡庸になるのを防ぎます。
- インタラクションとビジュアルは一緒に設計します。 「どこからどこまでが一方で、どこからが他方かを区別できないようにすべきです。」モーションはピクセルの後に追加されるレイヤーではありません。
- 実際のコンテキストで実際のユーザーとテストし、モーションは新鮮な目でレビューします — スローモーションやフレーム単位で再生して、通常速度では見えないものを捉えましょう。
クイックリファレンス
| 目的 | 手法 | 具体的な値 |
|---|---|---|
| デフォルトの UI スプリング | 臨界減衰、オーバーシュートなし | damping 1.0、response 0.3–0.4 |
| モメンタム / フリックスプリング | 不足減衰、わずかなバウンス | damping ~0.8、response 0.3–0.4 |
| ジェスチャー → スプリング速度 | リリース速度を引き継ぐ | 正規化されている場合は gestureVelocity / (target − current) |
| フリックの着地点 | モメンタムを投影 | current + (v/1000)·d/(1−d)、d ≈ 0.998 |
| クリーンに中断する | プレゼンテーション(ライブ)値から開始 | 画面上のトランスフォームを読み取る |
| 反転時の「レンガの壁」を避ける | 再ターゲットを通じて速度を引き継ぐ | 速度をブレンドするスプリング |
| 可逆的なトランジション | イージングカーブをミラーリング | 逆 cubic-bézier |
| 反転か確定かを判断する | 位置ではなく速度の符号を使う | リリース時 |
| 1:1 ドラッグ | Pointer Events + キャプチャ | グラブオフセットを尊重 |
| フィードバック | ポインターダウン時に、継続的に | 最後だけにしない |
| 境界 | ラバーバンド、ハードストップにしない | 漸進的な抵抗 |
| 半透明のクローム | backdrop-filter レイヤー | コンテンツが下をスクロールする |
| タイプトラッキング | サイズごとに設定、固定にしない | 大きなテキストは詰める(-0.02em)、本文はほぼ 0 |
| モーションの低減 | スライド / スプリングではなくクロスフェード | @media (prefers-reduced-motion) |