atan2() で要素をカーソルの方向に向ける(角度計算を CSS に任せる)
rotate: atan2(var(--dy), var(--dx)) と書けば、2点間の角度を CSS が計算してくれるので、JS はカーソルとのずれ(dx, dy)を渡すだけでよくなる。
どんな時に使う?
- カーソルを追いかける矢印・目玉・コンパスの針などの「向き」を持つ演出。
- 円形メニューや放射状のレイアウトで、中心からの方向に合わせて要素を回したいとき。
これまでは JS 側で Math.atan2(dy, dx) を計算して deg に直し、transform に書き込むのが定番だった。CSS の atan2() は角度(<angle>)を返すので、計算と単位変換をまるごと CSS 側に移せる。
コード
css
.arrow {
/* --dx, --dy = 要素の中心から見たカーソルの位置 */
rotate: atan2(var(--dy, 0px), var(--dx, 1px));
transition: rotate 0.1s linear; /* 任意: 少しなめらかに */
}js
const arrow = document.querySelector('.arrow');
addEventListener('pointermove', (e) => {
const r = arrow.getBoundingClientRect();
arrow.style.setProperty('--dx', `${e.clientX - (r.left + r.width / 2)}px`);
arrow.style.setProperty('--dy', `${e.clientY - (r.top + r.height / 2)}px`);
});- 引数の順番は
atan2(縦, 横)。Math.atan2と同じく y が先。 - 角度 0 は右向きなので、素材の矢印は右を向いた状態で作っておくと補正が要らない(上向きの素材なら
calc(atan2(...) + 90deg))。 - 2つの引数は同じ種類の値ならよい(
px同士、数値同士など)。単位が揃っていればpxのまま渡せる。
注意点・対応状況
- カーソル位置そのものは CSS では取れないので、
--dx/--dyを更新する JS は残る。CSS が受け持つのは角度の計算だけ。 atan2()はsin()cos()などの三角関数と一緒に、主要ブラウザすべてで使える(2023 年に揃った)。- 子要素が大量にあるときは、親に
--mx/--my(カーソル座標)だけを置き、各要素が自分の位置との差をcalc()で出す形にすると JS の更新が1回で済む。 - 動きが苦手な人向けに
@media (prefers-reduced-motion: reduce)ではtransitionを外すか追従をやめる。
出典
- @aviralj02(2026-11-03)