Lucas Kent e39465ad2f Changes to be committed:
new file:   Files/flashplayer_32_sa.exe
	new file:   favicon.ico
	new file:   globe.gif
	new file:   imgs/download.png
	new file:   imgs/zuck.jpg
	new file:   index.html
	new file:   other.ico
	new file:   script.js
	new file:   site.webmanifest
	new file:   sitemap.html
	new file:   styles/backround.css
	new file:   styles/border.css
	new file:   styles/fonts/Titillium_Web/OFL.txt
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-Black.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-Bold.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-BoldItalic.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-ExtraLight.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-ExtraLightItalic.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-Italic.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-Light.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-LightItalic.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-Regular.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-SemiBold.ttf
	new file:   styles/fonts/Titillium_Web/TitilliumWeb-SemiBoldItalic.ttf
	new file:   styles/fonts/webfontkit-20221027-163353/generator_config.txt
	new file:   styles/fonts/webfontkit-20221027-163353/specimen_files/grid_12-825-55-15.css
	new file:   styles/fonts/webfontkit-20221027-163353/specimen_files/specimen_stylesheet.css
	new file:   styles/fonts/webfontkit-20221027-163353/stylesheet.css
	new file:   styles/fonts/webfontkit-20221027-163353/titilliumweb-extralight-demo.html
	new file:   styles/fonts/webfontkit-20221027-163353/titilliumweb-extralight-webfont.woff
	new file:   styles/fonts/webfontkit-20221027-163353/titilliumweb-extralight-webfont.woff2
	new file:   styles/fonts/webfontkit-20221027-165950/generator_config.txt
	new file:   styles/fonts/webfontkit-20221027-165950/specimen_files/grid_12-825-55-15.css
	new file:   styles/fonts/webfontkit-20221027-165950/specimen_files/specimen_stylesheet.css
	new file:   styles/fonts/webfontkit-20221027-165950/stylesheet.css
	new file:   styles/fonts/webfontkit-20221027-165950/titilliumweb-bold-demo.html
	new file:   styles/fonts/webfontkit-20221027-165950/titilliumweb-bold-webfont.woff
	new file:   styles/fonts/webfontkit-20221027-165950/titilliumweb-bold-webfont.woff2
	new file:   styles/style.css
	new file:   tools/2048/.gitignore
	new file:   tools/2048/.jshintrc
	new file:   tools/2048/CONTRIBUTING.md
	new file:   tools/2048/LICENSE.txt
	new file:   tools/2048/README.md
	new file:   tools/2048/Rakefile
	new file:   tools/2048/favicon.ico
	new file:   tools/2048/index.html
	new file:   tools/2048/js/animframe_polyfill.js
	new file:   tools/2048/js/application.js
	new file:   tools/2048/js/bind_polyfill.js
	new file:   tools/2048/js/classlist_polyfill.js
	new file:   tools/2048/js/game_manager.js
	new file:   tools/2048/js/grid.js
	new file:   tools/2048/js/html_actuator.js
	new file:   tools/2048/js/keyboard_input_manager.js
	new file:   tools/2048/js/local_storage_manager.js
	new file:   tools/2048/js/tile.js
    new file:   tools/2048/meta/apple-touch-icon.png
	new file:   tools/webretro/cores/neocd_libretro.js
	new file:   tools/webretro/cores/neocd_libretro.wasm
	new file:   tools/webretro/cores/nestopia_libretro.js
	new file:   tools/webretro/cores/nestopia_libretro.wasm
	new file:   tools/webretro/cores/o2em_libretro.js
	new file:   tools/webretro/cores/o2em_libretro.wasm
	new file:   tools/webretro/cores/opera_libretro.js
	new file:   tools/webretro/cores/opera_libretro.wasm
2022-11-02 08:40:01 -04:00

233 lines
9.0 KiB
JavaScript

let my={}
function init(){let version='0.82'
let w=520
let h=240
let s=''
s+='<canvas id="canvasId" width="'+w+'" height="'+h+'" style="z-index:100;"></canvas>'
s+='<div style="font: 16px arial; font-weight: bold; position:absolute; bottom:3px; right:10px; text-align:center;">Drag the numerals to the blue boxes</div>'
s+=wrap({cls:'copyrt',pos:'abs',style:'left:5px; bottom:3px'},`&copy; 2022 Rod Pierce v${version}`)
s=wrap({cls:'js',style:'width:'+w+'px; height:'+my.ht+'px;'},s)
docInsert(s)
my.can=new Can('canvasId',w,h,2)
my.drag={n:0,onq:false,holdX:0,holdY:0}
my.shapes=[]
my.startX=10
my.cellWidth=40
my.spacing=10
my.drag.onQ=false
this.numbers=[0,1,2,3,4,5,6,7,8,9]
my.dests=[[70,100,60,40,0],[210,100,60,40,0],]
my.eqs=['1','+','2','=','3']
this.ball={size:10,color:'white',lightColor:'yellow',darkColor:'blue',position:{x:160,y:120}}
newGame()
let el=my.can.el
el.addEventListener('mousedown',mouseDownListener,false)
el.addEventListener('touchstart',ontouchstart,false)
el.addEventListener('mousemove',dopointer,false)}
function newGame(){makeShapes()
drawShapes()}
function ontouchstart(ev){let touch=ev.targetTouches[0]
ev.clientX=touch.clientX
ev.clientY=touch.clientY
ev.touchQ=true
mouseDownListener(ev)}
function ontouchmove(ev){let touch=ev.targetTouches[0]
ev.clientX=touch.clientX
ev.clientY=touch.clientY
ev.touchQ=true
mouseMoveListener(ev)
ev.preventDefault()}
function ontouchend(ev){my.can.el.addEventListener('touchstart',ontouchstart,false)
window.removeEventListener('touchend',ontouchend,false)
let[mouseX,mouseY]=my.can.mousePos(ev)
drop(mouseX,mouseY)
if(my.drag.onQ){my.drag.onQ=false
window.removeEventListener('touchmove',ontouchmove,false)}}
function dopointer(ev){let[mouseX,mouseY]=my.can.mousePos(ev)
let inQ=false
for(let i=0;i<my.shapes.length;i++){if(hitTest(my.shapes[i],mouseX,mouseY)){inQ=true}}
if(inQ){document.body.style.cursor='pointer'}else{document.body.style.cursor='default'}}
function mouseDownListener(ev){let i
let highestIndex=-1
let[mouseX,mouseY]=my.can.mousePos(ev)
for(i=0;i<my.shapes.length;i++){if(hitTest(my.shapes[i],mouseX,mouseY)){my.drag.onQ=true
if(i>highestIndex){my.drag.holdX=mouseX-my.shapes[i].x
my.drag.holdY=mouseY-my.shapes[i].y
highestIndex=i
my.drag.n=i}}}
if(my.drag.onQ){if(ev.touchQ){window.addEventListener('touchmove',ontouchmove,false)}else{window.addEventListener('mousemove',mouseMoveListener,false)}}
if(ev.touchQ){my.can.el.removeEventListener('touchstart',ontouchstart,false)
window.addEventListener('touchend',ontouchend,false)}else{my.can.el.removeEventListener('mousedown',mouseDownListener,false)
window.addEventListener('mouseup',mouseUpListener,false)}
if(ev.preventDefault){ev.preventDefault()}
else if(ev.returnValue){ev.returnValue=false}
return false}
function mouseUpListener(ev){my.can.el.addEventListener('mousedown',mouseDownListener,false)
window.removeEventListener('mouseup',mouseUpListener,false)
let[mouseX,mouseY]=my.can.mousePos(ev)
drop(mouseX,mouseY)
if(my.drag.onQ){my.drag.onQ=false
window.removeEventListener('mousemove',mouseMoveListener,false)}}
function mouseMoveListener(ev){if(my.drag.n<0)return
let[mouseX,mouseY]=my.can.mousePos(ev)
let minX=0
let maxX=my.can.el.width-my.shapes[my.drag.n].wd
let posX=mouseX-my.drag.holdX
posX=posX<minX?minX:posX>maxX?maxX:posX
let posY=mouseY-my.drag.holdY
my.shapes[my.drag.n].x=posX
my.shapes[my.drag.n].y=posY
for(let i=0;i<my.dests.length;i++){let dest=my.dests[i]
if(isIn(mouseX,mouseY,dest[0],dest[1],dest[2],dest[3])){dest[4]=1}else{dest[4]=0}}
drawShapes()}
function drop(mouseX,mouseY){for(let i=0;i<my.dests.length;i++){let dest=my.dests[i]
dest[4]=0
if(isIn(mouseX,mouseY,dest[0],dest[1],dest[2],dest[3])){updateDest(i,my.drag.n)}}}
function updateDest(to,from){if(to==0){my.eqs[0]=from}else{my.eqs[2]=from}
my.eqs[4]=(my.eqs[0]>>0)+(my.eqs[2]>>0)
makeShapes()
drawShapes()}
function isIn(x,y,lt,tp,wd,ht){if(x<lt)return false
if(x>lt+wd)return false
if(y<tp)return false
if(y>tp+ht)return false
return true}
function hitTest(shape,mx,my){if(mx<shape.x)return false
if(my<shape.y)return false
if(mx>shape.x+shape.wd)return false
if(my>shape.y+shape.ht)return false
return true}
function makeShapes(){my.shapes=[]
for(let i=0;i<this.numbers.length;i++){let tempX=my.startX+i*(my.cellWidth+my.spacing)
let tempY=20
let tempColor='rgb('+0+','+0+','+255+')'
let tempShape={x:tempX,y:tempY,wd:my.cellWidth,ht:my.cellWidth,color:tempColor,txt:this.numbers[i].toString()}
my.shapes.push(tempShape)}}
function drawShapes(){my.can.clear()
let g=my.can.g
for(let i=0;i<my.dests.length;i++){let dest=my.dests[i]
if(dest[4]==0){g.fillStyle='rgba(190, 210, 255, 0.6)'}else{g.fillStyle='rgba(255, 255, 0, 0.8)'}
g.beginPath()
g.rect(dest[0],dest[1],dest[2],dest[3])
g.closePath()
g.fill()}
g.font='bold 30px Arial'
g.textAlign='center'
for(let i=0;i<my.eqs.length;i++){let x=70+i*70
let y=100
g.strokeStyle='rgba(0, 0, 0, 1)'
g.fillStyle='hsla(240,100%,60%,1)'
g.fillText(my.eqs[i],x+60/2,y+40/2+8)}
g.lineWidth=1
g.strokeStyle='#aaaaaa'
for(let i=0;i<my.shapes.length;i++){g.lineWidth=1
g.strokeStyle='rgba(0, 0, 0, 1)'
g.fillStyle='rgba(220, 255, 220, 0.8)'
g.beginPath()
g.rect(my.shapes[i].x,my.shapes[i].y,my.shapes[i].wd,my.shapes[i].ht)
g.closePath()
g.stroke()
g.fill()
g.strokeStyle='rgba(0, 0, 0, 1)'
g.fillStyle='black'
g.font='bold 20px Arial'
g.textAlign='center'
g.fillText(my.shapes[i].txt,my.shapes[i].x+my.shapes[i].wd/2,my.shapes[i].y+my.shapes[i].ht/2+6,100)}
drawBalls(my.dests[0][0]-1,my.dests[0][1]+48,my.eqs[0])
drawBalls(my.dests[1][0]-1,my.dests[1][1]+48,my.eqs[2])
drawBalls(350,my.dests[0][1]+48,my.eqs[4])}
function drawBalls(x,y,n){if(n==0)return
let g=my.can.g
let xp=0
let yp=0
for(let i=0;i<n;i++){g.ball(this.ball,x+xp,y+yp)
xp+=22
if(xp>100){xp-=110
yp+=22}}}
CanvasRenderingContext2D.prototype.ball=function(ball,x,y){let size=ball.size
this.beginPath()
this.fillStyle=ball.color
this.arc(x,y,size,0,Math.PI*2,true)
let gradient=this.createRadialGradient(x-size/2,y-size/2,0,x,y,size)
gradient.addColorStop(0,ball.color)
gradient.addColorStop(1,ball.darkColor)
this.fillStyle=gradient
this.fill()
this.closePath()
this.beginPath()
this.arc(x,y,size*0.85,(Math.PI/180)*270,(Math.PI/180)*200,true)
gradient=this.createRadialGradient(x-size*0.5,y-size*0.5,0,x,y,size)
gradient.addColorStop(0,ball.lightColor)
gradient.addColorStop(0.5,'transparent')
this.fillStyle=gradient
this.fill()}
function docInsert(s){let div=document.createElement('div')
div.innerHTML=s
let script=document.currentScript
script.parentElement.insertBefore(div,script)}
class Can{constructor(id,wd,ht,ratio){this.id=id
this.wd=wd
this.ht=ht
this.ratio=ratio
let el=document.getElementById(id)
el.width=wd*ratio
el.style.width=wd+'px'
el.height=ht*ratio
el.style.height=ht+'px'
this.g=el.getContext('2d')
this.g.setTransform(ratio,0,0,ratio,0,0)
this.el=el
return this}
clear(){this.g.clearRect(0,0,this.wd,this.ht)}
mousePos(ev){let bRect=this.el.getBoundingClientRect()
let mouseX=(ev.clientX-bRect.left)*(this.el.width/this.ratio/bRect.width)
let mouseY=(ev.clientY-bRect.top)*(this.el.height/this.ratio/bRect.height)
return[mouseX,mouseY]}}
function wrap({id='',cls='',pos='rel',style='',txt='',tag='div',lbl='',fn='',opts=[]},...mores){let s=''
s+='\n'
txt+=mores.join('')
s+={btn:()=>{if(cls.length==0)cls='btn'
return '<button onclick="'+fn+'"'},can:()=>'<canvas',div:()=>'<div',edit:()=>{let s=''
s+=lbl.length>0?'<label class="label">'+lbl+' ':''
s+='<textarea onkeyup="'+fn+'" onchange="'+fn+'"'
return s},inp:()=>{if(cls.length==0)cls='input'
let s=''
s+=lbl.length>0?'<label class="label">'+lbl+' ':''
s+='<input value="'+txt+'"'
s+=fn.length>0?' oninput="'+fn+'" onchange="'+fn+'"':''
return s},out:()=>{pos='dib'
if(cls.length==0)cls='output'
let s=''
s+=lbl.length>0?'<label class="label">'+lbl+' ':''
s+='<span '
return s},rad:()=>{if(cls.length==0)cls='radio'
return '<form'+(fn.length>0?(s+=' onclick="'+fn+'"'):'')},sel:()=>{if(cls.length==0)cls='select'
let s=''
s+=lbl.length>0?'<label class="label">'+lbl+' ':''
s+='<select '
s+=fn.length>0?' onchange="'+fn+'"':''
return s},sld:()=>'<input type="range" '+txt+' oninput="'+fn+'" onchange="'+fn+'"',}[tag]()||''
if(id.length>0)s+=' id="'+id+'"'
if(cls.length>0)s+=' class="'+cls+'"'
if(pos=='dib')s+=' style="position:relative; display:inline-block;'+style+'"'
if(pos=='rel')s+=' style="position:relative; '+style+'"'
if(pos=='abs')s+=' style="position:absolute; '+style+'"'
s+={btn:()=>'>'+txt+'</button>',can:()=>'></canvas>',div:()=>' >'+txt+'</div>',edit:()=>' >'+txt+'</textarea>',inp:()=>'>'+(lbl.length>0?'</label>':''),out:()=>' >'+txt+'</span>'+(lbl.length>0?'</label>':''),rad:()=>{let s=''
s+='>\n'
for(let i=0;i<opts.length;i++){let chk=''
if(i==0)chk='checked'
s+='<input type="radio" id="r'+i+'" name="typ" style="cursor:pointer;" value="'+opts[i][0]+'" '+chk+' />\n'
s+='<label for="r'+i+'" style="cursor:pointer;">'+opts[i][1]+'</label><br/>\n'}
s+='</form>'
return s},sel:()=>{let s=''
s+='>\n'
for(let i=0;i<opts.length;i++){let opt=opts[i]
let idStr=id+i
let chkStr=opt.descr==txt?' selected ':''
s+='<option id="'+idStr+'" value="'+opt.name+'"'+chkStr+'>'+opt.descr+'</option>\n'}
s+='</select>'
if(lbl.length>0)s+='</label>'
return s},sld:()=>'>',}[tag]()||''
s+='\n'
return s.trim()}
init()