fix: scale marks and progress both on full arc+line path, aligned

This commit is contained in:
2026-07-25 17:42:22 +08:00
parent 86d8120a10
commit 20fd2964b2
+38 -10
View File
@@ -90,35 +90,63 @@ function draw(cur,max){
ctx.clearRect(0,0,W,H); ctx.clearRect(0,0,W,H);
const sx=Ca/640*W,sy=Cb/480*H,sr=Cr/640*W; const sx=Ca/640*W,sy=Cb/480*H,sr=Cr/640*W;
const gw=Math.max(36,W/18); const gw=Math.max(36,W/18);
const ae=d2r(Ae),ex=sx+sr*Math.cos(ae),ey=sy+sr*Math.sin(ae); const ae=d2r(Ae),ex=sx+sr*Math.cos(ae),ey=sy+sr*Math.sin(ae),lx=W*.93;
const arcLen=Math.PI*2*sr*((Ae-As)/360),lineLen=lx-ex,totalLen=arcLen+lineLen;
const rl=max*.85; const rl=max*.85;
// point on total path (0→1 mapped to arc+line)
function pathPt(t){
const ad=t*totalLen;
if(ad<=arcLen){
const a=d2r(As+(Ae-As)*(ad/arcLen));
return{x:sx+sr*Math.cos(a),y:sy+sr*Math.sin(a)};
}
const lp=(ad-arcLen)/lineLen;
return{x:ex+lp*(lx-ex),y:ey};
}
// background: arc + line // background: arc + line
ctx.beginPath(); ctx.beginPath();
ctx.arc(sx,sy,sr,d2r(As),d2r(Ae),false); ctx.arc(sx,sy,sr,d2r(As),d2r(Ae),false);
ctx.lineTo(W*.93,ey); ctx.lineTo(lx,ey);
ctx.strokeStyle='rgba(255,255,255,.04)'; ctx.strokeStyle='rgba(255,255,255,.04)';
ctx.lineWidth=gw; ctx.lineWidth=gw;
ctx.stroke(); ctx.stroke();
// progress: ARC ONLY (0→max RPM fills the 90° arc) // progress along full path
const pc=Math.min(cur/max,1); const pc=Math.min(cur/max,1);
if(pc>.005){ if(pc>.005){
const ep=pathPt(pc);
ctx.beginPath(); ctx.beginPath();
ctx.arc(sx,sy,sr,d2r(As),d2r(As+(Ae-As)*pc),false); const ad=pc*totalLen;
if(ad<=arcLen){
ctx.arc(sx,sy,sr,d2r(As),d2r(As+(Ae-As)*(ad/arcLen)),false);
}else{
ctx.arc(sx,sy,sr,d2r(As),d2r(Ae),false);
ctx.lineTo(ep.x,ey);
}
ctx.strokeStyle=cur>=rl?'rgba(255,50,35,.95)':'rgba(255,255,255,.85)'; ctx.strokeStyle=cur>=rl?'rgba(255,50,35,.95)':'rgba(255,255,255,.85)';
ctx.lineWidth=gw; ctx.lineWidth=gw;
ctx.stroke(); ctx.stroke();
} }
// scale marks // scale marks along TOTAL path (arc + line)
const mr=sr-gw/2-6,pr=sr+gw/2+6; const mr=sr-gw/2-6,pr=sr+gw/2+6;
for(let r=0;r<=max;r+=2000){ for(let r=0;r<=max;r+=2000){
const a=d2r(As+(Ae-As)*(r/max)); const t=r/max,p=pathPt(t);
ctx.beginPath();ctx.moveTo(sx+mr*Math.cos(a),sy+mr*Math.sin(a));ctx.lineTo(sx+pr*Math.cos(a),sy+pr*Math.sin(a)); if(r*totalLen/max<=arcLen){
ctx.strokeStyle=r>=rl?'rgba(255,255,255,.15)':'rgba(255,255,255,.08)'; const a=d2r(As+(Ae-As)*t);
ctx.lineWidth=r%4000===0?2.5:1;ctx.stroke(); ctx.beginPath();ctx.moveTo(sx+mr*Math.cos(a),sy+mr*Math.sin(a));ctx.lineTo(sx+pr*Math.cos(a),sy+pr*Math.sin(a));
if(r%4000===0){ctx.fillStyle='rgba(255,255,255,.22)';ctx.font=`${Math.max(13,W/38)|0}px 'NEXT ART',sans-serif`;ctx.textAlign='center';ctx.fillText(Math.round(r/1000),sx+(pr+22)*Math.cos(a),sy+(pr+22)*Math.sin(a)+5)} ctx.strokeStyle=r>=rl?'rgba(255,255,255,.15)':'rgba(255,255,255,.08)';
ctx.lineWidth=r%4000===0?2.5:1;ctx.stroke();
if(r%4000===0){ctx.fillStyle='rgba(255,255,255,.22)';ctx.font=`${Math.max(13,W/38)|0}px 'NEXT ART',sans-serif`;ctx.textAlign='center';ctx.fillText(Math.round(r/1000),sx+(pr+22)*Math.cos(a),sy+(pr+22)*Math.sin(a)+5)}
}else{
// on line portion: vertical marks
ctx.beginPath();ctx.moveTo(p.x,ey-gw/2-4);ctx.lineTo(p.x,ey+gw/2+4);
ctx.strokeStyle=r>=rl?'rgba(255,255,255,.15)':'rgba(255,255,255,.08)';
ctx.lineWidth=r%4000===0?2.5:1;ctx.stroke();
if(r%4000===0){ctx.fillStyle='rgba(255,255,255,.22)';ctx.font=`${Math.max(13,W/38)|0}px 'NEXT ART',sans-serif`;ctx.textAlign='center';ctx.fillText(Math.round(r/1000),p.x,ey+gw/2+22)}
}
} }
// RPM number // RPM number