No-repeat random name picker

Wheel of Names Without Repeats

Wheel of Names Without Repeats selects every name once by automatically removing each result. It is useful for classroom turns, task rotations, raffles, reading orders, and any activity where duplicate winners are not allowed.

remove winnerno duplicate namesfair rotationrandom order

It works as a no-duplicate picker, unique-name selector, and no-repeat wheel for fair turn-taking.

Spin the no-repeat Wheel of Names

Each selected name is removed automatically so the same entry cannot be selected twice in the current round.

Wheel of Names

Elimination: OFF Accumulation: OFF Auto-Spin: OFF Fair Rotation: OFF
Add entries and spin the wheel.
(()=>{ const r=document.currentScript.closest(‘.wnx-spinner’); if(!r||r.dataset.ready)return; r.dataset.ready=’1′; const $=s=>r.querySelector(s),$$=s=>[…r.querySelectorAll(s)]; const params=new URLSearchParams(location.search),cfg=document.querySelector(‘.wnx-config’); const mode=cfg?.dataset.mode||r.dataset.mode||’standard’; const title=cfg?.dataset.title||r.dataset.title||document.querySelector(‘.wn-page h1′)?.textContent||’Wheel of Names’; const raw=params.get(‘wnitems’)||cfg?.dataset.items||r.dataset.items||’Alice~Bob~Charlie~David~Eve~Frank’; const palettes=[ ((cfg?.dataset.palette)||r.dataset.palette||”).split(‘,’).filter(Boolean), [‘#6366f1′,’#8b5cf6′,’#ec4899′,’#f97316′,’#14b8a6′,’#3b82f6’], [‘#ef476f’,’#f78c6b’,’#ffd166′,’#06d6a0′,’#118ab2′,’#7353ba’], [‘#22c55e’,’#06b6d4′,’#3b82f6′,’#8b5cf6′,’#ec4899′,’#f59e0b’] ].filter(x=>x.length>2); let colors=palettes[0]; let entries=raw.split(‘~’).map(v=>{try{return decodeURIComponent(v)}catch(e){return v}}).filter(Boolean).map(v=>{ const p=v.split(‘|’); const weight=mode===’weighted’?Math.max(1,Number(p.pop())||1):1; return{name:p.join(‘|’),weight,count:0,last:-999,image:”}; }); let angle=0,busy=false,history=[],undo=[],redo=[],spinNumber=0,lastReceipt=null,preSpin=[]; let backgroundImage=”,centerImage=”,backgroundOpacity=.45,centerRadius=76,pendingEntryImage=”,pendingEntryFilename=”; const imageCache=new Map(); const canvas=$(‘.wnx-canvas’),ctx=canvas.getContext(‘2d’),spin=$(‘.wnx-spin’),result=$(‘.wnx-result’),list=$(‘.wnx-list’); const elimination=$(‘.wnx-elimination’),accumulation=$(‘.wnx-accumulation’),auto=$(‘.wnx-auto’),winnerCount=$(‘.wnx-winner-count’),duration=$(‘.wnx-duration’); const balance=$(‘.wnx-smart-balance’),cooldown=$(‘.wnx-smart-cooldown’); $(‘.wnx-title’).textContent=title; elimination.checked=mode===’norepeat’||params.get(‘wnremove’)===’1′; winnerCount.value=mode===’multi’?Math.max(1,Number(cfg?.dataset.count||r.dataset.count)||3):1; $(‘.wnx-multi-field’).classList.toggle(‘wnx-hidden’,mode!==’multi’); const escapeHtml=s=>String(s).replace(/[&”‘]/g,m=>({‘&’:’&’,”:’>’,'”‘:’"’,”‘”:’'’}[m])); const snapshot=()=>JSON.stringify(entries); const save=()=>{undo.push(snapshot());if(undo.length>25)undo.shift();redo=[];}; const randomInt=n=>{if(n=limit);return a[0]%n;}; function getImage(src){ if(!src)return null; if(imageCache.has(src))return imageCache.get(src); const img=new Image(); img.onload=draw; img.src=src; imageCache.set(src,img); return img; } function drawCover(img,x,y,w,h){ if(!img||!img.complete||!img.naturalWidth)return; const scale=Math.max(w/img.naturalWidth,h/img.naturalHeight); const dw=img.naturalWidth*scale,dh=img.naturalHeight*scale; ctx.drawImage(img,x+(w-dw)/2,y+(h-dh)/2,dw,dh); } function readOptimizedImage(file,maxSize=1000){ return new Promise((resolve,reject)=>{ if(!file||!file.type.startsWith(‘image/’)){reject(new Error(‘Please choose an image file.’));return;} const reader=new FileReader(); reader.onerror=()=>reject(new Error(‘The image could not be read.’)); reader.onload=()=>{ const img=new Image(); img.onerror=()=>reject(new Error(‘The image format is not supported.’)); img.onload=()=>{ const scale=Math.min(1,maxSize/Math.max(img.naturalWidth,img.naturalHeight)); const w=Math.max(1,Math.round(img.naturalWidth*scale)),h=Math.max(1,Math.round(img.naturalHeight*scale)); const temp=document.createElement(‘canvas’);temp.width=w;temp.height=h; const t=temp.getContext(‘2d’);t.drawImage(img,0,0,w,h); const type=file.type===’image/png’?’image/png’:’image/jpeg’; resolve(temp.toDataURL(type,type===’image/jpeg’?.86:undefined)); }; img.src=String(reader.result||”); }; reader.readAsDataURL(file); }); } const smartOn=()=>!elimination.checked&&(balance.checked||Number(cooldown.value)>0); function eligibleEntries(){ let pool=[…entries]; if(!smartOn())return pool; const cd=Number(cooldown.value); if(cd>0){const cooled=pool.filter(e=>spinNumber-e.last>=cd);if(cooled.length)pool=cooled;} if(balance.checked&&pool.length){const min=Math.min(…pool.map(e=>e.count));pool=pool.filter(e=>e.count===min);} return pool.length?pool:[…entries]; } function segments(){ const total=entries.reduce((s,e)=>s+e.weight,0)||1; let used=0; return entries.map(entry=>{const start=used/total*Math.PI*2;used+=entry.weight;return{entry,start,end:used/total*Math.PI*2};}); } function draw(){ const size=900,center=450,radius=418,segs=segments(),allowed=new Set(eligibleEntries()); ctx.clearRect(0,0,size,size); if(backgroundImage){ const img=getImage(backgroundImage); ctx.save();ctx.beginPath();ctx.arc(center,center,radius,0,Math.PI*2);ctx.clip();ctx.globalAlpha=backgroundOpacity;drawCover(img,center-radius,center-radius,radius*2,radius*2);ctx.restore(); } if(!segs.length){ ctx.beginPath();ctx.arc(center,center,radius,0,Math.PI*2);ctx.fillStyle=’#0b1628′;ctx.fill();ctx.strokeStyle=’rgba(129,140,248,.24)’;ctx.lineWidth=6;ctx.stroke();ctx.fillStyle=’#94a3b8′;ctx.font=’800 34px system-ui’;ctx.textAlign=’center’;ctx.fillText(‘Add entries’,center,center);return; } segs.forEach((seg,index)=>{ const dim=smartOn()&&!allowed.has(seg.entry); const start=seg.start+angle,end=seg.end+angle; ctx.save(); ctx.globalAlpha=dim?.2:1; ctx.beginPath();ctx.moveTo(center,center);ctx.arc(center,center,radius,start,end);ctx.closePath(); if(seg.entry.image){ ctx.save();ctx.clip();drawCover(getImage(seg.entry.image),center-radius,center-radius,radius*2,radius*2);ctx.restore(); ctx.globalAlpha=dim?.12:.22;ctx.fillStyle=colors[index%colors.length];ctx.fill();ctx.globalAlpha=dim?.2:1; }else{ ctx.fillStyle=colors[index%colors.length]; if(backgroundImage)ctx.globalAlpha=dim?.14:.72; ctx.fill();ctx.globalAlpha=dim?.2:1; } ctx.strokeStyle=’rgba(255,255,255,.82)’;ctx.lineWidth=5;ctx.stroke(); const mid=(seg.start+seg.end)/2+angle; ctx.translate(center,center);ctx.rotate(mid);ctx.textAlign=’right’;ctx.fillStyle=’#fff’;ctx.shadowColor=’rgba(0,0,0,.55)’;ctx.shadowBlur=8; ctx.font=`850 ${Math.max(18,Math.min(33,350/entries.length+16))}px system-ui`; const label=seg.entry.name.length>22?seg.entry.name.slice(0,20)+’…’:seg.entry.name; ctx.fillText(label,radius-34,10);ctx.restore(); }); ctx.save();ctx.beginPath();ctx.arc(center,center,centerRadius,0,Math.PI*2);ctx.clip(); if(centerImage){drawCover(getImage(centerImage),center-centerRadius,center-centerRadius,centerRadius*2,centerRadius*2);}else{ctx.fillStyle=’#0b1628′;ctx.fillRect(center-centerRadius,center-centerRadius,centerRadius*2,centerRadius*2);} ctx.restore();ctx.beginPath();ctx.arc(center,center,centerRadius,0,Math.PI*2);ctx.strokeStyle=’rgba(255,255,255,.24)’;ctx.lineWidth=10;ctx.stroke(); } function updateBadges(){ [[ $(‘.wnx-badge-elimination’),elimination,’Elimination’],[$(‘.wnx-badge-accumulation’),accumulation,’Accumulation’],[$(‘.wnx-badge-auto’),auto,’Auto-Spin’],[$(‘.wnx-badge-smart’),{checked:smartOn()},’Fair Rotation’]].forEach(([el,input,label])=>{el.textContent=`${label}: ${input.checked?’ON’:’OFF’}`;el.classList.toggle(‘is-on’,input.checked);}); } function balanceScore(){ if(!entries.length)return 100; const total=entries.reduce((s,e)=>s+e.count,0),mean=total/entries.length; if(!mean)return 100; const deviation=entries.reduce((s,e)=>s+Math.abs(e.count-mean),0)/entries.length; return Math.max(0,Math.round(100-deviation/mean*100)); } function updateDashboard(){ $(‘.wnx-balance-score’).textContent=balanceScore()+’%’;$(‘.wnx-smart-spins’).textContent=String(spinNumber); $(‘.wnx-smart-counts’).innerHTML=[…entries].sort((a,b)=>a.count-b.count||a.name.localeCompare(b.name)).map(e=>`
${escapeHtml(e.name)}${e.count}
`).join(”)||’

No entries yet.

‘; const status=$(‘.wnx-smart-status’); if(elimination.checked&&(balance.checked||Number(cooldown.value)>0))status.textContent=’Smart Fair Rotation is paused while Elimination mode is active.’; else if(!smartOn())status.textContent=’Pure random mode is active.’; else{const parts=[];if(balance.checked)parts.push(‘least-selected priority’);if(Number(cooldown.value)>0)parts.push(`${cooldown.value}-spin cooldown`);status.textContent=`Smart mode active: ${parts.join(‘ + ‘)}. Dimmed slices are temporarily ineligible.`;} } function render(){ list.innerHTML=entries.map((entry,index)=>`
  • ⋮⋮
    ${entry.image?``:”}
    ${entry.weight}
  • `).join(”); $(‘.wnx-undo’).disabled=!undo.length;$(‘.wnx-redo’).disabled=!redo.length;draw();updateBadges();updateDashboard(); } function choose(pool){ const total=pool.reduce((s,e)=>s+e.weight,0);let n=randomInt(total),used=0; for(let i=0;i<pool.length;i++){used+=pool[i].weight;if(nv.toString(16).padStart(2,’0′)).join(”); const bytes=new TextEncoder().encode(text),hash=await crypto.subtle.digest(‘SHA-256′,bytes); return[…new Uint8Array(hash)].map(v=>v.toString(16).padStart(2,’0’)).join(”); } async function createReceipt(selected){ const payload={version:2,site:location.origin,page:location.pathname,timestamp:new Date().toISOString(),spinNumber,result:selected.map(e=>e.name),entries:preSpin,entryImages:selected.map(e=>({name:e.name,hasImage:Boolean(e.image)})),backgroundImage:Boolean(backgroundImage),centerImage:Boolean(centerImage),smartFairRotation:balance.checked,cooldownSpins:Number(cooldown.value),elimination:elimination.checked,accumulation:accumulation.checked,autoSpin:auto.checked}; const hash=await sha256(JSON.stringify(payload));lastReceipt={…payload,sha256:hash,receiptId:’WNR-‘+hash.slice(0,16).toUpperCase()}; $(‘.wnx-receipt-id’).textContent=lastReceipt.receiptId;$(‘.wnx-copy-receipt’).disabled=false;$(‘.wnx-download-receipt’).disabled=false; } function finish(selected){ spinNumber++;selected.forEach(e=>{e.count++;e.last=spinNumber;}); const time=new Date().toLocaleTimeString();history.unshift(`${time} — ${selected.map(e=>e.name).join(‘, ‘)}`); $(‘.wnx-history’).innerHTML=history.map(v=>`
  • ${escapeHtml(v)}
  • `).join(”);$(‘.wnx-empty’).classList.toggle(‘wnx-hidden’,history.length>0); result.textContent=(selected.length>1?’Winners: ‘:’Winner: ‘)+selected.map(e=>e.name+(accumulation.checked?` (${e.count})`:”)).join(‘, ‘); createReceipt(selected); if(elimination.checked){save();const set=new Set(selected);entries=entries.filter(e=>!set.has(e));render();}else{draw();updateDashboard();updateBadges();} busy=false;spin.disabled=false;if(auto.checked&&entries.length)setTimeout(startSpin,1200); } function startSpin(){ if(busy||!entries.length){if(!entries.length)result.textContent=’Add at least one entry.’;return;} busy=true;spin.disabled=true;preSpin=entries.map(e=>({name:e.name,weight:e.weight,hasImage:Boolean(e.image)})); let base=eligibleEntries();if(mode===’multi’&&base.length<Math.max(1,Number(winnerCount.value)||1))base=[…entries]; const pool=[…base],selected=[],wanted=Math.min(pool.length,Math.max(1,Number(winnerCount.value)||1)); for(let i=0;i<wanted;i++){const index=choose(pool);selected.push(pool[index]);pool.splice(index,1);} const segs=segments(),targetIndex=entries.indexOf(selected[0]),middle=(segs[targetIndex].start+segs[targetIndex].end)/2,target=-Math.PI/2-middle,start=angle,delta=((target-start)%(Math.PI*2)+Math.PI*2)%(Math.PI*2)+(5+randomInt(4))*Math.PI*2,ms=Number(duration.value)*1000,startTime=performance.now(); function frame(now){const progress=Math.min(1,(now-startTime)/ms),ease=1-Math.pow(1-progress,3);angle=start+delta*ease;draw();if(progress{if(e.key===’Enter’||e.key===’ ‘){e.preventDefault();startSpin();}}; $(‘.wnx-add-button’).onclick=()=>{const input=$(‘.wnx-new-entry’),value=input.value.trim();if(!value)return;save();entries.push({name:value,weight:1,count:0,last:-999,image:”});input.value=”;render();}; $(‘.wnx-new-entry’).onkeydown=e=>{if(e.key===’Enter’)$(‘.wnx-add-button’).click();}; $(‘.wnx-apply’).onclick=()=>{const values=$(‘.wnx-bulk’).value.split(/n|,/).map(v=>v.trim()).filter(Boolean);if(!values.length)return;save();entries=values.map(name=>({name,weight:1,count:0,last:-999,image:”}));spinNumber=0;render();}; $(‘.wnx-file’).onchange=e=>{const file=e.target.files?.[0];if(!file)return;const reader=new FileReader();reader.onload=()=>{$(‘.wnx-bulk’).value=String(reader.result||”).replace(/,/g,’n’);};reader.readAsText(file);}; $(‘.wnx-shuffle’).onclick=()=>{save();for(let i=entries.length-1;i>0;i–){const j=randomInt(i+1);[entries[i],entries[j]]=[entries[j],entries[i]];}render();}; $(‘.wnx-clear’).onclick=()=>{save();entries=[];spinNumber=0;render();}; $(‘.wnx-undo’).onclick=()=>{if(!undo.length)return;redo.push(snapshot());entries=JSON.parse(undo.pop());render();}; $(‘.wnx-redo’).onclick=()=>{if(!redo.length)return;undo.push(snapshot());entries=JSON.parse(redo.pop());render();}; list.onclick=e=>{const button=e.target.closest(‘[data-act]’);if(!button)return;save();const index=Number(button.dataset.i),action=button.dataset.act;if(action===’remove’)entries.splice(index,1);if(action===’plus’)entries[index].weight++;if(action===’minus’)entries[index].weight=Math.max(1,entries[index].weight-1);render();}; list.onchange=e=>{if(!e.target.matches(‘[data-edit]’))return;save();entries[Number(e.target.dataset.edit)].name=e.target.value.trim()||’Untitled’;render();}; $(‘.wnx-bg-file’).onchange=async e=>{const file=e.target.files?.[0];if(!file)return;try{backgroundImage=await readOptimizedImage(file,1200);$(‘.wnx-bg-status’).textContent=file.name;$(‘.wnx-remove-bg’).disabled=false;draw();}catch(err){$(‘.wnx-bg-status’).textContent=err.message;}}; $(‘.wnx-bg-opacity’).oninput=e=>{backgroundOpacity=Number(e.target.value)/100;draw();}; $(‘.wnx-remove-bg’).onclick=()=>{backgroundImage=”;$(‘.wnx-bg-file’).value=”;$(‘.wnx-bg-status’).textContent=’No image selected’;$(‘.wnx-remove-bg’).disabled=true;draw();}; $(‘.wnx-center-file’).onchange=async e=>{const file=e.target.files?.[0];if(!file)return;try{centerImage=await readOptimizedImage(file,600);$(‘.wnx-center-status’).textContent=file.name;$(‘.wnx-remove-center’).disabled=false;draw();}catch(err){$(‘.wnx-center-status’).textContent=err.message;}}; $(‘.wnx-center-size’).oninput=e=>{centerRadius=Number(e.target.value);draw();}; $(‘.wnx-remove-center’).onclick=()=>{centerImage=”;$(‘.wnx-center-file’).value=”;$(‘.wnx-center-status’).textContent=’No image selected’;$(‘.wnx-remove-center’).disabled=true;draw();}; $(‘.wnx-entry-image-file’).onchange=async e=>{const file=e.target.files?.[0];if(!file)return;try{pendingEntryImage=await readOptimizedImage(file,650);pendingEntryFilename=file.name.replace(/.[^.]+$/,”);const preview=$(‘.wnx-entry-image-preview’);preview.querySelector(‘img’).src=pendingEntryImage;preview.querySelector(‘span’).textContent=file.name;preview.hidden=false;$(‘.wnx-add-image-entry’).disabled=false;}catch(err){result.textContent=err.message;}}; $(‘.wnx-add-image-entry’).onclick=()=>{if(!pendingEntryImage)return;const label=$(‘.wnx-image-entry-name’).value.trim()||pendingEntryFilename||’Image entry’;save();entries.push({name:label,weight:1,count:0,last:-999,image:pendingEntryImage});pendingEntryImage=”;pendingEntryFilename=”;$(‘.wnx-image-entry-name’).value=”;$(‘.wnx-entry-image-file’).value=”;$(‘.wnx-entry-image-preview’).hidden=true;$(‘.wnx-add-image-entry’).disabled=true;render();}; $(‘.wnx-reset-images’).onclick=()=>{backgroundImage=”;centerImage=”;pendingEntryImage=”;entries.forEach(e=>e.image=”);$(‘.wnx-bg-file’).value=”;$(‘.wnx-center-file’).value=”;$(‘.wnx-entry-image-file’).value=”;$(‘.wnx-bg-status’).textContent=’No image selected’;$(‘.wnx-center-status’).textContent=’No image selected’;$(‘.wnx-remove-bg’).disabled=true;$(‘.wnx-remove-center’).disabled=true;$(‘.wnx-add-image-entry’).disabled=true;$(‘.wnx-entry-image-preview’).hidden=true;render();}; duration.oninput=()=>{$(‘.wnx-duration-text’).textContent=duration.value;}; [elimination,accumulation,auto,balance,cooldown].forEach(control=>control.onchange=()=>{updateBadges();updateDashboard();draw();}); $(‘.wnx-smart-reset’).onclick=()=>{entries.forEach(e=>{e.count=0;e.last=-999;});spinNumber=0;lastReceipt=null;$(‘.wnx-receipt-id’).textContent=’No receipt yet’;$(‘.wnx-copy-receipt’).disabled=true;$(‘.wnx-download-receipt’).disabled=true;render();}; $(‘.wnx-hide-panel’).onclick=()=>{const panel=$(‘.wnx-panel’);panel.classList.toggle(‘wnx-hidden’);$(‘.wnx-hide-panel’).textContent=panel.classList.contains(‘wnx-hidden’)?’Show Panel’:’Hide Panel’;}; $(‘.wnx-fullscreen’).onclick=()=>r.requestFullscreen?.(); $(‘.wnx-export’).onclick=()=>{const csv=’entry,weight,count,has_imagen’+entries.map(e=>`”${e.name.replace(/”/g,'””‘)}”,${e.weight},${e.count},${e.image?’yes’:’no’}`).join(‘n’),a=document.createElement(‘a’);a.href=URL.createObjectURL(new Blob([csv],{type:’text/csv’}));a.download=’wheel-entries.csv’;a.click();setTimeout(()=>URL.revokeObjectURL(a.href),1000);}; $(‘.wnx-share’).onclick=async()=>{const url=new URL(location.href);url.searchParams.set(‘wnitems’,entries.map(e=>encodeURIComponent(e.name)+(e.weight>1?’|’+e.weight:”)).join(‘~’));elimination.checked?url.searchParams.set(‘wnremove’,’1′):url.searchParams.delete(‘wnremove’);try{await navigator.clipboard.writeText(url);result.textContent=entries.some(e=>e.image)||backgroundImage||centerImage?’Share link copied. Images stay in this browser session.’:’Share link copied.’;}catch(e){result.textContent=url;}}; $(‘.wnx-copy-receipt’).onclick=async()=>{if(!lastReceipt)return;const text=`${lastReceipt.receiptId}nWinner: ${lastReceipt.result.join(‘, ‘)}nTime: ${lastReceipt.timestamp}nSHA-256: ${lastReceipt.sha256}`;try{await navigator.clipboard.writeText(text);$(‘.wnx-copy-receipt’).textContent=’Copied’;setTimeout(()=>$(‘.wnx-copy-receipt’).textContent=’Copy Receipt’,1200);}catch(e){$(‘.wnx-receipt-id’).textContent=text;}}; $(‘.wnx-download-receipt’).onclick=()=>{if(!lastReceipt)return;const report={receipt:lastReceipt,balanceScore:balanceScore()+’%’,selectionCounts:Object.fromEntries(entries.map(e=>[e.name,e.count]))},a=document.createElement(‘a’);a.href=URL.createObjectURL(new Blob([JSON.stringify(report,null,2)],{type:’application/json’}));a.download=lastReceipt.receiptId+’.json’;a.click();setTimeout(()=>URL.revokeObjectURL(a.href),1000);}; $$(‘.wnx-tab’).forEach(button=>button.onclick=()=>{$$(‘.wnx-tab’).forEach(x=>x.classList.remove(‘is-active’));$$(‘.wnx-pane’).forEach(x=>x.classList.remove(‘is-active’));button.classList.add(‘is-active’);$(`.wnx-pane[data-pane=”${button.dataset.tab}”]`).classList.add(‘is-active’);if(button.dataset.tab===’smart’)updateDashboard();}); palettes.forEach((palette,index)=>{const button=document.createElement(‘button’);button.type=’button’;button.className=’wnx-palette’+(index?”:’ is-active’);button.style.background=`linear-gradient(135deg,${palette.join(‘,’)})`;button.onclick=()=>{colors=palette;$$(‘.wnx-palette’).forEach(x=>x.classList.remove(‘is-active’));button.classList.add(‘is-active’);draw();};$(‘.wnx-palettes’).append(button);}); render(); })();

    What is Wheel of Names Without Repeats?

    no-duplicate picker is a free browser-based elimination-mode name spinner that removes each selected entry until the list is reset. Edit the sample entries, confirm the eligible list, choose the mode that matches the activity, and spin for a visible random result. Use it for unique turn order, prize rounds, classroom sequences, or task rotation after confirming the list and explaining when a redraw is allowed.

    How a unique-name selector works

    Paste one eligible name per line and press Spin. When the wheel stops, the selected line is removed from the active list. The next spin uses only the remaining names. Continue until everyone has been selected, or add the original list again to start a new round.

    This mode is different from ordinary random selection. In a standard wheel, the same person can appear again because every spin starts with the full list. A no-repeat wheel creates a random sequence across the whole group, making it better for balanced participation and one-time prize draws.

    each name
    Autowinner removal
    Liveremaining list
    Resetstart again

    When to use a no-repeat name wheel

    🎓

    Balanced classroom turns

    Choose students for answers, reading, demonstrations, or classroom jobs without selecting the same student twice before others receive a turn.

    🎁

    Unique winners

    Draw several raffle or giveaway winners while preventing one eligible entry from winning more than once in the same round.

    🔄

    Rotation order

    Create a random speaking, presentation, meeting-host, or task order and work through the list from first selection to last.

    No-repeat wheel setup checklist

    Clean the list

    Remove absent, ineligible, or duplicate entries. If two people share a name, add an initial or identifier so each line is clear.

    Agree on the reset rule

    Decide whether the wheel resets after everyone is chosen, after a session ends, or only when a new group starts.

    Record important outcomes

    For prizes or formal assignments, keep the original list and record results in the order selected.

    Technical reference: MDN random-value documentation.

    no-duplicate picker FAQs

    Can a removed name be added back?

    Yes. Type the name into the list again or paste the original list to restore all entries.

    What happens when only one name remains?

    The final remaining name can still be selected. After that, the list is empty until you add entries.

    Does this create a random order?

    Yes. Repeated spins produce a random sequence because each selected name is removed before the next spin.

    Are my names uploaded?

    No. The wheel logic runs in your browser and does not submit the names through the spinner code.