hover

dock magnification / fisheye dock

ドックマグニファイ

ドックマグニファイ

ドックマグニファイ

カーソルに一番近いアイコンが最大に膨らみ、隣・その隣となだらかに小さくなっていくmacOSドックの拡大。1つだけ大きくする実装との差は距離の減衰カーブにあり、そこを二次で落とすとあの「山」の形になる。

01 — Demo video

Play live →

02 — Prompt template

アイコンを横一列に並べたドックに dock magnification を実装してください。

- mousemove でポインタのX座標を取り、各アイテムの中心とのX距離 d を求める
- 倍率は距離の二次関数で落とす: scale = 1 + ({{maxScale}} - 1) * max(0, 1 - (d / {{range}})^2)
  {{range}}px より遠いアイテムは等倍のまま(隣が連れて膨らむ「山」がドックらしさの正体)
- 中心の測定は transform 適用後の矩形ではなく、レイアウト上の位置(offsetLeft)から出す
  拡大後の矩形で測ると中心が自分の拡大に引きずられて震える
- 適用するのは transform: translateY(せり出し) scale() だけ。せり出し量は倍率に比例させ、最大 {{lift}}px
- width / height / margin は絶対に動かさない(列の全アイテムにリフローが波及してカクつく)
- transform-origin: bottom center。底辺を揃えたまま上へ伸ばす
- transition: transform {{duration}}s ease-out。mousemove ごとの値の飛びをここで吸収する
- ドックから mouseleave したら全アイテムを scale(1) に戻す
- タッチ環境には hover が無いので、指のX座標(touchmove)で同じ計算を行うか、拡大を無効にして等倍で並べる。ホバー前提のまま放置しない
- prefers-reduced-motion: reduce では拡大を行わず、いま指しているアイテムを背景色の変化だけで示す
アイコンを横一列に並べたドックに dock magnification を実装してください。

- mousemove でポインタのX座標を取り、各アイテムの中心とのX距離 d を求める
- 倍率は距離の二次関数で落とす: scale = 1 + ({{maxScale}} - 1) * max(0, 1 - (d / {{range}})^2)
  {{range}}px より遠いアイテムは等倍のまま(隣が連れて膨らむ「山」がドックらしさの正体)
- 中心の測定は transform 適用後の矩形ではなく、レイアウト上の位置(offsetLeft)から出す
  拡大後の矩形で測ると中心が自分の拡大に引きずられて震える
- 適用するのは transform: translateY(せり出し) scale() だけ。せり出し量は倍率に比例させ、最大 {{lift}}px
- width / height / margin は絶対に動かさない(列の全アイテムにリフローが波及してカクつく)
- transform-origin: bottom center。底辺を揃えたまま上へ伸ばす
- transition: transform {{duration}}s ease-out。mousemove ごとの値の飛びをここで吸収する
- ドックから mouseleave したら全アイテムを scale(1) に戻す
- タッチ環境には hover が無いので、指のX座標(touchmove)で同じ計算を行うか、拡大を無効にして等倍で並べる。ホバー前提のまま放置しない
- prefers-reduced-motion: reduce では拡大を行わず、いま指しているアイテムを背景色の変化だけで示す
アイコンを横一列に並べたドックに dock magnification を実装してください。

- mousemove でポインタのX座標を取り、各アイテムの中心とのX距離 d を求める
- 倍率は距離の二次関数で落とす: scale = 1 + ({{maxScale}} - 1) * max(0, 1 - (d / {{range}})^2)
  {{range}}px より遠いアイテムは等倍のまま(隣が連れて膨らむ「山」がドックらしさの正体)
- 中心の測定は transform 適用後の矩形ではなく、レイアウト上の位置(offsetLeft)から出す
  拡大後の矩形で測ると中心が自分の拡大に引きずられて震える
- 適用するのは transform: translateY(せり出し) scale() だけ。せり出し量は倍率に比例させ、最大 {{lift}}px
- width / height / margin は絶対に動かさない(列の全アイテムにリフローが波及してカクつく)
- transform-origin: bottom center。底辺を揃えたまま上へ伸ばす
- transition: transform {{duration}}s ease-out。mousemove ごとの値の飛びをここで吸収する
- ドックから mouseleave したら全アイテムを scale(1) に戻す
- タッチ環境には hover が無いので、指のX座標(touchmove)で同じ計算を行うか、拡大を無効にして等倍で並べる。ホバー前提のまま放置しない
- prefers-reduced-motion: reduce では拡大を行わず、いま指しているアイテムを背景色の変化だけで示す

03 — Params

  • maxScale(直下の最大倍率) — 範囲 1〜2.4 / 初期 1.6
    1.5〜1.8倍が実用。2倍を超えると隣を押しのけて列が暴れて見える。

  • range(拡大が届く距離 px) — 範囲 40〜320 / 初期 160
    アイコン3〜4個分(140〜180px)で山がなだらかになる。狭いほど反応が鋭く、機械的になる。

  • lift(せり出す量 px) — 範囲 0〜24 / 初期 10
    拡大に比例して上へ持ち上げる量。0だと純粋な拡大、8〜12pxで「せり出す」感じが出る。

  • duration(倍率が追いつく時間 s) — 範囲 0〜0.5 / 初期 0.12
    0.1〜0.15sが滑らか。0.3sを超えるとカーソルに遅れて付いてくる重さが出る。

04 — Vocab

  • 距離減衰(falloff) — カーソルからの距離を倍率へ変換する曲線。二次で落とすとドック特有のなだらかな山になり、線形だと稜線が角張る。

  • フィッシュアイ(fisheye) — 注目点だけを拡大して周辺を縮めて見せる情報可視化の手法。ドックの拡大はその応用で、狭い帯に多数の項目を置くための道具。

  • transform-origin: bottom — 拡大の基準点を下端に置く指定。底辺が揃ったまま上だけ伸びるので「せり出す」印象になる。

  • リフロー(reflow) — width/heightを動かすと走るレイアウト再計算。横一列では全アイテムに波及するため、拡大は必ずtransformで行う。

  • hover: none — ポインタでのホバーができない環境を判定するメディア特性。タッチではホバー前提の演出を切るか、指の座標で代替する。

05 — NG → OK examples

NG

言い方: 「「macOSのDockみたいに、ホバーしたらアイコンが大きくなるナビにして」」

なぜNG: 「Dockみたい」だけだと、ホバー中の1個だけがポンと拡大する実装が返ってくる。Dockらしさの正体は隣が連れて膨らむ距離の減衰なので、影響範囲と落とし方を言わないと再現されない。加えて width/height で拡大され、列全体が押し合ってガタつく実装も定番の失敗。

OK

言い方: 「「dock magnificationを実装。ポインタXと各アイコン中心のX距離dで scale = 1 + 0.6 * max(0, 1 - (d/160)^2)、最大1.6倍。中心はoffsetLeftから算出。transform: translateY(最大-10px) scale() のみで、transform-origin: bottom、transition 0.12s ease-out。leaveで等倍に戻す」」

なぜOK: 減衰式・影響範囲・最大倍率・変形プロパティ・戻しまで数値で指定してある。「中心はoffsetLeftから」「transformのみ」の2点が、震えとガタつきという2大失敗を先回りで潰している。

Create a free website with Framer, the website builder loved by startups, designers and agencies.