我今天下午的大部分时间都在研究/试验这个基本的冥想应用程序,并且只是在我自己找到解决方案后数小时才提出这个问题。
冥想应用程序应该有3列代表吸气,保持和呼气,以秒为单位。每次列/时间达到它设置的时间,该列暂停,下一列开始增加高度并且秒计数器低于它。当所有三列都达到完成时,呼吸循环计数器增加1,所有条都重置,并且过程继续,直到标签关闭。 (当前时间为5(吸气):20(保持):15(呼气)。
我让所有的酒吧均匀增加,但是在按顺序改变工作的过程中,酒吧完全停止了。我现在只包括我现有的所有代码,因为我不知道这里有什么重要的。再次感谢任何想法。
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<Title>Meditation App</title>
</head>
<body>
<canvas id="canvas" width="500" height="500">
</canvas>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Columns x1 == xPos, x2 == width, y1 == yPos ,y2 == height
x1a = 10, x2a = 50, y1a = 250, y2a = -10;
x1b = 50, x2b = 50, y1b = 250, y2b = -10;
x1c = 100, x2c = 50, y1c = 250, y2c = -10;
inhaleTime = 5;
holdTime = 20;
exhaleTime = 10;
breathCounter = 0;
timerA = 1;
timerB = 1;
timerC = 1;
function render(){
//Draw background
ctx.fillStyle = "#49faff";
ctx.fillRect(0, 0, 700, 500);
//Draw column A
ctx.fillStyle = "#045f84";
ctx.fillRect(x1a, y1a, x2a, y2a);
//Draw column B
ctx.fillStyle = "#14fe14";
ctx.fillRect(x1b, y1b, x2b, y2b);
//Draw column C
ctx.fillStyle = "#d600f0";
ctx.fillRect(x1c, y1c, x2c, y2c);
//Write seconds counter under column A
ctx.fillStyle = "red";
ctx.font = "48px serif";
ctx.strokeText(timerA, 10, 300);
//Write seconds counter under column B
ctx.fillStyle = "red";
ctx.font = "48px serif";
ctx.strokeText(timerB, 50, 300);
//Write seconds counter under column C
ctx.fillStyle = "red";
ctx.font = "48px serif";
ctx.strokeText(timerC, 100, 300);
//Write breath cycles counter above columns
ctx.fillStyle = "red";
ctx.font = "48px serif";
ctx.strokeText(("Breath Cycles: " + breathCounter), 10, 100);
}
// Increase column A height by 1 unit & increase seconds counter by 1
function renderA(){
x1a += 0;
x2a += 0;
y1a += 0;
y2a += -100;
timerA += 1;
}
// Increase column B height by 1 unit & increase seconds counter by 1
function renderB(){
x1b += 0;
x2b += 0;
y1b += 0;
y2b += -100;
timerB += 1;
}
// Increase column C height by 1 unit & increase seconds counter by 1
function renderC(){
x1c += 0;
x2c += 0;
y1c += 0;
y2c += -100;
timerC += 1;
}
//Reset column heights after each breath cycle & add 1 to Breath Cycles counter
function renderReset(){
x1a = 10, x2a = 50, y1a = 250, y2a = -10;
x1b = 50, x2b = 50, y1b = 250, y2b = -10;
x1c = 100, x2c = 50, y1c = 250, y2c = -10;
breathCounter += 1;
}
function updateRender(){
renderA();
renderB();
renderC();
// setInterval(renderA, 1000);
// setInterval(renderB, 1000);
// setInterval(renderC, 1000);
}
/*
if (timerA > inhaleTime){
timerA = 1;
x1a = 10, x2a = 50, y1a = 250, y2a = -10;
x1b = 50, x2b = 50, y1b = 250, y2b = -10;
x1c = 100, x2c = 50, y1c = 250, y2c = -10;
}
if (timerA > inhaleTime && timerB > holdTime){
timerA = 1;
x1a = 10, x2a = 50, y1a = 250, y2a = -10;
x1b = 50, x2b = 50, y1b = 250, y2b = -10;
x1c = 100, x2c = 50, y1c = 250, y2c = -10;
}
if (timerA > inhaleTime && timerB > holdTime && timerC > exhaleTime){
timerA = 1;
x1a = 10, x2a = 50, y1a = 250, y2a = -10;
x1b = 50, x2b = 50, y1b = 250, y2b = -10;
x1c = 100, x2c = 50, y1c = 250, y2c = -10;
}
}
function inhaleBreath(){
//increase barA x1a += 0; x2a += 0; y1a += 0; y2a += -10;
//increase timerA timerA += 1;
//check if timer > inhaleTime
}
function holdBreath(){
//increase barB x1b += 0; x2b += 0; y1b += 0; y2b += -10;
//increase timerB timerB += 1;
//check if timer > holdTime
}
function exhaleBreath(){
//increase barC x1c += 0; x2c += 0; y1c += 0; y2c += -10;
//increase timerC timerC += 1;
//check if timer > exhaleTime
}
*/
render();
renderA();
//
//Insert functions to continually increment column heights, seconds counter, and breath counter
//
</script>
答案 0 :(得分:0)
好的,我会咬人......
这是一个使用单个requestAnimationFrame
循环而不是多个计时器的呼吸条版本。
关键是计算当前呼吸周期内的经过时间。
假设:
// milliseconds for each part of the breathing cycle
var maxInhale=5000;
var maxHold=20000;
var maxExhale=15000;
如果经过的时间是&lt; 5秒,
// where each pct is between 0.00 & 1.00 (==0% to 100%)
pctInhale = elapsed / maxCycleTime
pctHold = 0;
pctExhale = 0;
如果经过的时间是&lt; (5 + 20)25秒,
pctInhale=1;
pctHold=(elapsed-maxInhale)/maxHold;
pctExhale = 0;
如果经过的时间是&lt; (5 + 20 + 15)40秒,
pctInhale=1;
pctHold=1;
pctExhale=(elapsed-maxInhale-maxHold)/maxExhale
示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var maxInhale=5000;
var maxHold=20000;
var maxExhale=15000;
var maxCycle=maxInhale+maxHold+maxExhale;
var cycleStartTime=0;
var xa=50;
var xb=150;
var xc=250;
var width=75;
var maxHeight=300;
var maxY=ch-100;
ctx.font='36px verdana';
ctx.textAlign='center';
ctx.textBaseline='middle';
requestAnimationFrame(animate);
function draw(pctInhale,pctHold,pctExhale){
ctx.fillStyle = "#49faff";
ctx.fillRect(0,0,cw,ch);
//Draw column A
ctx.fillStyle = "#045f84";
ctx.fillRect(xa,maxY,width,-maxHeight*pctInhale);
//Draw column B
ctx.fillStyle = "#14fe14";
ctx.fillRect(xb,maxY,width,-maxHeight*pctHold);
//Draw column C
ctx.fillStyle = "#d600f0";
ctx.fillRect(xc,maxY,width,-maxHeight*pctExhale);
ctx.fillStyle='red';
ctx.fillText(parseInt(maxInhale*pctInhale/1000)+'s',xa+width/2,maxY-48);
ctx.fillText(parseInt(maxHold*pctHold/1000)+'s',xb+width/2,maxY-48);
ctx.fillText(parseInt(maxExhale*pctExhale/1000)+'s',xc+width/2,maxY-48);
}
function animate(time){
var elapsed=time-cycleStartTime;
// cycle done? start over.
if(elapsed>maxCycle){
cycleStartTime=time;
elapsed=0;
}
// calc each bars percentage based on elapsed time
var pctInhale=0;
var pctHold=0;
var pctExhale=0;
if(elapsed<maxInhale){
pctInhale=elapsed/maxInhale;
}else if(elapsed<maxInhale+maxHold){
pctInhale=1;
pctHold=(elapsed-maxInhale)/maxHold;
}else if(elapsed<maxInhale+maxHold+maxExhale){
pctInhale=1;
pctHold=1;
pctExhale=(elapsed-maxInhale-maxHold)/maxExhale
}
// draw the bars
draw(pctInhale,pctHold,pctExhale);
// request another animation loop
requestAnimationFrame(animate);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=700 height=500></canvas>
答案 1 :(得分:0)
我尽可能地坚持使用现有代码并添加了我需要添加的内容。在代码的底部,我添加了以下内容:
var whichCounter = 'A';
function newUpdate() {
//console.log('newUpdate, A=' + timerA + ', B=' + timerB + ', C=' + timerC);
render();
switch (whichCounter) {
case 'A':
if (timerA < inhaleTime) {
renderA();
} else {
timerB = 1;
whichCounter = 'B';
}
break;
case 'B':
if (timerB < holdTime) {
renderB();
} else {
timerC = 1;
whichCounter = 'C';
}
break;
case 'C':
if (timerC < exhaleTime) {
renderC();
} else {
whichCounter = 'Q';
}
break;
case 'Q':
timerA = 1;
timerB = 1;
timerC = 1;
renderReset();
whichCounter = 'A';
render();
break;
}
}
setInterval(newUpdate, 1000);
您可以在this jfiddle中看到它。