/** * Periodic BBS Demo (SVG version) * by Kazuki Maeda * Last-Modified: May 26, 2013 */ var WIDTH=900, HEIGHT=50; var boxWidth; var boxNumber; var state; var box, ball; var thread; var rootSVG; var defs; var animationThread; window.onload = function(){ init(); } function init(){ document.getElementById("startstop").addEventListener("click", startstop, true); document.getElementById("prev").addEventListener("click", prev, true); document.getElementById("next").addEventListener("click", next, true); document.getElementById("random").addEventListener("click", random, true); document.getElementById("clear").addEventListener("click", reset, true); document.getElementById("number").addEventListener("keypress", setSize, true); document.getElementById("set").addEventListener("click", init2, true); init2(); } function init2(){ document.getElementById("canvas").removeChild(document.getElementById("canvas").firstChild); rootSVG = document.createElementNS("http://www.w3.org/2000/svg", "svg"); rootSVG.setAttribute("width", WIDTH); rootSVG.setAttribute("height", HEIGHT); document.getElementById("canvas").appendChild(rootSVG); boxNumber = document.getElementById("number").value; if(boxNumber < 3){ boxNumber = 3; document.getElementById("number").value = 3; } if(boxNumber > 300){ boxNumber = 300; document.getElementById("number").value = 100; } boxWidth = Math.floor(WIDTH/boxNumber); if(boxWidth > HEIGHT) boxWidth = HEIGHT; state = new Array(boxNumber); for(var i = 0; i < boxNumber; ++i) state[i] = 0; if(document.getElementById("startstop").value == "Stop") { clearInterval(thread); document.getElementById("startstop").value = "Start"; document.getElementById("next").disabled = false; document.getElementById("prev").disabled = false; document.getElementById("random").disabled = false; document.getElementById("clear").disabled = false; document.getElementById("set").disabled = false; document.getElementById("number").disabled = false; document.getElementById("fps").disabled = false; document.getElementById("effect").disabled = false; } // create box images box = new Array(boxNumber); for(var i = 0; i < boxNumber; ++i){ box[i] = document.createElementNS("http://www.w3.org/2000/svg", "rect"); box[i].setAttribute("id", "box"+i); box[i].setAttribute("x", ""+(i*boxWidth)); box[i].setAttribute("y", ""+((HEIGHT-boxWidth)/2)); box[i].setAttribute("width", ""+boxWidth); box[i].setAttribute("height", ""+boxWidth); box[i].setAttribute("stroke", "#000000"); box[i].setAttribute("stroke-width", "1.0"); if(Math.floor(i/5)%2) box[i].setAttribute("fill", "#DDDDFF"); else box[i].setAttribute("fill", "#FFFFFF"); box[i].addEventListener("click", setBallClicked, true); rootSVG.appendChild(box[i]); } // create ball images defs = document.createElementNS("http://www.w3.org/2000/svg", "defs"); rootSVG.appendChild(defs); var grad = document.createElementNS("http://www.w3.org/2000/svg", "radialGradient"); grad.setAttribute("id", "grad"); grad.setAttribute("cx", "50%"); grad.setAttribute("cy", "50%"); grad.setAttribute("r", "50%"); grad.setAttribute("fx", "30%"); grad.setAttribute("fy", "30%"); var stop0 = document.createElementNS("http://www.w3.org/2000/svg", "stop"); stop0.setAttribute("offset", "0%"); stop0.setAttribute("stop-color", "#FFFFFF"); grad.appendChild(stop0); var stop1 = document.createElementNS("http://www.w3.org/2000/svg", "stop"); stop1.setAttribute("offset", "100%"); stop1.setAttribute("stop-color", "#000000"); grad.appendChild(stop1); defs.appendChild(grad); ball = new Array(boxNumber); for(var i = 0; i < boxNumber; ++i){ ball[i] = document.createElementNS("http://www.w3.org/2000/svg", "circle"); ball[i].setAttribute("id", "bal"+i); ball[i].setAttribute("cx", ""+((i+0.5)*boxWidth)); ball[i].setAttribute("cy", ""+(HEIGHT/2)); ball[i].setAttribute("r", ""+0); ball[i].setAttribute("fill", "url(#grad)"); ball[i].addEventListener("click", setBallClicked, true); rootSVG.appendChild(ball[i]); } animationThread = new Array(boxNumber); } function startstop() { if(document.getElementById("startstop").value == "Start") { var timeInterval = parseInt(document.getElementById("fps").value); if(timeInterval < 1) timeInterval = 1000; else if(timeInterval > 60) timeInterval = 1000/60; else timeInterval = 1000/timeInterval; thread = setInterval("next();", timeInterval); document.getElementById("startstop").value = "Stop"; document.getElementById("random").disabled = true; document.getElementById("clear").disabled = true; document.getElementById("next").disabled = true; document.getElementById("prev").disabled = true; document.getElementById("set").disabled = true; document.getElementById("number").disabled = true; document.getElementById("fps").disabled = true; document.getElementById("effect").disabled = true; } else { clearInterval(thread); document.getElementById("startstop").value = "Start"; document.getElementById("random").disabled = false; document.getElementById("clear").disabled = false; document.getElementById("next").disabled = false; document.getElementById("prev").disabled = false; document.getElementById("set").disabled = false; document.getElementById("number").disabled = false; document.getElementById("fps").disabled = false; document.getElementById("effect").disabled = false; } } function random(){ reset(); var sum = 0; for(var i = 0; i < boxNumber; ++i) if(sum < boxNumber/2 && Math.random()>0.8){ setBall(i, true); ++sum; } } function reset(){ for(var i = 0; i < boxNumber; ++i) if(state[i]) setBall(i, true); } function resetNoAnimate(){ for(var i = 0; i < boxNumber; ++i) if(state[i]) setBall(i, false); } function next(){ var newState = new Array(boxNumber); var car = 0; for(var i = 0; i < boxNumber; ++i){ if(state[i]){ newState[i] = 0; ++car; } else if(car > 0){ newState[i] = 1; --car; } else { newState[i] = 0; } } // periodicity for(var i = 0; i < boxNumber; ++i) if(!state[i] && !newState[i] && car){ newState[i] = 1; --car; } resetNoAnimate(); for(var i = 0; i < boxNumber; ++i) if(newState[i]) setBall(i, false); } function prev(){ var newState = new Array(boxNumber); var car = 0; for(var i = boxNumber-1; i >= 0; --i){ if(state[i]){ newState[i] = 0; ++car; } else if(car > 0){ newState[i] = 1; --car; } else { newState[i] = 0; } } // periodicity for(var i = boxNumber-1; i >= 0; --i) if(!state[i] && !newState[i] && car){ newState[i] = 1; --car; } resetNoAnimate(); for(var i = 0; i < boxNumber; ++i) if(newState[i]) setBall(i, false); } function setBallClicked(e){ if(document.getElementById("startstop").value == "Start"){ var str = e.target.id; var n = parseInt(str.substr(3, str.length-3)); setBall(n, true); } } function animateSet(n) { var r = parseFloat(ball[n].getAttribute("r"))+(boxWidth/20); if(r > boxWidth/2*0.8) { r = boxWidth/2*0.8; clearInterval(animationThread[n]); } ball[n].setAttribute("r", ""+r); } function animateRemove(n) { var r = parseFloat(ball[n].getAttribute("r"))-(boxWidth/20); if(r < 0) { r = 0; clearInterval(animationThread[n]); } ball[n].setAttribute("r", ""+r); } function setBall(n, animate){ if(state[n]){ if(document.getElementById("effect").checked && animate){ clearInterval(animationThread[n]); animationThread[n] = setInterval("animateRemove("+n+");", 1000/60); } else { ball[n].setAttribute("r", "0"); } state[n]=0; } else { var sum = 0; for(var i = 0; i < boxNumber; ++i) if(state[i]) ++sum; if(sum