Show code
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><title>Binary Search Visualizer</title>
<style>
html,body{margin:0;height:100%;background:radial-gradient(1200px 700px at 50% 0%,#141c34,#080b16 70%);
display:flex;align-items:center;justify-content:center;font-family:ui-monospace,Menlo,Consolas,monospace}
canvas{border-radius:14px;box-shadow:0 20px 60px rgba(0,0,0,.6);background:#0b1020}
</style></head><body><canvas id="c"></canvas><script>
const cv=document.getElementById('c'),g=cv.getContext('2d');
const W=980,H=480,DPR=Math.min(2,window.devicePixelRatio||1);
cv.width=W*DPR;cv.height=H*DPR;cv.style.width=W+'px';cv.style.height=H+'px';g.scale(DPR,DPR);
const N=40,PL=50,PR=50,TOP=104,BASE=374,SLOT=(W-PL-PR)/N,BW=SLOT*0.62;
let vals,target,steps,idx,alpha,mLo,mHi,mMid,found,t0=0,last=0,maxV;
function xOf(i){return PL+i*SLOT+SLOT/2}
function init(){
const s=new Set();while(s.size<N)s.add(4+Math.floor(Math.random()*392));
vals=[...s].sort((a,b)=>a-b);maxV=vals[N-1];
target=Math.random()<0.8?vals[Math.floor(Math.random()*N)]:1+Math.floor(Math.random()*400);
steps=[];found=-1;let lo=0,hi=N-1;
while(lo<=hi){const mid=(lo+hi)>>1,c=vals[mid]===target?0:(vals[mid]<target?-1:1);
steps.push({lo:lo,hi:hi,mid:mid,c:c});if(c===0){found=mid;break}
if(c<0)lo=mid+1;else hi=mid-1}
if(found<0)steps.push({lo:lo,hi:hi,mid:-1,c:null});
idx=0;t0=0;alpha=new Array(N).fill(1);
mLo=xOf(0);mHi=xOf(N-1);mMid=xOf(steps[0].mid);
}
function lerp(a,b,k){return a+(b-a)*k}
function marker(x,y,label,col,dir){
g.fillStyle=col;g.beginPath();g.moveTo(x,y);g.lineTo(x-6,y+11);g.lineTo(x+6,y+11);g.closePath();g.fill();
g.font='bold 12px ui-monospace,monospace';g.textAlign='center';g.fillText(label,x+dir*11,y+22);
}
function draw(ts){
const dt=Math.min(60,ts-last||16);last=ts;if(!t0)t0=ts;
const cur=steps[idx],end=idx===steps.length-1,D=end?1900:1000;
if(ts-t0>D){if(!end){idx++;t0=ts}else{init();t0=ts}}
const st=steps[idx],k=1-Math.exp(-dt/110);
mLo=lerp(mLo,xOf(Math.min(st.lo,N-1)),k);mHi=lerp(mHi,xOf(Math.max(st.hi,0)),k);
if(st.mid>=0)mMid=lerp(mMid,xOf(st.mid),k);
let cmps=0;for(let i=0;i<=idx;i++)if(steps[i].mid>=0)cmps++;
g.clearRect(0,0,W,H);
g.fillStyle='#0b1020';g.fillRect(0,0,W,H);
g.fillStyle='#f1f5f9';g.textAlign='left';g.font='bold 20px ui-monospace,monospace';
g.fillText('Binary Search',PL,44);
g.font='13px ui-monospace,monospace';g.fillStyle='#7f8ca8';
g.fillText('sorted array · n = '+N,PL+186,44);
g.textAlign='right';g.font='bold 17px ui-monospace,monospace';g.fillStyle='#fbbf24';
g.fillText('target = '+target,W-PR,32);
g.fillStyle='#7dd3fc';g.font='13px ui-monospace,monospace';
g.fillText('comparisons: '+cmps+' range: '+(st.hi>=st.lo?'['+st.lo+' … '+st.hi+']':'empty'),W-PR,54);
let msg,mc='#94a3b8';
if(st.mid<0){msg='target not present — search space empty';mc='#f87171'}
else if(st.c===0){msg='a[mid] = '+vals[st.mid]+' == target → FOUND at index '+st.mid;mc='#4ade80'}
else if(st.c<0){msg='a[mid] = '+vals[st.mid]+' < '+target+' → discard left half';mc='#fbbf24'}
else {msg='a[mid] = '+vals[st.mid]+' > '+target+' → discard right half';mc='#fbbf24'}
g.textAlign='left';g.fillStyle=mc;g.font='14px ui-monospace,monospace';g.fillText(msg,PL,78);
g.strokeStyle='#1e293b';g.lineWidth=1;g.beginPath();g.moveTo(PL-14,BASE+.5);g.lineTo(W-PR+14,BASE+.5);g.stroke();
const pulse=0.62+0.38*Math.sin(ts/150);
for(let i=0;i<N;i++){
const on=i>=st.lo&&i<=st.hi?1:0.16;alpha[i]=lerp(alpha[i],on,k);
const h=8+(vals[i]/maxV)*(BASE-TOP-8),x=xOf(i),y=BASE-h,a=alpha[i];
const isMid=i===st.mid,hit=isMid&&st.c===0;
let col=hit?'74,222,128':isMid?'251,191,36':'45,212,191';
g.fillStyle='rgba('+col+','+(a*(isMid?pulse:0.9))+')';
g.beginPath();g.roundRect(x-BW/2,y,BW,h,3);g.fill();
if(isMid){g.strokeStyle='rgba(255,255,255,'+(0.55*a)+')';g.lineWidth=1.4;g.stroke()}
g.save();g.translate(x,y-7);g.rotate(-Math.PI/2);g.textAlign='left';
g.font=(isMid?'bold ':'')+'10px ui-monospace,monospace';
g.fillStyle='rgba('+(isMid?'255,255,255':'203,213,225')+','+(a*0.95)+')';
g.fillText(vals[i],0,3.5);g.restore();
if(i%5===0){g.textAlign='center';g.font='9px ui-monospace,monospace';
g.fillStyle='rgba(100,116,139,'+(0.35+a*0.5)+')';g.fillText(i,x,BASE+13)}
}
if(st.hi>=st.lo){
g.strokeStyle='rgba(125,211,252,.45)';g.lineWidth=2;g.beginPath();
g.moveTo(mLo-SLOT/2+3,BASE+26);g.lineTo(mHi+SLOT/2-3,BASE+26);g.stroke();
g.fillStyle='rgba(125,211,252,.10)';g.fillRect(mLo-SLOT/2+3,TOP-14,(mHi-mLo)+SLOT-6,BASE-TOP+14);
marker(mLo,BASE+32,'low','#7dd3fc',-1);marker(mHi,BASE+32,'high','#7dd3fc',1);
}
if(st.mid>=0)marker(mMid,BASE+64,'mid',st.c===0?'#4ade80':'#fbbf24',0);
g.textAlign='center';g.fillStyle='#475569';g.font='11px ui-monospace,monospace';
g.fillText('O(log n) — worst case '+Math.ceil(Math.log2(N+1))+' comparisons',W/2,H-12);
requestAnimationFrame(draw);
}
init();requestAnimationFrame(draw);
</script></body></html>