summaryrefslogtreecommitdiff
path: root/libs/music/player.d/main.js
diff options
context:
space:
mode:
Diffstat (limited to 'libs/music/player.d/main.js')
-rw-r--r--libs/music/player.d/main.js610
1 files changed, 610 insertions, 0 deletions
diff --git a/libs/music/player.d/main.js b/libs/music/player.d/main.js
new file mode 100644
index 0000000..4795e5f
--- /dev/null
+++ b/libs/music/player.d/main.js
@@ -0,0 +1,610 @@
+var audio;
+var playlist;
+var tracks;
+var current;
+var mbuttonstate=0;
+var plistshown=true;
+var shuffle=0,repeat=0;
+var plistRect;
+var dpiratio=window.devicePixelRatio?window.devicePixelRatio:1;
+
+var audioCtxt=null;
+var CtxtSource=null;
+var CtxtAnalyser=null;
+var canvas;
+var CSpectrum=1024,CSpectrumIF=128;
+var SpecWidth=0.7,SpecGap=0.08125;
+var caps=[];
+var visualselector=null;
+var SpecRingRadius=225;
+var spectrogrampos=0;
+var inkimg=[];
+var f1=0,f2=0,penv=0,btrig=0,beatp=0,lastbp=0;
+var lpbd=300,lpf=1./(2*Math.PI*lpbd),beatr=0.02;
+var frms=0,lastfpsupd=null,fps=0;
+var ic1=["#FF3333","#FF8800","#FFFF00","#CCFF00","#33CCFF","#0000FF","#9966FF"];
+var ic2=["rgba(204,51,51,0.6)","rgba(187,85,0,0.6)","rgba(255,204,0,0.6)","rgba(153,204,0,0.6)","rgba(51,153,255,0.6)","rgba(0,0,102,0.6)","rgba(153,51,204,0.6)"]
+var Ink=function(_vx,_vy,_c)
+{
+ this.x=canvas.width/2;this.y=canvas.height/2;
+ this.vx=_vx;this.vy=_vy;
+ this.color=_c>6?6:_c;this.active=true;
+};
+Ink.prototype.update=function()
+{
+ this.x+=this.vx;this.y+=this.vy;
+ this.vx*=0.995;this.vy*=0.995;
+ if(this.x<-10||this.x>canvas.width+10||this.y<-10||this.y>canvas.height+10)
+ this.active=false;
+}
+Ink.prototype.draw=function(cctx)
+{
+ cctx.drawImage(inkimg[this.color],this.x+5*window.devicePixelRatio,this.y+5*window.devicePixelRatio);
+}
+var inks=[];
+function inkPrepare()
+{
+ for(var i=0;i<7;++i)
+ {
+ inkimg[i]=document.createElement('canvas');
+ inkimg[i].width=inkimg[i].height=10*window.devicePixelRatio;
+ var cctx=inkimg[i].getContext('2d');
+ cctx.fillStyle=ic1[i];
+ cctx.beginPath();
+ cctx.arc(5*window.devicePixelRatio,5*window.devicePixelRatio,3*window.devicePixelRatio,0,2*Math.PI);
+ cctx.fill();
+ cctx.fillStyle=ic2[i];
+ cctx.beginPath();
+ cctx.arc(5*window.devicePixelRatio,5*window.devicePixelRatio,5*window.devicePixelRatio,0,2*Math.PI);
+ cctx.fill();
+ }
+}
+function createInk(_vx,_vy,_c1,_c2)
+{
+ var f=false;
+ for(var i=0;i<inks.length;++i)
+ {
+ if(!inks[i].active)
+ {inks[i]=new Ink(_vx,_vy,_c1,_c2);f=true;break;}
+ }
+ if(!f&&inks.length<512)inks.push(new Ink(_vx,_vy,_c1,_c2));
+}
+
+function gup(name,url)
+{
+ if(!url)url=location.href;
+ name=name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
+ var regexS="[\\?&]"+name+"=([^&#]*)";
+ var regex=new RegExp(regexS);
+ var results=regex.exec(url);
+ return results==null?null:results[1];
+}
+function getcookie(key)
+{return document.cookie.replace(new RegExp("(?:(?:^|.*;\\s*)"+key+"\\s*\\=\\s*([^;]*).*$)|^.*$"),"$1");}
+
+function initAPI()
+{
+ window.AudioContext=window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext;
+ window.requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame;
+ window.cancelAnimationFrame=window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.msCancelAnimationFrame;
+ audioCtxt=new AudioContext;
+ CtxtSource=audioCtxt.createBufferSource();
+ CtxtAnalyser=audioCtxt.createAnalyser();
+ CtxtAnalyser.fftSize=2*CSpectrum;
+ for(var i=0;i<CSpectrum;++i)caps[i]=0;
+}
+
+function init()
+{
+ if( navigator.userAgent.match(/Android/i)
+ || navigator.userAgent.match(/webOS/i)
+ || navigator.userAgent.match(/iPhone/i)
+ || navigator.userAgent.match(/iPad/i)
+ || navigator.userAgent.match(/iPod/i)
+ || navigator.userAgent.match(/BlackBerry/i)
+ || navigator.userAgent.match(/Windows Phone/i)
+ )
+ {
+ visualselector=document.getElementById("playlist").style.width="90%";
+ document.getElementById("help").style.maxWidth=window.innerWidth+"px";
+ if(window.innerWidth<window.innerHeight)
+ document.getElementById("cvs").width=screen.width*0.98,
+ document.getElementById("cvs").height=(screen.width*0.98/16*9);
+ else
+ document.getElementById("cvs").width=(screen.height*0.98/9*16),
+ document.getElementById("cvs").height=screen.height*0.98;
+ }
+ if(!window.devicePixelRatio)window.devicePixelRatio=1;
+ document.getElementById("cvs").style.width=document.getElementById("cvs").width+"px";
+ document.getElementById("cvs").style.height=document.getElementById("cvs").height+"px";
+ document.getElementById("cvs").width=document.getElementById("cvs").width*window.devicePixelRatio;
+ document.getElementById("cvs").height=document.getElementById("cvs").height*window.devicePixelRatio;
+ current=0;
+ visualselector=document.getElementById("visualizationsel");
+ canvas=document.getElementById("cvs");
+ audio=document.getElementById("audio");
+ playlist=$('#playlist');
+ tracks=playlist.find('li a');
+ len=tracks.length;SpecRingRadius=canvas.width/2;
+ audio.volume=.80;SpecWidth=canvas.width/CSpectrum;SpecGap=SpecWidth/10;SpecWidth*=0.9;
+ initAPI();inkPrepare();document.onmousemove=mm;
+ CtxtSource=audioCtxt.createMediaElementSource(audio);
+ CtxtSource.connect(CtxtAnalyser);
+ CtxtAnalyser.connect(audioCtxt.destination);
+ plistRect=document.getElementById("playlist").getBoundingClientRect();
+ for(var i=0;i<playlist.find('a').length;++i)
+ {
+ if(playlist.find('a')[i].textContent==decodeURIComponent(gup('title')))
+ {current=i;run($(playlist.find('a')[i]));break;}
+ }
+ playlist.find('a').click(function(e){
+ e.preventDefault();
+ link=$(this);
+ current=link.parent().index()-1;
+ run(link);
+ });
+ visualselector.onchange=function(){
+ if(this.value!="none"&&this.oldvalue=="none")requestAnimationFrame(updateVisualization);
+ else canvas.getContext('2d').clearRect(0,0,canvas.width,canvas.height);
+ document.cookie="playervisualization="+this.value;
+ this.oldvalue=this.value;
+ };
+ window.onresize=windowresize;
+ audio.ontimeupdate=timeUpdate;
+ audio.addEventListener('ended',function(e){
+ if(repeat==0)
+ {
+ current++;
+ if(current==len){
+ current=0;
+ if(shuffle)shufflePlist();
+ link=playlist.find('a')[0];
+ }else{
+ link=playlist.find('a')[current];
+ }
+ run($(link));
+ }
+ });
+ document.getElementById("shufflesw").onclick=function(){
+ shuffle=1-shuffle;
+ if(shuffle==0)
+ {
+ document.getElementById("shufflesw").innerHTML="Off";
+ document.cookie="playershuffle=0";
+ sortPlist();
+ }
+ else
+ {
+ document.getElementById("shufflesw").innerHTML="On";
+ document.cookie="playershuffle=1";
+ shufflePlist();
+ }
+ }
+ document.getElementById("repeatsw").onclick=function(){
+ repeat=1-repeat;
+ if(repeat==0)
+ {
+ document.getElementById("repeatsw").innerHTML="Off";
+ document.cookie="playerrepeat=0";
+ audio.loop=false;
+ }
+ else
+ {
+ document.getElementById("repeatsw").innerHTML="On";
+ document.cookie="playerrepeat=1";
+ audio.loop=true;
+ }
+ }
+ document.getElementById("plistsw").onclick=togglePlist;
+ document.body.onmousedown=function(e){if(e.buttons==1)mbuttonstate=1;}
+ document.body.onmouseup=function(e){if(e.buttons!=1)mbuttonstate=0;}
+ document.getElementById("tsliderbase").onclick=function(e)
+ {
+ var sr=this.getBoundingClientRect();
+ var p=(e.clientX-sr.left)/sr.width;
+ audio.currentTime=audio.duration*p;
+ }
+ document.getElementById("tsliderbase").onmousemove=function(e)
+ {
+ if(!mbuttonstate)return;
+ var sr=this.getBoundingClientRect();
+ var p=(e.clientX-sr.left)/sr.width;
+ audio.currentTime=audio.duration*p;
+ }
+ document.getElementById("pbplaypause").onclick=function()
+ {
+ if(audio.src==""){run($(playlist.find('a')[0]));return;}
+ if(audio.paused)
+ {
+ audio.play();
+ document.getElementById("imgplaypause").src="pause.svg";
+ }
+ else
+ {
+ audio.pause();
+ document.getElementById("imgplaypause").src="play.svg";
+ }
+ }
+ document.getElementById("pbprev").onclick=function()
+ {
+ if(audio.currentTime>10)audio.currentTime=0;
+ else
+ {
+ current--;
+ if(current<0){
+ current+=len;
+ if(shuffle)shufflePlist();
+ link=playlist.find('a')[len-1];
+ }else{
+ link=playlist.find('a')[current];
+ }
+ run($(link));
+ }
+ }
+ document.getElementById("pbnext").onclick=function()
+ {
+ current++;
+ if(current==len){
+ current=0;
+ if(shuffle)shufflePlist();
+ link=playlist.find('a')[0];
+ }else{
+ link=playlist.find('a')[current];
+ }
+ run($(link));
+ }
+ switch(getcookie("playershuffle"))
+ {
+ case "1":
+ document.getElementById("shufflesw").innerHTML="On";
+ document.cookie="playershuffle=1";
+ shufflePlist();
+ break;
+ default:
+ case "0":
+ document.getElementById("shufflesw").innerHTML="Off";
+ document.cookie="playershuffle=0";
+ sortPlist();
+ break;
+ }
+ switch(getcookie("playerrepeat"))
+ {
+ case "1":
+ document.getElementById("repeatsw").innerHTML="On";
+ document.cookie="playerrepeat=1";
+ audio.loop=true;
+ break;
+ default:
+ case "0":
+ document.getElementById("repeatsw").innerHTML="Off";
+ document.cookie="playerrepeat=0";
+ audio.loop=false;
+ break;
+ }
+ if(getcookie("playervisualization").length!==0)
+ visualselector.value=getcookie("playervisualization");
+ requestAnimationFrame(updateVisualization);
+}
+function shufflePlist()
+{
+ for(var i=0;i<playlist.find('a').length;++i)
+ $(playlist.find('a')[i]).attr("sord",Math.random()*playlist.find('a').length);
+ var plli=$(playlist).children('li');
+ plli.sort(
+ function(a,b)
+ {
+ var as=Number($(a).children('a').attr("sord"));
+ var bs=Number($(b).children('a').attr("sord"));
+ return as>bs?1:as<bs?-1:0;
+ }
+ );
+ plli.detach().appendTo($(playlist));
+ var t=$("li.active").children().length?$("li.active").children()[0].textContent:"";
+ for(var i=0;i<playlist.find('a').length;++i)
+ {
+ if(playlist.find('a')[i].textContent==t)
+ {current=i;break;}
+ }
+}
+function sortPlist()
+{
+ var plli=$(playlist).children('li');
+ plli.sort(
+ function(a,b)
+ {
+ var as=Number($(a).children('a').attr("ord"));
+ var bs=Number($(b).children('a').attr("ord"));
+ return as>bs?1:as<bs?-1:0;
+ }
+ );
+ plli.detach().appendTo($(playlist));
+ var t=$("li.active").children().length?$("li.active").children()[0].textContent:"";
+ for(var i=0;i<playlist.find('a').length;++i)
+ {
+ if(playlist.find('a')[i].textContent==t)
+ {current=i;break;}
+ }
+}
+function formatTime(t)
+{
+ var m=Math.floor(t/60),s=Math.round(t-Math.floor(t/60)*60);
+ if(s<10)return m+":0"+s;
+ else if(s==60)return (m+1)+":00";
+ else return m+":"+s;
+}
+function bufferedUpdate()
+{
+ var r=0;
+ for(var i=0;i<audio.buffered.length;++i)
+ r=r<audio.buffered.end(i)?audio.buffered.end(i):r;
+ document.getElementById("cbuff").style.width=r/audio.duration*100+"%";
+}
+function timeUpdate()
+{
+ document.getElementById("timenow").innerHTML=formatTime(audio.currentTime);
+ document.getElementById("timeleft").innerHTML="-"+formatTime(audio.duration-audio.currentTime);
+ document.getElementById("ctime").style.width=audio.currentTime/audio.duration*100+"%";
+ bufferedUpdate();
+}
+function mm(e)
+{
+ /*if(e.clientX<320&&e.clientY>(window.innerHeight-383))
+ {
+ changeImage('../../../koishi_hovr.png');
+ document.getElementById("aqt").style.opacity="0.5";
+ }
+ else
+ {
+ changeImage('../../../koishi_norm.png');
+ document.getElementById("aqt").style.opacity="1.0";
+ }*/
+}
+function windowresize()
+{
+ if(plistshown)
+ {
+ document.getElementById("playlist").style.left=(window.innerWidth-plistRect.width)/2+"px";
+ plistRect=document.getElementById("playlist").getBoundingClientRect();
+ }
+ else
+ {
+ }
+}
+function run(link)
+{
+ var trurl="";
+ if(window.location.href.indexOf("&title=")==-1)
+ trurl=window.location.href;
+ else
+ trurl=window.location.href.substr(0,window.location.href.indexOf("&title="));
+ trurl=trurl.concat("&title=");
+ trurl=trurl.concat(link.attr('tr'));
+ window.history.replaceState("","The Stupid Online Player",trurl);
+ document.getElementById("imgplaypause").src="pause.svg";
+ audio.src=link.attr('href');
+ document.getElementById("nowplaying").innerHTML="Now Playing: "+link.attr('tr');
+ par=link.parent();
+ par.addClass('active').siblings().removeClass('active');
+ audio.load();
+ audio.play();
+}
+
+function togglePlist()
+{
+ document.getElementById("plistsw").onclick=function(){};
+ plistshown=!plistshown;
+ if(plistshown)
+ {
+ for(var i=0;i<playlist.find('a').length;++i)
+ $(playlist.find('a')[i]).css("transition","0.8s");
+ document.getElementById("plistsw").innerHTML="[↓Hide Playlist]";
+ setTimeout(
+ function(){
+ document.getElementById("playlist").style.left=(window.innerWidth-plistRect.width)/2+"px";
+ document.getElementById("playlist").style.top=document.getElementById("plistref").getBoundingClientRect().top+"px";
+ document.getElementById("playlist").style.background="rgba(153,187,238,0.6)";
+ for(var i=0;i<playlist.find('a').length;++i)
+ $(playlist.find('a')[i]).css("color","");
+ }
+ ,40);
+ setTimeout(
+ function(){
+ document.getElementById("playlist").style.position="static";
+ document.getElementById("plistsw").onclick=togglePlist;
+ plistRect=document.getElementById("playlist").getBoundingClientRect();
+ for(var i=0;i<playlist.find('a').length;++i)
+ $(playlist.find('a')[i]).css("transition","none");
+ }
+ ,840);
+ }
+ else
+ {
+ var d=$(document).scrollTop();
+ $('html,body').stop().animate({scrollTop:0},d);
+ setTimeout(
+ function(){
+ plistRect=document.getElementById("playlist").getBoundingClientRect();
+ document.getElementById("playlist").style.position="fixed";
+ document.getElementById("playlist").style.top=plistRect.top+"px";
+ document.getElementById("playlist").style.left=plistRect.left+"px";
+ for(var i=0;i<playlist.find('a').length;++i)
+ $(playlist.find('a')[i]).css("transition","0.8s");
+ },
+ d+1);
+ setTimeout(
+ function(){
+ document.getElementById("playlist").style.top="100%";
+ document.getElementById("playlist").style.background="rgba(153,187,238,0)";
+ document.getElementById("plistsw").onclick=togglePlist;
+ for(var i=0;i<playlist.find('a').length;++i)
+ $(playlist.find('a')[i]).css("color",$(playlist.find('a')[i]).hasClass("active")?"rgba(255,204,0,0);":"rgba(32,172,255,0)");
+ },
+ d+5);
+ document.getElementById("plistsw").innerHTML="[↑Show Playlist]";
+ }
+}
+
+function updateVisualization()
+{
+ if(visualselector.value=="spectrum")
+ {
+ var cctx=canvas.getContext('2d');
+ cctx.clearRect(0,0,canvas.width,canvas.height);
+ try{
+ var freqarr=new Uint8Array(CtxtAnalyser.frequencyBinCount);
+ CtxtAnalyser.getByteFrequencyData(freqarr);
+ for(var i=0;i<CSpectrum;++i)
+ {
+ var color='hsl('+i*360.0/CSpectrum+',100%,50%)';
+ cctx.fillStyle=color;
+ cctx.fillRect(i*(SpecWidth+SpecGap),canvas.height-(canvas.height*freqarr[i]/255.),SpecWidth,canvas.height*freqarr[i]/255.);
+ if(caps[i]<freqarr[i])caps[i]=freqarr[i];else if(caps[i]>0)--caps[i];
+ color='hsl('+i*360.0/CSpectrum+',100%,25%)';
+ cctx.fillStyle=color;
+ cctx.fillRect(i*(SpecWidth+SpecGap),canvas.height-(canvas.height*caps[i]/255.)-1,SpecWidth,1);
+ }
+ }catch(e){
+ if(caps[i]>0)--caps[i];
+ color='hsl('+i*360.0/CSpectrum+',100%,25%)';
+ cctx.fillStyle=color;
+ cctx.fillRect(i*(SpecWidth+SpecGap),canvas.height-caps[i]-1,SpecWidth,1);
+ };
+ }
+ if(visualselector.value=="spectrumring")
+ {
+ var cctx=canvas.getContext('2d');
+ cctx.clearRect(0,0,canvas.width,canvas.height);
+ try{
+ var freqarr=new Uint8Array(CtxtAnalyser.frequencyBinCount);
+ CtxtAnalyser.getByteFrequencyData(freqarr);
+ for(var i=0;i<CSpectrum;++i)
+ {
+ var color='hsl('+i*360.0/CSpectrum+',100%,50%)';
+ cctx.strokeStyle=color;
+ cctx.beginPath();cctx.moveTo(canvas.width/2.,canvas.height/2.);
+ cctx.lineTo(canvas.width/2.-Math.cos(2*Math.PI*(i/CSpectrum))*SpecRingRadius*freqarr[i]/255.,
+ canvas.height/2.-Math.sin(2*Math.PI*(i/CSpectrum))*SpecRingRadius*freqarr[i]/255.);
+ cctx.stroke();
+ if(caps[i]<freqarr[i])caps[i]=freqarr[i];else if(caps[i]>0)--caps[i];
+ color='hsl('+i*360.0/CSpectrum+',100%,25%)';
+ cctx.strokeStyle=color;
+ cctx.beginPath();
+ cctx.moveTo(canvas.width/2.-Math.cos(2*Math.PI*(i/CSpectrum))*SpecRingRadius*(caps[i]+1)/255.,
+ canvas.height/2.-Math.sin(2*Math.PI*(i/CSpectrum))*SpecRingRadius*(caps[i]+1)/255.);
+ cctx.lineTo(canvas.width/2.-Math.cos(2*Math.PI*(i/CSpectrum))*SpecRingRadius*caps[i]/255.,
+ canvas.height/2.-Math.sin(2*Math.PI*(i/CSpectrum))*SpecRingRadius*caps[i]/255.);
+ cctx.stroke();
+ }
+ }catch(e){
+ if(caps[i]>0)--caps[i];
+ color='hsl('+i*360.0/CSpectrum+',100%,25%)';
+ cctx.strokeStyle=color;
+ cctx.moveTo(canvas.width/2.-Math.cos(2*Math.PI*(i/CSpectrum))*SpecRingRadius*(caps[i]+1)/255.,
+ canvas.height/2.-Math.sin(2*Math.PI*(i/CSpectrum))*SpecRingRadius*(caps[i]+1)/255.);
+ cctx.lineTo(canvas.width/2.-Math.cos(2*Math.PI*(i/CSpectrum))*SpecRingRadius*caps[i]/255.,
+ canvas.height/2.-Math.sin(2*Math.PI*(i/CSpectrum))*SpecRingRadius*caps[i]/255.);
+ cctx.stroke();
+ };
+ }
+ if(visualselector.value=="scope")
+ {
+ var cctx=canvas.getContext('2d');
+ cctx.clearRect(0,0,canvas.width,canvas.height);
+ try{
+ var tdomainarr=new Uint8Array(CtxtAnalyser.frequencyBinCount);
+ CtxtAnalyser.getByteTimeDomainData(tdomainarr);
+ cctx.lineWidth=dpiratio;
+ cctx.strokeStyle="#000";
+ cctx.beginPath();
+ var x=0;
+ for(var i=0;i<CSpectrum;++i)
+ {
+ if(i==0)cctx.moveTo(x,tdomainarr[i]/128.*canvas.height/2);
+ else cctx.lineTo(x,tdomainarr[i]/128.*canvas.height/2);
+ x+=canvas.width*1./CSpectrum;
+ }
+ cctx.stroke();
+ }catch(e){
+ console.log(e.message);
+ };
+ }
+ if(visualselector.value=="spectrogram")
+ {
+ var cctx=canvas.getContext('2d');
+ try{
+ var freqarr=new Uint8Array(CtxtAnalyser.frequencyBinCount);
+ CtxtAnalyser.getByteFrequencyData(freqarr);
+ cctx.clearRect(spectrogrampos/1800*canvas.width,0,canvas.width/1800,canvas.height);
+ for(var i=0;i<CSpectrum;++i)
+ {
+ var color='rgba(0,0,0,'+freqarr[i]/256.+')';
+ cctx.fillStyle=color;
+ cctx.fillRect(spectrogrampos/1800*canvas.width,(CSpectrum-i)/CSpectrum*canvas.height,canvas.width/1800.,canvas.height/CSpectrum);
+ }
+ ++spectrogrampos;if(spectrogrampos>=1800)spectrogrampos=0;
+ }catch(e){
+ };
+ }
+ if(visualselector.value=="inkfountain")
+ {
+ var cctx=canvas.getContext('2d'),ts=Date.now(),tu;
+ cctx.clearRect(0,0,canvas.width,canvas.height);
+ ++frms;if(Date.now()-lastfpsupd>500){if(lastfpsupd)fps=1000*frms/(Date.now()-lastfpsupd),frms=0;lastfpsupd=Date.now();}
+ try{
+ var freqarr=new Uint8Array(CtxtAnalyser.frequencyBinCount);
+ CtxtAnalyser.getByteFrequencyData(freqarr);
+ for(var i=0;i<CSpectrumIF;++i)
+ {
+ var r=0;
+ for(var j=0;j<8;++j)r+=freqarr[i*8+j];
+ r/=8.;
+ if(r-caps[i]>7)
+ {
+ var color=Math.floor(i*8.0/CSpectrumIF),rad=Math.random()*Math.PI*2;
+ var ndrops=(128-i)/128.*3+1;ndrops*=(r/128.);ndrops=Math.floor(ndrops);if(ndrops<1)ndrops=1;
+ for(var k=0;k<ndrops;++k)
+ {
+ createInk(((r-caps[i]-7)/32*24+12)*Math.cos(rad),((r-caps[i]-7)/32*24+12)*Math.sin(rad),color);
+ rad=Math.random()*Math.PI*2;
+ }
+ }
+ if(r>caps[i])caps[i]=r;else caps[i]-=2;
+ }
+ }catch(e){
+ console.log(e.message);
+ };
+ tu=Date.now();
+ var aa=0;
+ for(var i=0;i<inks.length;++i){
+ if(inks[i].active){inks[i].update();inks[i].draw(cctx);++aa}
+ }
+ cctx.fillStyle="#000";
+ cctx.font="1em Courier, monospace";
+ cctx.fillText("Active droplets "+aa+", "+fps.toFixed(2)+" FPS",0,10);
+ cctx.fillText("Update time "+(tu-ts)+"ms, render time "+(Date.now()-tu)+"ms",0,24);
+ }
+ if(visualselector.value=="shakeurbody")
+ {
+ var cctx=canvas.getContext('2d');
+ cctx.clearRect(0,0,canvas.width,canvas.height);
+ try{
+ var tdomainarr=new Float32Array(CtxtAnalyser.frequencyBinCount);
+ CtxtAnalyser.getFloatTimeDomainData(tdomainarr);
+ for(var i=0;i<CSpectrum;++i)
+ {
+ var kbf=1/(audioCtxt.sampleRate*lpf),br=Math.exp(-1/(audioCtxt.sampleRate*beatr));
+ f1+=(kbf*(tdomainarr[i]-f1));
+ f2+=(kbf*(f1-f2));
+ var env=Math.abs(f2);
+ if(env>penv)penv=env;else{penv*=br;penv+=(1-br)*env;}
+ if(!btrig){if(penv>0.20)btrig=1;}else{if(penv<0.125)btrig=0;}
+ beatp=0;if(btrig&&!lastbp)beatp=1;lastbp=beatp;
+ if(beatp)document.body.style.transform='translateY(100px)';else document.body.style.transform='translateY(0px)';
+ }
+ }catch(e){
+ document.body.style.transform='translateY(0px)';
+ };
+ }else document.body.style.transform='none';
+ if(visualselector.value!="none")
+ af=requestAnimationFrame(updateVisualization);
+}