apple-design について
apple-designは、AppleのWWDCで語られた原則をCSSやポインター操作に応用する、Webインターフェース向けのデザインスキルです。即時のフィードバック、中断可能な動き、速度の引き継ぎを重視します。
主な機能
- 01ポインター操作と直接操作
- 02中断可能なスプリングアニメーション
- 03速度の引き継ぎと勢いの投影
- 04空間的一貫性と起点の固定
- 05ラバーバンド式の境界フィードバック
- 06フレーム単位の滑らかさに関する指針
活用シーン
- 01動作中にも反転できるドラッグ操作の設計
- 02ドロワーやカルーセルの勢いに応じた停止位置の決定
- 03Webインターフェースのジェスチャー追従性の改善
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ davidhdev/ react-bits --skill apple-designインストール後、Claude Code で/apple-designを入力して読み込まれたか確認します。
詳細
Apple Design
Apple がどのようにして、コンピューターのように感じられなくなり、あなたの延長のように感じられるインターフェースを構築しているか。この知識は Apple の WWDC デザイントーク — 主に Designing Fluid Interfaces(WWDC 2018)— から得られたもので、Web プラットフォーム(CSS、Pointer Events、requestAnimationFrame、Motion/Framer Motion のようなスプリングライブラリ)向けに蒸留・翻訳したものです。
一貫するテーマ:インターフェースは、モーションが現在の画面上の値から始まり、ユーザーの速度を引き継ぎ、勢いを前方に投影し、いつでも掴んで反転できるときに、生きているように感じられる。 スプリングは、本質的に中断可能で速度を認識するため、このすべてを自然にするツールです。
中心となる考え方
「インターフェースを、私たちが考え、動く方法に合わせると、魔法のようなことが起こります — それはコンピューターのように感じられなくなり、私たちのシームレスな延長のように感じられ始めます。」
インターフェースは、物理世界のように振る舞うとき、流動的です。つまり、物事は即座に反応し、連続的に動き、勢いを保ち、境界で抵抗し、動きの途中で方向を変えられます。以下はすべて、それに近づくための方法です。
Apple はデザインを、人間の 4 つのニーズ — 安全/予測可能性、理解、達成、喜び — に奉仕するものとして位置づけています。ここにあるすべてのルールは、そのいずれかに奉仕します。
1. レスポンス — レイテンシをなくす
遅延が現れた瞬間、直接性の感覚は「崖から落ちる」ように失われます。レスポンスは、他のすべてがその上に築かれる基盤です。
- リリース時ではなく、ポインターダウン時に反応する。 ボタンが押された瞬間にハイライトします。フィードバックを表示するために
click/タッチアップを待つと、死んでいるように感じられます。 - あらゆるレイテンシに警戒する。 デバウンス、人為的なタイマー、トランジションの待機、約 300ms のタップ遅延を監査します。入力経路にある、本質的でないものはすべてリグレッションです。
- フィードバックは、最後だけでなく、インタラクションの最中に連続的でなければならない。 ドラッグ、スライダー、ドロワーの場合、ポインターと 1:1 で最後まで UI を更新します — ジェスチャーが完了したときだけアニメーションしないでください。
/* Feedback lives on the press, and it's instant */
.button:active {
transform: scale(0.97);
transition: transform 100ms ease-out;
}
2. 直接操作 — 1:1 の追従
「タッチとコンテンツは一緒に動くべきです。」
ユーザーが何かをドラッグするとき、それは指に貼り付いたままでなければならず、どこを掴んだかというオフセットを尊重する必要があります。掴んだときに要素の中心にスナップすると、幻想は即座に壊れます。
setPointerCaptureを伴う Pointer Events を使用して、ポインターが要素の境界を離れても追従が続くようにします。- 現在のポイントだけでなく、短い速度/位置の履歴(直近数回の
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. 中断可能性 — 最も重要な単一の原則
「思考とジェスチャーは並行して起こります。」
すべてのアニメーションは、いつでも中断可能で方向転換可能でなければなりません。ユーザーは、動いている要素を飛んでいる途中で掴んで、アニメーションの完了を待たずに反転できなければなりません。ユーザーが再び掴んだ閉じつつあるモーダルは、指に追従すべきです — 先に閉じるのを完了してから、再び開くのではありません。
- トランジション中に入力をロックしない。
- 常にプレゼンテーション(現在)の値からアニメーションし、ターゲット値からは決してアニメーションしない。 中断時には、要素のライブの画面上の transform を読み取り、そこから新しいアニメーションを開始します。論理/ターゲット値から開始すると、目に見えるジャンプが発生します。
- ジェスチャー駆動のものには CSS トランジションと
@keyframesを避ける — それらは飛んでいる途中で滑らかに掴んで反転できません。スプリングはデフォルトで現在の値からアニメーションし、まさにそれが中断に必要なものです。 - ジェスチャーが反転するときは、速度をブレンドする — ハードカットしない。 反転時に 1 つのアニメーションを別のものに置き換えると、速度の不連続性、つまり「レンガの壁」が生じます。再ターゲットを通じて速度を引き継ぐスプリングライブラリはそれを回避します。(これは iOS の加算アニメーションがネイティブで行っていることです。Web では、現在の速度から再ターゲットするスプリングライブラリを選択してください。)
- 2D モーションを独立した X と Y のスプリングに分解する。 2D 距離に対する単一のスプリングは、X と Y が異なる速度を持つときに同期がずれます。
4. アニメーションではなく挙動 — スプリングを使う
「アニメーションは、あなたとオブジェクトの間の会話だと考えてください。インターフェースによって規定されるものではありません。」
あらかじめスクリプト化された固定時間のアニメーションは、新しい入力に反応できません。スプリングは反応できます。新しい入力はターゲットを変えるだけで、動きは連続したままです。ユーザーが触れる可能性のあるものには、すべてスプリングを使いましょう。
Apple は、物理学の三つ組(mass/stiffness/damping)を意図的に、デザイナーに優しい2つのパラメータに置き換えました。次のように考えてください。
- Damping ratio — オーバーシュートを制御します。
1.0= 臨界減衰、バウンスなし、滑らかに収束します。< 1.0= オーバーシュートして振動します。低いほど、よく跳ねます。 - Response — 値がターゲットに到達するまでの速さを、秒単位で表します。低いほど、キビキビしています。これは「duration」ではありません — スプリングに固定の duration はなく、その収束時間はパラメータから自然に決まります。
デフォルト:
- ほとんどの UI は damping
1.0(臨界減衰)から始めましょう — 優雅で、気を散らしません。 - バウンスを加える(damping ~
0.8)のは、そのジェスチャー自体が勢いを伴っていた場合のみ(フリック、スロー、ドラッグのリリース)です。ただフェードインしただけのメニューのオーバーシュートは不自然に感じられます。フリックしたカードのオーバーシュートは自然に感じられます。
Apple が実際に採用している具体的な値:
| インタラクション | Damping | Response |
|---|---|---|
| 移動 / 再配置(例: PiP) | 1.0 | 0.4 |
| 回転 | 0.8 | 0.4 |
| ドロワー / シート | 0.8 | 0.3 |
Web でのマッピング(Motion / Framer Motion): bounce + duration のスプリング API は、Apple の damping + response にかなり近く対応します。安全なハウススタイルは、デフォルトでどこでも 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つの方向に逆の3次ベジェ制御点を使います)。
8. ジェスチャーの方向性を示すヒント
人間は軌道から最終状態を予測します。途中の動きは、物事がどこへ向かっているかを伝えるべきです — Control Center のモジュールは「あなたの指に向かって大きく、外へと成長する」のです。中間のフレームを、単に盲目的に補間するのではなく、結果を指し示すものにしましょう。
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. フレームレベルの滑らかさ
滑らかさは、単にフレームレートだけでなく、フレームの中身が重要です。
- ストロボ現象を避けるため、フレームごとの位置変化を知覚しきい値以下に保ちます。
- 非常に高速な動きには、微妙なモーションブラー/ストレッチが速度を表現し、硬くシャープな筋よりも良く伝わります。
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 は文字の形をサイズに応じて変化させるようにデザインしています。同じ規律がウェブにも当てはまります。(The Details of UI Typography、WWDC 2020 より。)
- トラッキング(letter-spacing)はサイズ固有です — すべてのサイズに 1 つの値を使ってはいけません。 大きなディスプレイテキストにはネガティブなトラッキングが望ましく(文字が大きくなるにつれて文字間が広がりすぎて見えます)、小さなテキストには可読性のためにわずかにポジティブなトラッキングが望ましいです。固定の
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) |