게이즈 호버

Gaze hover

눈이 향한 곳의 요소가 자동으로 하이라이트되는 상태 — 마우스 올림(hover)의 시선 버전.

다른 이름: Eye tracking hoverLook-to-highlight
···
html
<div class="row">
  <button class="gb" id="b0">Play</button>
  <button class="gb" id="b1">Save</button>
  <button class="gb" id="b2">Share</button>
</div><div class="dot" id="gd"></div>
css
.dot{position:absolute;width:16px;height:16px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 0 7px color-mix(in srgb,var(--accent) 22%,transparent);pointer-events:none;
  transform:translate(-50%,-50%);transition:left .5s cubic-bezier(.3,.8,.3,1),top .5s cubic-bezier(.3,.8,.3,1)}
body{background:radial-gradient(circle at 50% 30%,#1c2440,#0b0d18 70%)}
.row{position:absolute;inset:0;display:flex;gap:clamp(10px,3vmin,20px);align-items:center;justify-content:center}
.gb{padding:clamp(10px,3vmin,16px) clamp(16px,4vmin,26px);border-radius:999px;border:1px solid rgba(255,255,255,.16);
  background:rgba(255,255,255,.06);color:#cfd2e6;font-weight:700;font-size:clamp(11px,3vmin,14px);
  transition:transform .35s,background .35s,color .35s,box-shadow .35s}
.gb.focus{background:var(--accent);color:#fff;transform:scale(1.1);box-shadow:0 0 0 8px color-mix(in srgb,var(--accent) 20%,transparent)}
js
const btns=[...document.querySelectorAll('.gb')];
const dot=document.getElementById('gd');
let i=0;
function place(){
  const r=btns[i].getBoundingClientRect();
  dot.style.left=(r.left+r.width/2)+'px'; dot.style.top=(r.top-10)+'px';
  btns.forEach((b,j)=>b.classList.toggle('focus',j===i));
}
place();
setInterval(()=>{ i=(i+1)%btns.length; place(); },1500);

마우스가 없는 헤드셋에서는 "지금 무엇을 보고 있는지"가 곧 포인터다. 눈이 버튼 위에 머무르면 그 버튼이 밝아지거나 살짝 커지면서 "선택 가능"임을 알려준다 — 이게 게이즈 호버다.

여기서 중요한 규칙 하나: 시선만으로는 절대 실행(클릭)하지 않는다. 눈은 화면을 훑어보기만 해도 계속 움직이기 때문에, 본 것마다 바로 실행되면 원치 않는 동작이 쏟아진다(이걸 "마이다스 터치 문제"라 부른다). 그래서 게이즈는 hover 상태만 표시하고, 실제 확정은 손가락 핀치나 컨트롤러 버튼 같은 별도 제스처로 한다.

데모는 시선이 옮겨 다니듯 세 버튼 사이를 오가며 머무른 버튼만 밝아지는 걸 보여준다. 실제 앱에서는 이 하이라이트가 핀치와 짝을 이뤄야 완전한 상호작용이 된다.

언제 쓰나

핀치·컨트롤러 클릭과 항상 짝을 지어 쓰세요. 게이즈만으로 실행되는 UI는 사용자가 둘러보기만 해도 오작동합니다.