简体   繁体   English

HTML5 Canvas-动画无法正常工作

[英]HTML5 Canvas - animation not working as expected

I made easy background generator, which makes bg filled with same-sized diferently grayed cubes (blocks). 我制作了简单的背景生成器,它使bg充满了相同大小的不同灰色的多维数据集(块)。 Then I've prepared function to animate some random block to blue and then back to starting color. 然后,我准备了将一些随机块动画化为蓝色,然后再恢复为初始颜色的函数。 I set interval to run random block each 5 seconds. 我将间隔设置为每5秒运行一次随机块。 Inside function are two loops (2x 100 steps), with timeout setted to 25ms (5 sec in total). 内部函数有两个循环(2x 100步),超时设置为25ms(总计5秒)。 Problem is, that by console color changes but not on Canvas. 问题是,通过控制台颜色更改而不是在Canvas上更改。 Can you find, what is wrong, please? 您能找到问题在哪里吗?

Code on jsFiddle, this is here only to allow me to ask the question: jsFiddle上的代码,这里仅是允许我提出以下问题:

 var blockSize = 20; // Size of one block var canW = 200; // Size of canvas var canH = 100; var cvsName = 'cvsBg'; // Name of canvas var color = [0, 0, 0]; // container for changing color var defaultColor = [0, 0, 0] // container for block color given by prepareBG() var blueColor = [0, 204, 255]; // color to which is default color changing var rndPositonW = getRandomInt(0, canW); // random point on Canvas, to select actually changing block var rndPositonH = getRandomInt(0, canH); var cSteps = 100; // animation steps between default color and blue color var cChangeInterval = 5000; // run one block animation each 5s var can = document.getElementById(cvsName); can.width = canW; can.height = canH; var ctx = can.getContext('2d'); prepareBG(ctx); //prepare bg with gray colored blocks setInterval(colorAnimation, cChangeInterval, ctx, rndPositonW, rndPositonH); // in this interval to do animation: // 100 steps from default color to blue // 100 steps from blue back to default color function colorAnimation(ctx, cBlockX, cBlockY) { var pixelData = ctx.getImageData(cBlockX, cBlockY, 1, 1).data; // get default color at randomly selected point defaultColor = [pixelData[0], pixelData[1], pixelData[2]]; var blockX = Math.floor(cBlockX / blockSize) * blockSize; // get zero coordinated of block under randomly selected point var blockY = Math.floor(cBlockY / blockSize) * blockSize; var i, j; for (i = 0; i <= cSteps; i++) { // coloring from default color to blue: 100 steps, one step each 25ms (color change interval is 5000 divided by total steps 200 ) for (j = 0; j < 3; j++) { // compute changing RGB eg if i is near 100, color will be almost blue color[j] = defaultColor[j] + ((blueColor[j] - defaultColor[j]) / cSteps) * i; } console.log("Drawing: X=%i, Y=%i, Color=%i,%i,%i", blockX, blockY, color[0], color[1], color[2]); setTimeout(drawBlock, cChangeInterval / cSteps / 2, ctx, blockX, blockY, color, blockSize); } for (i = 0; i <= cSteps; i++) { // coloring from blue color to defalut: 100 steps, one step each 25ms (color change interval is 5000 divided by total steps 200 ) for (j = 0; j < 3; j++) { // compute changing RGB eg if i is near 100, color will be almost default color[j] = blueColor[j] - ((blueColor[j] - defaultColor[j]) / cSteps) * i; } setTimeout(drawBlock, cChangeInterval / cSteps / 2, ctx, blockX, blockY, color, blockSize); } rndPositonW = getRandomInt(0, canW); // find new random point for next block animation rndPositonH = getRandomInt(0, canH); } function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function prepareBG(ctx) { var x = 0; var y = 0; var c = 0 for (x = 0; x <= can.width; x += blockSize) { for (y = 0; y <= can.height; y += blockSize) { c = getRandomInt(50, 56); drawBlock(ctx, x, y, [c, c, c], blockSize); } } //CANVAS will be used as body's background: //document.body.style.background = 'url(' + can.toDataURL() + ')'; } function drawBlock(ctx, x, y, c, blocksize) { ctx.fillStyle = 'rgb(' + c[0] + ', ' + c[1] + ', ' + c[2] + ')'; ctx.fillRect(x, y, blockSize, blockSize); } 
 <canvas id="cvsBg"> 

Great, thanks Kaiido! 太好了,谢谢海道! It was my wrong understanding to how setTimeout works... I've wrongly expected behavior similar to pause because that was what i searched for. 这是我对setTimeout的工作方式的错误理解……我错误地期望了与暂停类似的行为,因为这正是我要寻找的。

 var blockSize = 20; // Size of one block var canW = 500; // Size of canvas var canH = 200; var cvsName = 'cvsBg'; // Name of canvas var color = [0,0,0]; // container for changing color var defaultColor = [0,0,0] // container for block color given by prepareBG() var blueColor = [0,204,255]; // color to which is default color changing var animationSteps = 30; // total animation steps up & down var animationPause = 1000; // pause between animations var animationTime = 1000; // duration of one animation var animationRunning = false; var can = document.getElementById(cvsName); can.width = canW; can.height = canH; var ctx = can.getContext('2d'); prepareBG(ctx); //prepare bg with gray colored blocks var count = 0; function update(rndPositonW,rndPositonH) { if(!animationRunning) { var pixelData = ctx.getImageData(rndPositonW, rndPositonH, 1, 1).data; // get default color at randomly selected point defaultColor = [pixelData[0],pixelData[1],pixelData[2]]; animationRunning = true; } var blockX = Math.floor(rndPositonW / blockSize) * blockSize; // get zero coordinated of block under randomly selected point var blockY = Math.floor(rndPositonH / blockSize) * blockSize; var j; for(j=0; j<3; j++){ // compute changing RGB eg if i is near 100, color will be almost blue if(count < (animationSteps / 2)) color[j] = defaultColor[j] + ((blueColor[j] - defaultColor[j]) / (animationSteps / 2)) * count; //way up else color[j] = blueColor[j] - ((blueColor[j] - defaultColor[j]) / (animationSteps / 2)) * (count - (animationSteps / 2)); //way down } drawBlock(ctx, blockX, blockY, color, blockSize); if (++count <= animationSteps) { setTimeout(update, animationTime / animationSteps, rndPositonW, rndPositonH); } else { count = 0; animationRunning = false; setTimeout(update, animationPause, getRandomInt(0, canW), getRandomInt(0, canH)); } } update(getRandomInt(0, canW), getRandomInt(0, canH)); function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function prepareBG(ctx){ var x = 0; var y = 0; var c = 0 for (x = 0; x <= can.width; x+=blockSize) { for (y = 0; y <= can.height; y+=blockSize) { c = getRandomInt(50, 60); drawBlock(ctx, x, y, [c,c,c], blockSize); } } //CANVAS will be used as body's background: //document.body.style.background = 'url(' + can.toDataURL() + ')'; } function drawBlock(ctx,x,y,c,blocksize){ ctx.fillStyle = 'rgb(' + c[0] + ', ' + c[1] + ', ' + c[2] + ')'; ctx.fillRect(x, y, blockSize, blockSize); } 
 <canvas id="cvsBg"> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM