Spaces:
Running
Running
Tooltip value now follows playback while the cursor stays on a cell
Browse files- ep0/viewer.html +12 -5
- ep1/viewer.html +12 -5
- ep2/viewer.html +12 -5
- ep3/viewer.html +12 -5
- ep4/viewer.html +12 -5
- ep5/viewer.html +12 -5
ep0/viewer.html
CHANGED
|
@@ -314,17 +314,24 @@ function drawTactile(i){
|
|
| 314 |
ctx.fillText(peak>0?String(peak):'\u2014',lx,cTop+2*fs+3);
|
| 315 |
ctx.textAlign='left';
|
| 316 |
});
|
|
|
|
|
|
|
| 317 |
}
|
| 318 |
|
|
|
|
|
|
|
|
|
|
| 319 |
cHand.addEventListener('mousemove',e=>{
|
| 320 |
const r=cHand.getBoundingClientRect(),mx=e.clientX-r.left,my=e.clientY-r.top;
|
| 321 |
-
let
|
| 322 |
-
for(
|
| 323 |
-
|
|
|
|
|
|
|
| 324 |
tacTip.style.left=Math.min(mx+12,r.width-160)+'px'; tacTip.style.top=Math.max(0,my-30)+'px';
|
| 325 |
-
tacTip.textContent=
|
| 326 |
else tacTip.style.display='none';});
|
| 327 |
-
cHand.addEventListener('mouseleave',()=>tacTip.style.display='none');
|
| 328 |
|
| 329 |
function loop(){update();if(playing)requestAnimationFrame(loop);}
|
| 330 |
|
|
|
|
| 314 |
ctx.fillText(peak>0?String(peak):'\u2014',lx,cTop+2*fs+3);
|
| 315 |
ctx.textAlign='left';
|
| 316 |
});
|
| 317 |
+
if(_hoverIdx>=0 && _hit[_hoverIdx] && tacTip.style.display!=='none')
|
| 318 |
+
tacTip.textContent=tipText(_hit[_hoverIdx]); // 播放时数值随帧刷新
|
| 319 |
}
|
| 320 |
|
| 321 |
+
// 记住悬浮的是"哪个格子"(索引), 每帧重绘后用最新值刷新文字, 鼠标不动也会跟着播放更新
|
| 322 |
+
let _hoverIdx=-1;
|
| 323 |
+
function tipText(h){return `${h.hand} \u00b7 ${h.part} \u00b7 pt ${h.pt} \u00b7 ${h.v}`;}
|
| 324 |
cHand.addEventListener('mousemove',e=>{
|
| 325 |
const r=cHand.getBoundingClientRect(),mx=e.clientX-r.left,my=e.clientY-r.top;
|
| 326 |
+
let bi=-1,bd=1e9;
|
| 327 |
+
for(let i=0;i<_hit.length;i++){const c=_hit[i],d=Math.hypot(mx-c.cx,my-c.cy);
|
| 328 |
+
if(d<c.r*1.15&&d<bd){bd=d;bi=i;}}
|
| 329 |
+
_hoverIdx=bi;
|
| 330 |
+
if(bi>=0){tacTip.style.display='block';
|
| 331 |
tacTip.style.left=Math.min(mx+12,r.width-160)+'px'; tacTip.style.top=Math.max(0,my-30)+'px';
|
| 332 |
+
tacTip.textContent=tipText(_hit[bi]);}
|
| 333 |
else tacTip.style.display='none';});
|
| 334 |
+
cHand.addEventListener('mouseleave',()=>{tacTip.style.display='none';_hoverIdx=-1;});
|
| 335 |
|
| 336 |
function loop(){update();if(playing)requestAnimationFrame(loop);}
|
| 337 |
|
ep1/viewer.html
CHANGED
|
@@ -314,17 +314,24 @@ function drawTactile(i){
|
|
| 314 |
ctx.fillText(peak>0?String(peak):'\u2014',lx,cTop+2*fs+3);
|
| 315 |
ctx.textAlign='left';
|
| 316 |
});
|
|
|
|
|
|
|
| 317 |
}
|
| 318 |
|
|
|
|
|
|
|
|
|
|
| 319 |
cHand.addEventListener('mousemove',e=>{
|
| 320 |
const r=cHand.getBoundingClientRect(),mx=e.clientX-r.left,my=e.clientY-r.top;
|
| 321 |
-
let
|
| 322 |
-
for(
|
| 323 |
-
|
|
|
|
|
|
|
| 324 |
tacTip.style.left=Math.min(mx+12,r.width-160)+'px'; tacTip.style.top=Math.max(0,my-30)+'px';
|
| 325 |
-
tacTip.textContent=
|
| 326 |
else tacTip.style.display='none';});
|
| 327 |
-
cHand.addEventListener('mouseleave',()=>tacTip.style.display='none');
|
| 328 |
|
| 329 |
function loop(){update();if(playing)requestAnimationFrame(loop);}
|
| 330 |
|
|
|
|
| 314 |
ctx.fillText(peak>0?String(peak):'\u2014',lx,cTop+2*fs+3);
|
| 315 |
ctx.textAlign='left';
|
| 316 |
});
|
| 317 |
+
if(_hoverIdx>=0 && _hit[_hoverIdx] && tacTip.style.display!=='none')
|
| 318 |
+
tacTip.textContent=tipText(_hit[_hoverIdx]); // 播放时数值随帧刷新
|
| 319 |
}
|
| 320 |
|
| 321 |
+
// 记住悬浮的是"哪个格子"(索引), 每帧重绘后用最新值刷新文字, 鼠标不动也会跟着播放更新
|
| 322 |
+
let _hoverIdx=-1;
|
| 323 |
+
function tipText(h){return `${h.hand} \u00b7 ${h.part} \u00b7 pt ${h.pt} \u00b7 ${h.v}`;}
|
| 324 |
cHand.addEventListener('mousemove',e=>{
|
| 325 |
const r=cHand.getBoundingClientRect(),mx=e.clientX-r.left,my=e.clientY-r.top;
|
| 326 |
+
let bi=-1,bd=1e9;
|
| 327 |
+
for(let i=0;i<_hit.length;i++){const c=_hit[i],d=Math.hypot(mx-c.cx,my-c.cy);
|
| 328 |
+
if(d<c.r*1.15&&d<bd){bd=d;bi=i;}}
|
| 329 |
+
_hoverIdx=bi;
|
| 330 |
+
if(bi>=0){tacTip.style.display='block';
|
| 331 |
tacTip.style.left=Math.min(mx+12,r.width-160)+'px'; tacTip.style.top=Math.max(0,my-30)+'px';
|
| 332 |
+
tacTip.textContent=tipText(_hit[bi]);}
|
| 333 |
else tacTip.style.display='none';});
|
| 334 |
+
cHand.addEventListener('mouseleave',()=>{tacTip.style.display='none';_hoverIdx=-1;});
|
| 335 |
|
| 336 |
function loop(){update();if(playing)requestAnimationFrame(loop);}
|
| 337 |
|
ep2/viewer.html
CHANGED
|
@@ -314,17 +314,24 @@ function drawTactile(i){
|
|
| 314 |
ctx.fillText(peak>0?String(peak):'\u2014',lx,cTop+2*fs+3);
|
| 315 |
ctx.textAlign='left';
|
| 316 |
});
|
|
|
|
|
|
|
| 317 |
}
|
| 318 |
|
|
|
|
|
|
|
|
|
|
| 319 |
cHand.addEventListener('mousemove',e=>{
|
| 320 |
const r=cHand.getBoundingClientRect(),mx=e.clientX-r.left,my=e.clientY-r.top;
|
| 321 |
-
let
|
| 322 |
-
for(
|
| 323 |
-
|
|
|
|
|
|
|
| 324 |
tacTip.style.left=Math.min(mx+12,r.width-160)+'px'; tacTip.style.top=Math.max(0,my-30)+'px';
|
| 325 |
-
tacTip.textContent=
|
| 326 |
else tacTip.style.display='none';});
|
| 327 |
-
cHand.addEventListener('mouseleave',()=>tacTip.style.display='none');
|
| 328 |
|
| 329 |
function loop(){update();if(playing)requestAnimationFrame(loop);}
|
| 330 |
|
|
|
|
| 314 |
ctx.fillText(peak>0?String(peak):'\u2014',lx,cTop+2*fs+3);
|
| 315 |
ctx.textAlign='left';
|
| 316 |
});
|
| 317 |
+
if(_hoverIdx>=0 && _hit[_hoverIdx] && tacTip.style.display!=='none')
|
| 318 |
+
tacTip.textContent=tipText(_hit[_hoverIdx]); // 播放时数值随帧刷新
|
| 319 |
}
|
| 320 |
|
| 321 |
+
// 记住悬浮的是"哪个格子"(索引), 每帧重绘后用最新值刷新文字, 鼠标不动也会跟着播放更新
|
| 322 |
+
let _hoverIdx=-1;
|
| 323 |
+
function tipText(h){return `${h.hand} \u00b7 ${h.part} \u00b7 pt ${h.pt} \u00b7 ${h.v}`;}
|
| 324 |
cHand.addEventListener('mousemove',e=>{
|
| 325 |
const r=cHand.getBoundingClientRect(),mx=e.clientX-r.left,my=e.clientY-r.top;
|
| 326 |
+
let bi=-1,bd=1e9;
|
| 327 |
+
for(let i=0;i<_hit.length;i++){const c=_hit[i],d=Math.hypot(mx-c.cx,my-c.cy);
|
| 328 |
+
if(d<c.r*1.15&&d<bd){bd=d;bi=i;}}
|
| 329 |
+
_hoverIdx=bi;
|
| 330 |
+
if(bi>=0){tacTip.style.display='block';
|
| 331 |
tacTip.style.left=Math.min(mx+12,r.width-160)+'px'; tacTip.style.top=Math.max(0,my-30)+'px';
|
| 332 |
+
tacTip.textContent=tipText(_hit[bi]);}
|
| 333 |
else tacTip.style.display='none';});
|
| 334 |
+
cHand.addEventListener('mouseleave',()=>{tacTip.style.display='none';_hoverIdx=-1;});
|
| 335 |
|
| 336 |
function loop(){update();if(playing)requestAnimationFrame(loop);}
|
| 337 |
|
ep3/viewer.html
CHANGED
|
@@ -314,17 +314,24 @@ function drawTactile(i){
|
|
| 314 |
ctx.fillText(peak>0?String(peak):'\u2014',lx,cTop+2*fs+3);
|
| 315 |
ctx.textAlign='left';
|
| 316 |
});
|
|
|
|
|
|
|
| 317 |
}
|
| 318 |
|
|
|
|
|
|
|
|
|
|
| 319 |
cHand.addEventListener('mousemove',e=>{
|
| 320 |
const r=cHand.getBoundingClientRect(),mx=e.clientX-r.left,my=e.clientY-r.top;
|
| 321 |
-
let
|
| 322 |
-
for(
|
| 323 |
-
|
|
|
|
|
|
|
| 324 |
tacTip.style.left=Math.min(mx+12,r.width-160)+'px'; tacTip.style.top=Math.max(0,my-30)+'px';
|
| 325 |
-
tacTip.textContent=
|
| 326 |
else tacTip.style.display='none';});
|
| 327 |
-
cHand.addEventListener('mouseleave',()=>tacTip.style.display='none');
|
| 328 |
|
| 329 |
function loop(){update();if(playing)requestAnimationFrame(loop);}
|
| 330 |
|
|
|
|
| 314 |
ctx.fillText(peak>0?String(peak):'\u2014',lx,cTop+2*fs+3);
|
| 315 |
ctx.textAlign='left';
|
| 316 |
});
|
| 317 |
+
if(_hoverIdx>=0 && _hit[_hoverIdx] && tacTip.style.display!=='none')
|
| 318 |
+
tacTip.textContent=tipText(_hit[_hoverIdx]); // 播放时数值随帧刷新
|
| 319 |
}
|
| 320 |
|
| 321 |
+
// 记住悬浮的是"哪个格子"(索引), 每帧重绘后用最新值刷新文字, 鼠标不动也会跟着播放更新
|
| 322 |
+
let _hoverIdx=-1;
|
| 323 |
+
function tipText(h){return `${h.hand} \u00b7 ${h.part} \u00b7 pt ${h.pt} \u00b7 ${h.v}`;}
|
| 324 |
cHand.addEventListener('mousemove',e=>{
|
| 325 |
const r=cHand.getBoundingClientRect(),mx=e.clientX-r.left,my=e.clientY-r.top;
|
| 326 |
+
let bi=-1,bd=1e9;
|
| 327 |
+
for(let i=0;i<_hit.length;i++){const c=_hit[i],d=Math.hypot(mx-c.cx,my-c.cy);
|
| 328 |
+
if(d<c.r*1.15&&d<bd){bd=d;bi=i;}}
|
| 329 |
+
_hoverIdx=bi;
|
| 330 |
+
if(bi>=0){tacTip.style.display='block';
|
| 331 |
tacTip.style.left=Math.min(mx+12,r.width-160)+'px'; tacTip.style.top=Math.max(0,my-30)+'px';
|
| 332 |
+
tacTip.textContent=tipText(_hit[bi]);}
|
| 333 |
else tacTip.style.display='none';});
|
| 334 |
+
cHand.addEventListener('mouseleave',()=>{tacTip.style.display='none';_hoverIdx=-1;});
|
| 335 |
|
| 336 |
function loop(){update();if(playing)requestAnimationFrame(loop);}
|
| 337 |
|
ep4/viewer.html
CHANGED
|
@@ -314,17 +314,24 @@ function drawTactile(i){
|
|
| 314 |
ctx.fillText(peak>0?String(peak):'\u2014',lx,cTop+2*fs+3);
|
| 315 |
ctx.textAlign='left';
|
| 316 |
});
|
|
|
|
|
|
|
| 317 |
}
|
| 318 |
|
|
|
|
|
|
|
|
|
|
| 319 |
cHand.addEventListener('mousemove',e=>{
|
| 320 |
const r=cHand.getBoundingClientRect(),mx=e.clientX-r.left,my=e.clientY-r.top;
|
| 321 |
-
let
|
| 322 |
-
for(
|
| 323 |
-
|
|
|
|
|
|
|
| 324 |
tacTip.style.left=Math.min(mx+12,r.width-160)+'px'; tacTip.style.top=Math.max(0,my-30)+'px';
|
| 325 |
-
tacTip.textContent=
|
| 326 |
else tacTip.style.display='none';});
|
| 327 |
-
cHand.addEventListener('mouseleave',()=>tacTip.style.display='none');
|
| 328 |
|
| 329 |
function loop(){update();if(playing)requestAnimationFrame(loop);}
|
| 330 |
|
|
|
|
| 314 |
ctx.fillText(peak>0?String(peak):'\u2014',lx,cTop+2*fs+3);
|
| 315 |
ctx.textAlign='left';
|
| 316 |
});
|
| 317 |
+
if(_hoverIdx>=0 && _hit[_hoverIdx] && tacTip.style.display!=='none')
|
| 318 |
+
tacTip.textContent=tipText(_hit[_hoverIdx]); // 播放时数值随帧刷新
|
| 319 |
}
|
| 320 |
|
| 321 |
+
// 记住悬浮的是"哪个格子"(索引), 每帧重绘后用最新值刷新文字, 鼠标不动也会跟着播放更新
|
| 322 |
+
let _hoverIdx=-1;
|
| 323 |
+
function tipText(h){return `${h.hand} \u00b7 ${h.part} \u00b7 pt ${h.pt} \u00b7 ${h.v}`;}
|
| 324 |
cHand.addEventListener('mousemove',e=>{
|
| 325 |
const r=cHand.getBoundingClientRect(),mx=e.clientX-r.left,my=e.clientY-r.top;
|
| 326 |
+
let bi=-1,bd=1e9;
|
| 327 |
+
for(let i=0;i<_hit.length;i++){const c=_hit[i],d=Math.hypot(mx-c.cx,my-c.cy);
|
| 328 |
+
if(d<c.r*1.15&&d<bd){bd=d;bi=i;}}
|
| 329 |
+
_hoverIdx=bi;
|
| 330 |
+
if(bi>=0){tacTip.style.display='block';
|
| 331 |
tacTip.style.left=Math.min(mx+12,r.width-160)+'px'; tacTip.style.top=Math.max(0,my-30)+'px';
|
| 332 |
+
tacTip.textContent=tipText(_hit[bi]);}
|
| 333 |
else tacTip.style.display='none';});
|
| 334 |
+
cHand.addEventListener('mouseleave',()=>{tacTip.style.display='none';_hoverIdx=-1;});
|
| 335 |
|
| 336 |
function loop(){update();if(playing)requestAnimationFrame(loop);}
|
| 337 |
|
ep5/viewer.html
CHANGED
|
@@ -314,17 +314,24 @@ function drawTactile(i){
|
|
| 314 |
ctx.fillText(peak>0?String(peak):'\u2014',lx,cTop+2*fs+3);
|
| 315 |
ctx.textAlign='left';
|
| 316 |
});
|
|
|
|
|
|
|
| 317 |
}
|
| 318 |
|
|
|
|
|
|
|
|
|
|
| 319 |
cHand.addEventListener('mousemove',e=>{
|
| 320 |
const r=cHand.getBoundingClientRect(),mx=e.clientX-r.left,my=e.clientY-r.top;
|
| 321 |
-
let
|
| 322 |
-
for(
|
| 323 |
-
|
|
|
|
|
|
|
| 324 |
tacTip.style.left=Math.min(mx+12,r.width-160)+'px'; tacTip.style.top=Math.max(0,my-30)+'px';
|
| 325 |
-
tacTip.textContent=
|
| 326 |
else tacTip.style.display='none';});
|
| 327 |
-
cHand.addEventListener('mouseleave',()=>tacTip.style.display='none');
|
| 328 |
|
| 329 |
function loop(){update();if(playing)requestAnimationFrame(loop);}
|
| 330 |
|
|
|
|
| 314 |
ctx.fillText(peak>0?String(peak):'\u2014',lx,cTop+2*fs+3);
|
| 315 |
ctx.textAlign='left';
|
| 316 |
});
|
| 317 |
+
if(_hoverIdx>=0 && _hit[_hoverIdx] && tacTip.style.display!=='none')
|
| 318 |
+
tacTip.textContent=tipText(_hit[_hoverIdx]); // 播放时数值随帧刷新
|
| 319 |
}
|
| 320 |
|
| 321 |
+
// 记住悬浮的是"哪个格子"(索引), 每帧重绘后用最新值刷新文字, 鼠标不动也会跟着播放更新
|
| 322 |
+
let _hoverIdx=-1;
|
| 323 |
+
function tipText(h){return `${h.hand} \u00b7 ${h.part} \u00b7 pt ${h.pt} \u00b7 ${h.v}`;}
|
| 324 |
cHand.addEventListener('mousemove',e=>{
|
| 325 |
const r=cHand.getBoundingClientRect(),mx=e.clientX-r.left,my=e.clientY-r.top;
|
| 326 |
+
let bi=-1,bd=1e9;
|
| 327 |
+
for(let i=0;i<_hit.length;i++){const c=_hit[i],d=Math.hypot(mx-c.cx,my-c.cy);
|
| 328 |
+
if(d<c.r*1.15&&d<bd){bd=d;bi=i;}}
|
| 329 |
+
_hoverIdx=bi;
|
| 330 |
+
if(bi>=0){tacTip.style.display='block';
|
| 331 |
tacTip.style.left=Math.min(mx+12,r.width-160)+'px'; tacTip.style.top=Math.max(0,my-30)+'px';
|
| 332 |
+
tacTip.textContent=tipText(_hit[bi]);}
|
| 333 |
else tacTip.style.display='none';});
|
| 334 |
+
cHand.addEventListener('mouseleave',()=>{tacTip.style.display='none';_hoverIdx=-1;});
|
| 335 |
|
| 336 |
function loop(){update();if(playing)requestAnimationFrame(loop);}
|
| 337 |
|