';document.write(s);let el=document.getElementById('canvas1');let ratio=3;el.width=w*ratio;el.height=h*ratio;el.style.width=w+"px";el.style.height=h+"px";g=el.getContext("2d");g.setTransform(ratio,0,0,ratio,0,0);msg('Click and Drag','black',w/2-140,w/2)
drawDartboard()
my.aimer=new Anim()
let div=document.getElementById('canvas1')
div.onmousedown=function(ev){let rtn=bdHit(ev.offsetX,ev.offsetY)
my.mouse.dnQ=true
my.mouse.sttx=ev.offsetX
my.mouse.stty=ev.offsetY
console.log('down',rtn,my.animClearQ)
if(!my.animClearQ)animsClear()
let mate=my.mates[my.mateN]
mate.dartN--
document.getElementById('mateDartN'+mate.id).innerHTML='*'.repeat(mate.dartN)
msg('',mate.clr,-500,0)};div.onmousemove=function(ev){if(!my.mouse.dnQ)return
let rtn=bdHit(ev.offsetX,ev.offsetY)
my.mouse.endx=ev.offsetX
my.mouse.endy=ev.offsetY
if(my.mouse.dnQ){let dx=my.mouse.endx-my.mouse.sttx
let dy=my.mouse.endy-my.mouse.stty
let ang=Math.atan2(dx,-dy)+Math.PI/2
let mate=my.mates[my.mateN]
my.aimer.drawAt(my.mouse.sttx,my.mouse.stty,ang)
my.aimer.drawLine(0,0,my.mouse.endx-my.mouse.sttx,my.mouse.endy-my.mouse.stty,mate.clr)}};div.onmouseup=function(ev){let rtn=bdHit(ev.offsetX,ev.offsetY)
console.log('up',rtn)
my.aimer.clear()
my.mouse.dnQ=false
my.mouse.endx=ev.offsetX
my.mouse.endy=ev.offsetY
fire()};gameNew()}
function gameNew(){my.mates.map(mate=>{mate.score=my.game.tgtScore
document.getElementById('mateScore'+mate.id).innerHTML=mate.score})
my.mateN=0
roundNew()}
function roundNew(){let mate=my.mates[my.mateN]
document.getElementById('mateDartN'+mate.id).innerHTML=''
my.mateN=1-my.mateN
mate=my.mates[my.mateN]
mate.dartN=3
document.getElementById('mateDartN'+mate.id).innerHTML='*'.repeat(mate.dartN)
mate.roundScoreStt=mate.score
let currId=mate.id
my.mates.map(mate=>{let div=document.getElementById('mateScore'+mate.id)
div.style.borderColor=mate.clr
if(mate.id==currId){div.style.backgroundColor='hsla(120,100%,90%,0.6)'}else{div.style.backgroundColor='hsla(120,100%,90%,0.0)'}})
my.animClearQ=false}
function animsClear(){my.anims.map(anim=>{anim.clear()})
my.anims=[]
my.animClearQ=true}
function fire(){console.log('fire',my.mouse)
doTraj()
let anim=new Anim(my.pts)
my.anims.push(anim)
anim.stt()}
function doTraj(){let dx=my.mouse.endx-my.mouse.sttx
let dy=my.mouse.endy-my.mouse.stty
console.log('doTraj dx,dy',dx,dy)
dx*=my.rads.bd/(my.bdSz/2)
dy*=my.rads.bd/(my.bdSz/2)
console.log('doTraj dx,dy',dx,dy)
let ang=Math.atan2(dx,-dy)
let px=my.mouse.sttx
let py=my.mouse.stty
let pz=0
let vx=dx
let vy=dy
let vz=Math.sqrt(dx*dx+dy*dy)*0.01
let ax=0
let ay=9
let az=0
let drag=0
console.log('doTraj',vx,vy)
let dt=0.1
let pts=[]
for(let i=0;i<=Math.ceil(10/dt);i++){pts.push({t:i*dt,x:fmt2(px),y:fmt2(py),z:fmt2(pz),ang:ang+Math.PI/2})
if(pz>2.37)break
vx+=ax*dt
vy+=ay*dt
vz+=az*dt
vx-=vx*vx*drag*dt
vy-=vy*vy*drag*dt
vz-=vz*vz*drag*dt
px+=vx*dt
py+=vy*dt
pz+=vz*dt
ang=Math.atan2(vx,-vy)}
my.pts=pts
console.log('doTraj',my.pts)}
function fmt2(x){return((x*100)<<0)/100}
class Anim{constructor(pts){this.pts=pts
this.rad=200
this.canvas=document.createElement("canvas");document.getElementById('drg').appendChild(this.canvas);this.canvas.setAttribute("id","ammo");this.canvas.setAttribute("style","position:absolute;");this.canvas.setAttribute("width",this.rad*2);this.canvas.setAttribute("height",this.rad*2);this.canvas.style.setProperty("top",0+"px");this.canvas.style.setProperty("left",0+"px");this.g=this.canvas.getContext('2d');}
stt(){this.frameN=0
this.frame()}
frame(){let pt=this.pts[this.frameN]
let finalQ=false
if(pt.y<0){finalQ=true}
this.canvas.style.setProperty("left",pt.x-this.rad+"px");this.canvas.style.setProperty("top",pt.y-this.rad+"px");this.g.clearRect(0,0,g.canvas.width,g.canvas.height)
this.g.dart(this.rad,this.rad,pt.ang)
this.frameN++
if(this.frameN>=this.pts.length)finalQ=true
if(finalQ){hit(pt)}else{requestAnimationFrame(this.frame.bind(this));}}
drawAt(x,y,ang){this.canvas.style.setProperty("left",x-this.rad+"px");this.canvas.style.setProperty("top",y-this.rad+"px");this.g.clearRect(0,0,g.canvas.width,g.canvas.height)
this.g.dart(this.rad,this.rad,ang)}
drawLine(x0,y0,x1,y1,clr){let g=this.g
g.strokeStyle=clr
g.lineWidth=3
g.beginPath()
g.moveTo(this.rad+x0,this.rad+y0)
g.lineTo(this.rad+x1,this.rad+y1)
g.stroke()}
clear(){this.g.clearRect(0,0,g.canvas.width,g.canvas.height)}}
function hit(pt){let result=bdHit(pt.x,pt.y)
console.log('Landed!',pt,result)
let mate=my.mates[my.mateN]
msg(result.score,mate.clr,pt.x,pt.y)
console.log('score',mate)
let currScore=mate.score-result.score
if(currScore==0&&(result.type=="double"||result.type=="triple"||result.type=="bullIn"||result.type=="bullOut")){document.getElementById('mateScore'+mate.id).innerHTML=currScore
win()
return}
if(currScore<0||currScore==1){mate.score=mate.roundScoreStt
document.getElementById('mateScore'+mate.id).innerHTML=mate.score
roundNew()
return}
mate.score=currScore
document.getElementById('mateScore'+mate.id).innerHTML=mate.score
if(mate.dartN==0){roundNew()}}
function win(){let mate=my.mates[my.mateN]
msg(mate.name+' Wins!',mate.clr,w/2-100,w/2)}
function bdHit(x,y){let dx=x-my.bdSz/2
let dy=y-my.bdSz/2
let rad=Math.sqrt(dx*dx+dy*dy)
rad=rad*my.rads.bd/(my.bdSz/2)
let ang=Math.atan2(dx,-dy)
if(ang<0)ang+=2*Math.PI
let sectN=(ang/(2*Math.PI)*my.vals.length+0.5)<<0
if(sectN>=my.vals.length)sectN=0
let rx=my.game.radExtra
console.log('bdHit',rx);if(radmy.rads.doubleOut+rx)return{type:'out',score:0}
let score=my.vals[sectN]
if(rad>my.rads.doubleIn-rx&&radmy.rads.tripleIn-rx&&rad '
s+=' .speaker { height: 30px; width: 30px; position: relative; overflow: hidden; display: inline-block; vertical-align:top; } '
s+=' .speaker span { display: block; width: 9px; height: 9px; background-color:'+onClr+'; margin: 10px 0 0 1px; }'
s+=' .speaker span:after { content: ""; position: absolute; width: 0; height: 0; border-style: solid; border-color: transparent '+onClr+' transparent transparent; border-width: 10px 16px 10px 15px; left: -13px; top: 5px; }'
s+=' .speaker span:before { transform: rotate(45deg); border-radius: 0 60px 0 0; content: ""; position: absolute; width: 5px; height: 5px; border-style: double; border-color:'+onClr+'; border-width: 7px 7px 0 0; left: 18px; top: 9px; transition: all 0.2s ease-out; }'
s+=' .speaker:hover span:before { transform: scale(.8) translate(-3px, 0) rotate(42deg); }'
s+=' .speaker.mute span:before { transform: scale(.5) translate(-15px, 0) rotate(36deg); opacity: 0; }'
s+=' .speaker.mute span { background-color:'+offClr+'; }'
s+=' .speaker.mute span:after {border-color: transparent '+offClr+' transparent '+offClr+';}'
s+=' '
s+='
'
return s}
function soundPlay(name,simulQ){if(!my.soundQ)return
simulQ=typeof simulQ!=='undefined'?simulQ:true
if(simulQ){if(name.length>0){let div=document.getElementById(name)
if(div.currentTime>0&&div.currentTime0)soundPlayQueue();};}
function soundToggle(){let btn='sound'
if(my.soundQ){my.soundQ=false
document.getElementById(btn).classList.add("mute")}else{my.soundQ=true
document.getElementById(btn).classList.remove("mute")}}
function radioHTML(prompt,id,lbls,checkN,func){let s='';s+='
';s+='
';s+=prompt;s+='
';s+='
';for(let i=0;i';s+='';}
s+='
';s+='
';return s;}
function radioNGet(name){var div=document.querySelector('input[name="'+name+'"]:checked')
var id=div.id
var n=(id.match(/\d+$/)||[]).pop();return n}
function optPopHTML(){let s='';s+='
';return s;}
function radioClick(n){}
function toggleBtn(btn,onq){if(onq){document.getElementById(btn).classList.add("hi");document.getElementById(btn).classList.remove("lo");}else{document.getElementById(btn).classList.add("lo");document.getElementById(btn).classList.remove("hi");}}
CanvasRenderingContext2D.prototype.roundRect=function(x,y,w,h,r){if(w<2*r)r=w/2;if(h<2*r)r=h/2;this.beginPath();this.moveTo(x+r,y);this.arcTo(x+w,y,x+w,y+h,r);this.arcTo(x+w,y+h,x,y+h,r);this.arcTo(x,y+h,x,y,r);this.arcTo(x,y,x+w,y,r);this.closePath();return this;}
CanvasRenderingContext2D.prototype.drawPoly=function(pts){let g=this;g.moveTo(pts[0].x,pts[0].y);for(let i=1;i{if(shape.mirrorQ){pts=mirror(shape.pts)
pts=toxy(pts)}else{pts=toxy(shape.pts)}
pts=trans(pts,x,y,ang,3,3)
g.strokeStyle='#000'
g.lineWidth=0.5
g.fillStyle=shape.clr
g.beginPath()
g.drawPoly(pts)
g.fill();g.stroke()})}
function mirror(pts){let len=pts.length
for(let i=len-1;i>=0;i--){let pt=pts[i];pts.push([pt[0],-pt[1]])}
return pts}
function toxy(pts){let ptsxy=pts.map(pt=>{return{x:pt[0],y:pt[1]}})
return ptsxy}
function trans(pts,xStt,yStt,ang,xFact,yFact){let a=Math.cos(ang)
let b=-Math.sin(ang)
let c=Math.sin(ang)
let d=Math.cos(ang)
let pts2=[]
for(let i=0;i{return{x:xStt+pt.x,y:yStt+pt.y}})
return pts3}
function polarToCartesian(centerX,centerY,radius,angle){let x=centerX+(radius*Math.cos(angle));let y=centerY+(radius*Math.sin(angle));return{x:x,y:y}}
function optPop(){console.log("optpop");var pop=document.getElementById('optpop');pop.style.transitionDuration="0.3s";pop.style.opacity=1;pop.style.zIndex=102;pop.style.left=(w-340)/2+'px';}
function optYes(){var pop=document.getElementById('optpop');pop.style.opacity=0;pop.style.zIndex=1;pop.style.left='-999px';my.gameN=radioNGet('game')
console.log('optYes',my.gameN)
optSet('gameN',my.gameN)
my.game=my.games[my.gameN]
gameNew()}
function optNo(){var pop=document.getElementById('optpop');pop.style.opacity=0;pop.style.zIndex=1;pop.style.left='-999px';}
function optGet(name){var val=localStorage.getItem(`yacht.${name}`)
if(val==null)val=my.opts[name]
return val}
function optSet(name,val){localStorage.setItem(`yacht.${name}`,val)
my.opts[name]=val}