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

91 lines
20 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

var w,h,ratio,i,s,el,g,div,dragQ,game,my={};function mathmatchMain(mode){my.version='0.61';typ=typeof mode!=='undefined'?mode:'longitudinal';w=360;h=415;my.wd=75;my.ht=55;radius=150;my.games=[{name:'2D Shapes',typ:'2d',rowMax:4,colMax:4},{name:'2D Names',typ:'2dn',rowMax:4,colMax:4},{name:'Add Easy',typ:'add1',rowMax:4,colMax:4,min:1,max:5,dec:0},{name:'Add Medium',typ:'add2',rowMax:4,colMax:4,min:2,max:9,dec:0},{name:'Add Hard',typ:'add3',rowMax:6,colMax:4,min:2,max:20,dec:0},{name:'Multiply Easy',typ:'mul1',rowMax:4,colMax:4,min:2,max:5,dec:0},{name:'Multiply Medium',typ:'mul2',rowMax:4,colMax:4,min:2,max:8,dec:0},{name:'Multiply Hard',typ:'mul3',rowMax:6,colMax:4,min:2,max:12,dec:0}];my.gameNo=0;my.game=my.games[my.gameNo];var s='';s+='<audio id="sndturn" src="../images/sounds/swish.mp3" preload="auto"></audio>';s+='<audio id="sndback" src="../images/sounds/swish3.mp3" preload="auto"></audio>';s+='<audio id="sndwin" src="../images/sounds/success.mp3" preload="auto"></audio>';s+='<div id="main" style="position:relative; width:'+w+'px; min-height:'+h+'px; background-color: white; margin:auto; display:block; border: none; border-radius: 10px;">';s+='<div id="canvasDad" style="">';s+='</div>';s+='<div id="togo" style="position: relative; top: 0px; width:60px; float:left; padding: 8px; border-radius: 10px; background-color: rgba(0,100,100,1); z-index: 30; color:white; font: 24px Arial; text-align:center; margin-right:10px;">0</div>';my.soundQ=true
s+=soundBtnHTML('rgba(0,100,100,1)')
s+='<div id="clock" style="position: relative; top: 0px; width:60px; float:right; padding: 8px; border-radius: 10px; background-color: rgba(0,0,100,0.7); z-index: 30; color:white; font: 24px Arial; text-align:center;">';s+=getDClockHTML();s+='</div>';s+='<div style="visibility:hidden">';s+='<svg id="svg1" xmlns="http://www.w3.org/2000/svg" width="9" height="9">';s+='<line x1="10" y1="0" x2="0" y2="10" stroke-width="1" stroke="green"/>';s+='</svg>';s+='</div>';s+='<div id="result" style="position: absolute; left: 10px; top: 60px; width: '+(w-60)+'px; text-align: center; padding: 20px; border-radius: 20px; background-color: rgba(0,0,100,0.5); z-index: 30; transition:opacity 1s; ">';s+='<div id="msg" style="font: 28px Verdana; color: white;"></div>';s+='<br>';s+='<style>input[type="radio"]:checked+label {font-weight: bold;}</style>';s+=getRadioHTML('Game','game',my.games,'radioClick');s+='<button id="restart" style="font: 14px Arial; height:30px; text-align:right; z-index: 10;" class="togglebtn" onclick="gameStart()" >New Game</button>';s+='</div>';s+='<div id="copyrt" style="font: 10px Arial; font-weight: bold; color: #6600cc; position:absolute; bottom:5px; left:5px; text-align:center;">&copy; 2017 MathsIsFun.com v'+my.version+'</div>';s+='</div>';document.write(s);my.clrs=[["Blue",'#0000FF'],["Red",'#FF0000'],["Green",'#00cc00'],["Orange",'#FFA500'],["Slate Blue",'#6A5ACD'],["Lime",'#00FF00'],["Spring Green",'#00FF7F'],["Teal",'#008080'],["Gold",'#ffd700'],["Med Purple",'#aa00aa'],["Light Blue",'#ADD8E6'],["Navy",'#000080'],["Purple",'#800080'],["Dark SeaGreen",'#8FBC8F'],["Black",'#000000']];clrNum=0;my.reveals=[];my.noClickQ=false;my.deck=new Deck();}
function radioClick(n){my.gameNo=n;}
function gameStart(){my.game=my.games[my.gameNo];console.log("gameStart",my.game,my.gameNo);var div=document.getElementById('result');div.style.visibility='hidden';div.style.opacity=0;var fromDate=new Date(Date.parse(new Date()));initializeClock('clockdiv',fromDate);my.deck.makeCards();my.deck.shuffle();placeCards();document.getElementById('togo').innerHTML=my.deck.countFace(false);my.inGameQ=true;my.revealN=0;}
function placeCards(){var xp=20;var yp=0;var lt=0;if(my.game.colMax==4)lt=30;var tp=55;for(var i=0;i<my.game.rowMax;i++){for(var j=0;j<my.game.colMax;j++){var cardNo=i*my.game.colMax+j;var card=my.deck.cards[cardNo];card.show('back');xp=lt+j*(card.wd+2);yp=tp+i*(card.ht+2);card.place(xp,yp);}}}
function typChg(){var div=document.getElementById('typSel');typ=div.options[div.selectedIndex].text;typ=typ.toLowerCase();console.log("typChg",typ);restart();}
function getRadioHTML(prompt,id,lbls,func){var s='';s+='<div style="display:inline-block; border: 1px solid white; border-radius:5px; padding:3px; margin:3px; background-color:rgba(255,255,255,0.7);font: 16px Verdana; text-align:left;">';s+=prompt+':';for(var i=0;i<lbls.length;i++){var idi=id+i;var lbl=lbls[i];var check='';if(i==0)check=' checked="checked" ';s+='<br>';s+='<input id="'+idi+'" type="radio" name="'+id+'" value="'+lbl+'" onclick="'+func+'('+i+');"'+check+' autocomplete="off" >';s+='<label for="'+idi+'">'+lbl.name+' </label>';}
s+='</div>';return s;}
function getDropdownHTML(opts,funcName,id){var s='';s+='<select id="'+id+'" style="font: 15px Arial; color: #6600cc; background: rgba(200,220,256,0.7); padding: 1px; border-radius: 6px;" onchange="'+funcName+'()" autocomplete="off" >';for(var i=0;i<opts.length;i++){var idStr=id+i;var chkStr=i==0?'selected':'';s+='<option id="'+idStr+'" value="'+opts[i]+'" style="height:18px;" '+chkStr+' >'+opts[i]+'</option>';}
s+='</select>';return s;}
function getPlayHTML(w){var s='';s+='<style type="text/css">';s+='.btn {display: inline-block; position: relative; width:'+w+'px; height:'+w+'px; margin-right:'+w*0.2+'px; padding: .6em; border: 0 solid rgba(208,208,248,1); border-radius: 10em; background: linear-gradient(#fff, #ccf), #c9c5c9; box-shadow: 0 3 4 rgba(0,0,0,.4); }';s+='.btn:hover {background: linear-gradient(#f5f5f5, #b9b9b9), #c9c5c9; }';s+='.btn:before, button:after {content: " "; position: absolute; }';s+='.btn:active {top:'+w*0.05+'px; box-shadow: 0 '+w*0.02+'px '+w*0.03+'px rgba(0,0,0,.4); }';s+='.play:before { left: '+w*0.36+'px; top: '+w*0.22+'px; width: 0; height: 0; border: '+w*0.3+'px solid transparent; border-left-width: '+w*0.4+'px; border-left-color: blue; }';s+='.play:hover:before {border-left-color: yellow; }';s+='.pause:before, .pause:after {display: block; left: '+w*0.29+'px; top: '+w*0.28+'px; width: '+w*0.19+'px; height: '+w*0.47+'px; background-color: blue; }';s+='.pause:after {left: '+w*0.54+'px; }';s+='.pause:hover:before, .pause:hover:after {background-color: yellow; }';s+='</style>';s+='<button id="playBtn" class="btn play" onclick="togglePlay()" ></button>';return s;}
function matchNo(){if(my.soundQ)document.getElementById('sndback').play();my.reveals[0].rotateTo(false);my.reveals[1].rotateTo(false);my.revealN=0;my.noClickQ=false;var togo=my.deck.countFace(false);}
function matchYes(){my.revealN=0;my.noClickQ=false;var togo=my.deck.countFace(false);togo-=1;document.getElementById('togo').innerHTML=togo;if(togo<=0)successDo();}
function successDo(){console.log("successDo");if(my.soundQ)document.getElementById('sndwin').play();var timeStr=document.getElementById('clockdiv').innerHTML;var s='';s+='Well Done!<br>';s+='You finished in '+timeStr;var div=document.getElementById('msg');div.innerHTML=s;clearInterval(my.timeinterval);var div=document.getElementById('result');div.style.visibility='visible';div.style.opacity=1;}
function togglePlay(){var btn='playBtn';if(my.playQ){my.playQ=false;document.getElementById(btn).classList.add("play");document.getElementById(btn).classList.remove("pause");}else{my.playQ=true;document.getElementById(btn).classList.add("pause");document.getElementById(btn).classList.remove("play");anim();}}
function anim(){if(my.playQ){requestAnimationFrame(anim);}}
function getDClockHTML(){var s='';s+='<div id="clockdiv">';s+='<span class="minutes">00</span>:';s+='<span class="seconds">00</span>';s+='</div>';return s;}
function getTimeSoFar(stttime){var t=Date.parse(new Date())-Date.parse(stttime);var seconds=Math.floor((t/1000)%60);var minutes=Math.floor((t/1000/60)%60);var hours=Math.floor((t/(1000*60*60))%24);var days=Math.floor(t/(1000*60*60*24));return{'total':t,'days':days,'hours':hours,'minutes':minutes,'seconds':seconds};}
function getTimeRemaining(endtime){var t=Date.parse(endtime)-Date.parse(new Date());var seconds=Math.floor((t/1000)%60);var minutes=Math.floor((t/1000/60)%60);var hours=Math.floor((t/(1000*60*60))%24);var days=Math.floor(t/(1000*60*60*24));return{'total':t,'days':days,'hours':hours,'minutes':minutes,'seconds':seconds};}
function stopClock(){clearInterval(my.timeinterval);}
function initializeClock(id,stttime){var clock=document.getElementById(id);var minutesSpan=clock.querySelector('.minutes');var secondsSpan=clock.querySelector('.seconds');function updateClock(){var t=getTimeSoFar(stttime);minutesSpan.innerHTML=('0'+t.minutes).slice(-2);secondsSpan.innerHTML=('0'+t.seconds).slice(-2);if(t.total<=0){clearInterval(my.timeinterval);}}
updateClock();my.timeinterval=setInterval(updateClock,1000);}
function getRegular(midX,midY,radius,sttAngle,n){var pts=[];var dAngle=Math.PI*2/n;for(var i=0;i<n;i++){var angle=sttAngle+i*dAngle;var x=midX+radius*Math.cos(angle);var y=midY+radius*Math.sin(angle);pts.push({x:x,y:y});}
return pts;}
function drawPts(g,pts){for(var i=0;i<pts.length;i++){var pt=pts[i];if(i==0){g.moveTo(pt.x,pt.y)}else{g.lineTo(pt.x,pt.y)}}}
function getRandomInt(min,max){return Math.floor(Math.random()*(max-min+1)+min);}
function fmtDec(v,dec,dropZerosQ){dropZerosQ=typeof dropZerosQ!=='undefined'?dropZerosQ:false;var s=(v/Math.pow(10,dec)).toFixed(dec);if(dropZerosQ){if(s.indexOf(".")>=0){s=s.replace(/0+$/,'');}
if(s.charAt(s.length-1)=="."){s=s.substring(0,s.length-1);}}
return s;}
function Deck(){this.names=['1','2','3','4','5','6','7','8','9','10','J','Q','K'];this.suits=['Clubs','Spades','Hearts','Diamonds'];this.cards=[];this.backImg=new Image();this.backImg.setAttribute('crossOrigin','anonymous');var svg=document.getElementById('svg1');var xml=(new XMLSerializer).serializeToString(svg);this.backImg.src='data:image/svg+xml;charset=utf-8,'+xml;this.frontImg=new Image();this.frontImg.setAttribute('crossOrigin','anonymous');this.frontImg.onload=this.makeCards.bind(this);this.frontImg.src='../data/images/cards.png';}
Deck.prototype.makeCards=function(){var dadDiv=document.getElementById("canvasDad");while(dadDiv.firstChild){dadDiv.removeChild(dadDiv.firstChild);}
this.cards=[];var deckTyp=my.game.typ;switch(deckTyp){case '2d':case '2dn':var names=['Rectangle','Circle','Kite','Pentagon','Hexagon','Semicircle','Quadrant','Triangle'];for(var i=0;i<names.length;i++){var name=names[i];for(var k=0;k<2;k++){var card=new Card(name,i,this.backImg,this.frontImg);var g=card.front.getContext('2d');g.fillStyle='#eed';g.beginPath();g.roundRect(0,0,card.wd,card.ht,5);g.fill();var mid={x:card.wd/2,y:card.ht/2}
if(deckTyp=='2dn'&&k==1){g.textAlign='center';g.font='16px Arial';g.fillStyle='blue';g.beginPath();g.fillText(name,mid.x,mid.y+5);g.fill();this.cards.push(card);continue;}
g.strokeStyle='black';g.fillStyle=my.clrs[i][1];g.beginPath();switch(name.toLowerCase().substr(0,4)){case 'squa':g.rect(20,10,35,35);break;case 'rect':g.rect(10,10,50,30);break;case 'kite':g.moveTo(mid.x,10);g.lineTo(mid.x+20,20);g.lineTo(mid.x,50);g.lineTo(mid.x-20,20);break;case 'circ':g.arc(mid.x,mid.y,20,0,2*Math.PI)
break;case 'semi':g.arc(mid.x,mid.y-10,20,0,Math.PI)
break;case 'quad':g.moveTo(mid.x-10,mid.y-10)
g.arc(mid.x-10,mid.y-10,25,0,Math.PI/2)
break;case 'tria':var sides=3;var poly=getRegular(mid.x,mid.y,20,Math.PI*(0.5+1/sides),sides);drawPts(g,poly);break;case 'pent':var sides=5;var poly=getRegular(mid.x,mid.y,20,Math.PI*(0.5+1/sides),sides);drawPts(g,poly);break;case 'hexa':var sides=6;var poly=getRegular(mid.x,mid.y,20,Math.PI*(0.5+1/sides),sides);drawPts(g,poly);break;default:}
g.closePath();g.fill();g.stroke();this.cards.push(card);}}
break;case 'add1':case 'add2':case 'add3':case 'mul1':case 'mul2':case 'mul3':var qTyp=deckTyp.substr(0,3);for(var i=0;i<my.game.rowMax*my.game.colMax/2;i++){var qa=newMathGame(qTyp);for(var k=0;k<2;k++){var card=new Card(qa.a,i,this.backImg,this.frontImg);var g=card.front.getContext('2d');g.fillStyle='#ffe';g.beginPath();g.roundRect(0,0,card.wd,card.ht,5);g.fill();var mid={x:card.wd/2,y:card.ht/2};var s='';if(k==0)s=qa.q;if(k==1)s=qa.a;g.textAlign='center';g.font='18px Arial';g.fillStyle='blue';g.beginPath();g.fillText(s,mid.x,mid.y+5);g.fill();this.cards.push(card);}}
break;default:}}
function getQAs(typ){var names=[];for(var i=0;i<8;i++){var qa=newMathGame('add');names.push(name)}
return names;}
function getQA(typ){}
function newMathGame(typ){var min=my.game.min;var max=my.game.max;var dec=my.game.dec;console.log("newMathGame",min,max,typ,dec);var decAns=dec;switch(typ){case 'add':my.tgtN=getRandomInt(min*2,max);var a=getRandomInt(min,my.tgtN-min);var b=my.tgtN-a;if(dec>0){var dec1=getRandomInt(0,dec-a.toString().length+1);var dec2=getRandomInt(0,dec-b.toString().length+1);if(dec1>0)a*=Math.pow(10,dec1);if(dec2>0)b*=Math.pow(10,dec2);}
console.log("add",a,b,dec1,dec2);my.q=fmtDec(a,dec)+' + '+fmtDec(b,dec);my.tgtN=fmtDec(a+b,dec);break;case 'sub':var a=getRandomInt(min,max);var b=getRandomInt(min,max);if(dec>0){var dec1=getRandomInt(0,dec-a.toString().length+1);var dec2=getRandomInt(0,dec-b.toString().length+1);if(dec1>0)a*=Math.pow(10,dec1);if(dec2>0)b*=Math.pow(10,dec2);}
if(a<b){var t=a
a=b;b=t;}
my.tgtN=fmtDec(a-b,dec)
my.q=fmtDec(a,dec)+' - '+fmtDec(b,dec)+' =';break;case 'mul':var a=getRandomInt(min,max);var b=getRandomInt(min,max);if(dec>0){dec1=getRandomInt(0,dec);dec2=dec-dec1;decAns=dec*2;if(dec1>0)a*=Math.pow(10,dec1);if(dec2>0)b*=Math.pow(10,dec2);}
my.tgtN=fmtDec(a*b,decAns,true)
my.q=fmtDec(a,dec)+' × '+fmtDec(b,dec);break;case 'div':var a=getRandomInt(min,max);var b=getRandomInt(min,max);if(dec>0){dec1=getRandomInt(0,dec);dec2=dec-dec1;decAns=dec*2;if(dec1>0)a*=Math.pow(10,dec1);if(dec2>0)b*=Math.pow(10,dec2);}
my.tgtN=fmtDec(a,dec,true);my.q=fmtDec(a*b,decAns,true)+' / '+fmtDec(b,dec)+' =';break;default:}
return{q:my.q,a:my.tgtN};}
Deck.prototype.countFace=function(frontq){var n=0;for(var i=0;i<this.cards.length;i++){var card=this.cards[i];if(card.frontQ==frontq)n++;}
return n;}
Deck.prototype.shuffle=function(){for(var i=this.cards.length-1;i>0;i-=1){var j=Math.floor(Math.random()*(i+1));var temp=this.cards[i];this.cards[i]=this.cards[j];this.cards[j]=temp;}}
Deck.prototype.redraw=function(){for(var i=0;i<this.cards.length;i++){var card=this.cards[i];card.front.style.left=(i*16)+'px';card.front.style.top=(100)+'px';card.front.style.zIndex=i;}}
function Card(name,i,backImg,frontImg){this.val=i;this.name=name;this.frontQ=true;this.ratio=1;this.wd=my.wd;this.ht=my.ht;var dadDiv=document.getElementById('canvasDad');this.front=document.createElement('canvas');dadDiv.appendChild(this.front);this.front.width=this.wd;this.front.height=this.ht;this.front.style.position="absolute";this.front.style.visibility='hidden';this.front.addEventListener('mousedown',this.click.bind(this));this.back=document.createElement('canvas');dadDiv.appendChild(this.back);this.back.width=this.wd;this.back.height=this.ht;this.drawBack(backImg);this.back.style.position="absolute";this.place(i*(this.wd+6),150);this.back.style.visibility='hidden';this.back.addEventListener('mousedown',this.click.bind(this));}
Card.prototype.click=function(){if(my.noClickQ)return;if(this.frontQ)return;my.reveals[my.revealN]=this;my.revealN++;if(my.soundQ){soundStopAll()
document.getElementById('sndturn').play();}
if(my.revealN>=2){if(my.reveals[0].name==my.reveals[1].name){my.revealN=0;matchYes();}else{my.noClickQ=true;setTimeout(matchNo,1000);}}
this.rotateStt();}
Card.prototype.rotateTo=function(frontq){if(this.frontQ!=frontq){this.rotateStt();}}
Card.prototype.rotateStt=function(){this.stt=performance.now();this.toFrontQ=!this.frontQ;this.rotate();}
Card.prototype.rotate=function(){var step=0.1;if(this.toFrontQ){if(!this.frontQ){this.ratio-=step;this.back.style.width=(this.wd*this.ratio)+'px';this.back.style.height=this.ht+'px';this.back.style.left=(this.x+this.wd*(1-this.ratio)/2)+'px';this.back.style.top=this.y+'px';if(this.ratio>=0){requestAnimationFrame(this.rotate.bind(this));}else{this.frontQ=true;this.front.style.width='0px';this.show('front');requestAnimationFrame(this.rotate.bind(this));}}else{this.ratio+=step;this.front.style.width=(this.wd*this.ratio)+'px';this.front.style.height=this.ht+'px';this.front.style.left=(this.x+this.wd*(1-this.ratio)/2)+'px';this.front.style.top=this.y+'px';if(this.ratio<1){requestAnimationFrame(this.rotate.bind(this));}else{this.front.style.width=this.wd+'px';this.front.style.height=this.ht+'px';this.back.style.width=this.wd+'px';this.back.style.height=this.ht+'px';}}}else{if(this.frontQ){this.ratio-=step;this.front.style.width=(this.wd*this.ratio)+'px';this.front.style.height=this.ht+'px';this.front.style.left=(this.x+this.wd*(1-this.ratio)/2)+'px';this.front.style.top=this.y+'px';if(this.ratio>=0){requestAnimationFrame(this.rotate.bind(this));}else{this.frontQ=false;this.back.style.width='0px';this.show('back');requestAnimationFrame(this.rotate.bind(this));}}else{this.ratio+=step;this.back.style.width=(this.wd*this.ratio)+'px';this.back.style.height=this.ht+'px';this.back.style.left=(this.x+this.wd*(1-this.ratio)/2)+'px';this.back.style.top=this.y+'px';if(this.ratio<1){requestAnimationFrame(this.rotate.bind(this));}else{this.front.style.width=this.wd+'px';this.front.style.height=this.ht+'px';this.back.style.width=this.wd+'px';this.back.style.height=this.ht+'px';}}}}
Card.prototype.drawBack=function(backImg){var g=this.back.getContext('2d');g.strokeStyle='grey';g.fillStyle='#def';g.beginPath();g.roundRect(0,0,this.wd,this.ht,5);g.fill();var gap=6;g.strokeStyle='grey';g.fillStyle='#cdf';g.beginPath();g.roundRect(gap,gap,this.wd-2*gap,this.ht-2*gap,gap/2);g.fill();g.stroke();g.beginPath();g.fillStyle='#fff';g.font='italic 40px Arial'
g.textAlign='center'
g.fillText('?',my.wd/2,my.ht/2+15);}
Card.prototype.drawBack2=function(backImg){var g=this.back.getContext('2d');g.strokeStyle='#def';g.fillStyle='#def';g.beginPath();g.roundRect(0,0,this.wd,this.ht,5);g.fill();var gap=6;g.strokeStyle='grey';g.fillStyle=g.createPattern(backImg,"repeat");g.beginPath();g.roundRect(gap,gap,this.wd-2*gap,this.ht-2*gap,gap/2);g.fill();g.stroke();}
Card.prototype.show=function(side){switch(side){case 'front':this.front.style.visibility='visible';this.back.style.visibility='hidden';this.frontQ=true;break;case 'back':this.front.style.visibility='hidden';this.back.style.visibility='visible';this.frontQ=false;break;case 'none':this.front.style.visibility='hidden';this.back.style.visibility='hidden';break;default:}}
Card.prototype.place=function(x,y){this.x=x;this.y=y;this.front.style.left=x+'px';this.front.style.top=y+'px';this.back.style.left=x+'px';this.back.style.top=y+'px';}
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;}
function soundBtnHTML(clr){s=''
s+='<style> '
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: '+clr+'; margin: 10px 0 0 1px; }'
s+=' .speaker span:after { content: ""; position: absolute; width: 0; height: 0; border-style: solid; border-color: transparent '+clr+' 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: blue; 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+=' </style>'
s+='<div id="sound" onClick="soundToggle()" class="speaker"><span></span></div>'
return s}
function soundToggle(){var 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 soundStopAll(){var sounds=document.getElementsByTagName('audio');console.log('sounds',sounds)
for(i=0;i<sounds.length;i++){sounds[i].pause();sounds[i].currentTime=0.0;}}