我简化了背景生成器,它使bg充满了相同大小的不同灰色的立方体(块)。然后,我准备了将一些随机块动画化为蓝色,然后再恢复为初始颜色的函数。我将间隔设置为每5秒运行一次随机块。内部函数有两个循环(2x 100步),超时设置为25ms(总计5秒)。问题是,通过控制台颜色更改而不是在Canvas上更改。您能找到问题在哪里吗?
关于jsFiddle的代码,这里仅是允许我提出以下问题:
emplid year month Reason
------ ---- ----- ------
1234 2018 APR Retire
5678 2018 FEB Terminated
9876 2018 MAY Transfer
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 e.g. 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 e.g. 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);
}
答案 0 :(得分:1)
太好了,谢谢海道!这是我对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 e.g. 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">